1 #include <stdlib.h>
2 #include <string.h>
3 #include <ctype.h>
4
5 #include "string.hpp"
6
7 #include "list_tem.hpp"
8 #include "chnkload.hpp"
9 #include "oechunk.h"
10 #include "stratdef.h"
11 //#include "bh_types.h"
12 #include "shpchunk.hpp"
13 #include "envchunk.hpp"
14 #include "obchunk.hpp"
15 #include "chunkpal.hpp"
16 #include "bmpnames.hpp"
17 #include "ltchunk.hpp"
18 #include "chnktexi.h"
19 #include "sprchunk.hpp"
20 #include "gsprchnk.hpp"
21 #include "animchnk.hpp"
22 #include "fragchnk.hpp"
23 #include "jsndsup.h"
24 #include "mempool.h"
25 #include <math.h>
26 // for log file
27 void SetupAnimatedTextures(Shape_Chunk* sc,SHAPEHEADER* shp,Animation_Chunk* ac,Shape_Merge_Data_Chunk* smdc);
28 void SetupAnimOnTriangle(SHAPEHEADER* shp,TEXANIM* ta,int poly);
29 void SetupAnimOnQuad(Shape_Chunk* sc,SHAPEHEADER* shp,TEXANIM* ta1,TEXANIM* ta2,int poly);
30
31 // what we need to do for now is load shapes into the mainshapelist
32 // and objects into the Mapheader - Map
33
34
35 double local_scale;
36
37 File_Chunk * Env_Chunk = 0;
38
39 RIFFHANDLE current_rif_handle;
40
41 unsigned char const * PaletteMapTable;
42
43 //////////////////////////////////////////////////////////
44 extern LOADED_SOUND const * GetSoundForMainRif(const char* wav_name);
45 extern char * extsounddir ;
46 extern char * sounddir ;
47
48 struct Shape_Fragment_Type
49 {
50 Shape_Fragment_Type(const char*);
51 ~Shape_Fragment_Type();
52 void AddShape(SHAPEHEADER*);
53 void Setup_sh_frags(Fragment_Type_Chunk*);
54
55 char* name;
56 List<SHAPEHEADER*> shapelist;
57 SHAPEFRAGMENTDESC* sh_fragdesc;
58 };
59
Shape_Fragment_Type(const char * _name)60 Shape_Fragment_Type::Shape_Fragment_Type(const char* _name)
61 {
62 name=new char[strlen(_name)+1];
63 strcpy(name,_name);
64 sh_fragdesc=0;
65 }
66
~Shape_Fragment_Type()67 Shape_Fragment_Type::~Shape_Fragment_Type()
68 {
69 while(shapelist.size())
70 {
71 shapelist.first_entry()->sh_fragdesc=0;
72 delete shapelist.first_entry();
73 }
74 if(sh_fragdesc)
75 {
76 #if USE_LEVEL_MEMORY_POOL
77 if(sh_fragdesc->sh_fragsound)
78 {
79 if(sh_fragdesc->sh_fragsound->sound_loaded)
80 LoseSound(sh_fragdesc->sh_fragsound->sound_loaded);
81 }
82 #else
83 if(sh_fragdesc->sh_frags)DeallocateMem(sh_fragdesc->sh_frags);
84 if(sh_fragdesc->sh_fragsound)
85 {
86 if(sh_fragdesc->sh_fragsound->sound_loaded)
87 LoseSound(sh_fragdesc->sh_fragsound->sound_loaded);
88 DeallocateMem(sh_fragdesc->sh_fragsound);
89 }
90 DeallocateMem(sh_fragdesc);
91 #endif
92
93 }
94 if(name) delete[] name;
95 }
96
AddShape(SHAPEHEADER * shp)97 void Shape_Fragment_Type::AddShape(SHAPEHEADER* shp)
98 {
99 shapelist.add_entry(shp);
100 if(sh_fragdesc) shp->sh_fragdesc=sh_fragdesc;
101 }
102
103
Setup_sh_frags(Fragment_Type_Chunk * ftc)104 void Shape_Fragment_Type::Setup_sh_frags(Fragment_Type_Chunk* ftc)
105 {
106 if(sh_fragdesc) return;
107 List<Chunk*> chlist;
108 ftc->lookup_child("FRGTYPSC",chlist);
109
110 sh_fragdesc=(SHAPEFRAGMENTDESC*)PoolAllocateMem(sizeof(SHAPEFRAGMENTDESC));
111 for(LIF<SHAPEHEADER*> slif(&shapelist);!slif.done();slif.next())
112 {
113 slif()->sh_fragdesc=sh_fragdesc;
114 }
115
116
117 sh_fragdesc->sh_frags = (SHAPEFRAGMENT *)PoolAllocateMem((chlist.size()+1) * sizeof(SHAPEFRAGMENT));
118 int pos=0;
119 while(chlist.size())
120 {
121 Fragment_Type_Shape_Chunk* ftsc=(Fragment_Type_Shape_Chunk*)chlist.first_entry();
122
123 int shapeindex=GetLoadedShapeMSL(ftsc->name);
124 if(shapeindex!=-1)
125 {
126 sh_fragdesc->sh_frags[pos].ShapeIndex=shapeindex;
127 sh_fragdesc->sh_frags[pos].NumFrags=ftsc->num_fragments;
128
129 sh_fragdesc->sh_frags[pos].x_offset = 0;
130 sh_fragdesc->sh_frags[pos].y_offset = 0;
131 sh_fragdesc->sh_frags[pos].z_offset = 0;
132 pos++;
133 }
134
135 chlist.delete_first_entry();
136 }
137 sh_fragdesc->sh_frags[pos].ShapeIndex = -1;
138 sh_fragdesc->sh_frags[pos].NumFrags = -1;
139
140 sh_fragdesc->sh_fragsound=0;
141
142 Chunk * pChunk = ftc->lookup_single_child("FRGSOUND");
143 if(pChunk)
144 {
145 Fragment_Type_Sound_Chunk* ftsoc=(Fragment_Type_Sound_Chunk*) pChunk;
146
147
148 sh_fragdesc->sh_fragsound=(SHAPEFRAGMENTSOUND*)PoolAllocateMem(sizeof(SHAPEFRAGMENTSOUND));
149 sh_fragdesc->sh_fragsound->sound_loaded=GetSoundForMainRif (ftsoc->wav_name);
150 sh_fragdesc->sh_fragsound->inner_range=(unsigned long)(ftsoc->inner_range*local_scale);
151 sh_fragdesc->sh_fragsound->outer_range=(unsigned long)(ftsoc->outer_range*local_scale);
152 sh_fragdesc->sh_fragsound->pitch=ftsoc->pitch;
153 sh_fragdesc->sh_fragsound->max_volume=ftsoc->max_volume;
154
155 }
156
157
158 }
159
160
161 static List<Shape_Fragment_Type*> FragList;
162
ApplyFragTypeToShape(SHAPEHEADER * shp,const char * name)163 void ApplyFragTypeToShape(SHAPEHEADER* shp,const char* name)
164 {
165 for(LIF<Shape_Fragment_Type*> flif(&FragList);!flif.done();flif.next())
166 {
167 if(!_stricmp(flif()->name,name))
168 {
169 flif()->AddShape(shp);
170 return;
171 }
172 }
173 Shape_Fragment_Type* sft=new Shape_Fragment_Type(name);
174 sft->AddShape(shp);
175 FragList.add_entry(sft);
176 }
177
SetupFragmentType(Fragment_Type_Chunk * ftc)178 void SetupFragmentType(Fragment_Type_Chunk* ftc)
179 {
180 const char* name=ftc->get_name();
181 if(!name) return;
182
183 Shape_Fragment_Type* sft=0;
184 for(LIF<Shape_Fragment_Type*> flif(&FragList);!flif.done();flif.next())
185 {
186 if(!_stricmp(flif()->name,name))
187 {
188 sft=flif();
189 break;
190 }
191 }
192 if(!sft)
193 {
194 return;
195 }
196
197 sft->Setup_sh_frags(ftc);
198 }
199
DeallocateFragments(SHAPEHEADER * shp,SHAPEFRAGMENTDESC * sh_fragdesc)200 void DeallocateFragments(SHAPEHEADER* shp,SHAPEFRAGMENTDESC* sh_fragdesc)
201 {
202 for(LIF<Shape_Fragment_Type*> flif(&FragList);!flif.done();flif.next())
203 {
204 if(flif()->sh_fragdesc==sh_fragdesc)
205 {
206 flif()->shapelist.delete_entry(shp);
207 if(!flif()->shapelist.size())
208 {
209 //no more shapes use this fragment type - so deallocate it
210 delete flif();
211 flif.delete_current();
212 }
213 return;
214 }
215 }
216 //sh_fragdesc not generated by a fragment type so deallocate it.
217 #if USE_LEVEL_MEMORY_POOL
218 if(sh_fragdesc->sh_fragsound)
219 {
220 if(sh_fragdesc->sh_fragsound->sound_loaded)
221 LoseSound(sh_fragdesc->sh_fragsound->sound_loaded);
222 }
223 #else
224 if(sh_fragdesc->sh_frags)DeallocateMem(sh_fragdesc->sh_frags);
225 if(sh_fragdesc->sh_fragsound)
226 {
227 if(sh_fragdesc->sh_fragsound->sound_loaded)
228 LoseSound(sh_fragdesc->sh_fragsound->sound_loaded);
229 DeallocateMem(sh_fragdesc->sh_fragsound);
230 }
231 DeallocateMem(sh_fragdesc);
232 #endif
233 }
234
DeallocateAllFragments()235 void DeallocateAllFragments()
236 {
237 while(FragList.size())
238 {
239 Shape_Fragment_Type* frag_type=FragList.first_entry();
240
241 while(frag_type->shapelist.size())
242 {
243 frag_type->shapelist.delete_first_entry();
244 }
245 frag_type->sh_fragdesc=0;
246 delete frag_type;
247
248 FragList.delete_first_entry();
249 }
250 }
251
252 /////////////////////////////////////////
253 /////////////////////////////////////////
254 // Hold data about chunk loaded shapes //
255 /////////////////////////////////////////
256 /////////////////////////////////////////
257
258 class ShapeInMSL
259 {
260 private:
261 void AddToHashTables();
262 void RemoveFromHashTables();
263
264 #define SIM_HASH_BITS 6
265 #define SIM_HASH_SIZE (1<<SIM_HASH_BITS)
266 #define SIM_HASH_MASK (SIM_HASH_SIZE-1)
267
268 static List<ShapeInMSL const *> hash_msl[];
269 static List<ShapeInMSL const *> hash_ptr[];
270 static List<ShapeInMSL const *> hash_name[];
271
272 static int HashMSLFunc(int);
273 static int HashPtrFunc(SHAPEHEADER *);
274 static int HashNameFunc(char const *);
275
276
277 int listpos;
278 SHAPEHEADER * shptr;
279 String name;
280 BOOL in_hash_table;
281
282 public:
283
Listpos() const284 inline int Listpos() const { return listpos; }
Shptr() const285 inline SHAPEHEADER * Shptr() const { return shptr; }
Name() const286 inline char const * Name() const { return name; }
287
288 static ShapeInMSL const * GetByName(char const *);
289 static ShapeInMSL const * GetByMSL(int);
290 static ShapeInMSL const * GetByPtr(SHAPEHEADER *);
291 static void PurgeMSLShapeList();
292
293 ShapeInMSL();
294 ShapeInMSL(int _p);
295 ShapeInMSL(SHAPEHEADER * _s, char const * _n, int _p);
296 ShapeInMSL(ShapeInMSL const &);
297 ShapeInMSL & operator = (ShapeInMSL const &);
298 ~ShapeInMSL();
299
operator ==(ShapeInMSL const & s2) const300 BOOL operator == (ShapeInMSL const & s2) const
301 { return (GLS_NOTINLIST==listpos && GLS_NOTINLIST==s2.listpos) ? shptr == s2.shptr : listpos == s2.listpos; }
operator !=(ShapeInMSL const & s2) const302 inline BOOL operator != (ShapeInMSL const & s2) const { return ! operator == (s2); }
303 };
304
AddToHashTables()305 void ShapeInMSL::AddToHashTables()
306 {
307 if (GLS_NOTINLIST != listpos)
308 hash_msl[HashMSLFunc(listpos)].add_entry(this);
309 hash_ptr[HashPtrFunc(shptr)].add_entry(this);
310 hash_name[HashNameFunc(name)].add_entry(this);
311
312 in_hash_table = TRUE;
313 }
314
RemoveFromHashTables()315 void ShapeInMSL::RemoveFromHashTables()
316 {
317 if (GLS_NOTINLIST != listpos)
318 hash_msl[HashMSLFunc(listpos)].delete_entry(this);
319 hash_ptr[HashPtrFunc(shptr)].delete_entry(this);
320 hash_name[HashNameFunc(name)].delete_entry(this);
321
322 in_hash_table = FALSE;
323 }
324
325 List<ShapeInMSL const *> ShapeInMSL::hash_msl[SIM_HASH_SIZE];
326 List<ShapeInMSL const *> ShapeInMSL::hash_ptr[SIM_HASH_SIZE];
327 List<ShapeInMSL const *> ShapeInMSL::hash_name[SIM_HASH_SIZE];
328
HashMSLFunc(int pos)329 int ShapeInMSL::HashMSLFunc(int pos)
330 {
331 return pos & SIM_HASH_MASK;
332 }
333
HashPtrFunc(SHAPEHEADER * shp)334 int ShapeInMSL::HashPtrFunc(SHAPEHEADER * shp)
335 {
336 size_t p = (size_t)shp;
337
338 while (p>=SIM_HASH_SIZE)
339 p = (p & SIM_HASH_MASK) ^ (p>>SIM_HASH_BITS);
340
341 return (int)p;
342 }
343
HashNameFunc(char const * nam)344 int ShapeInMSL::HashNameFunc(char const * nam)
345 {
346 int v = 0;
347
348 while (*nam) v += (unsigned char)toupper(*nam++);
349
350 return v & SIM_HASH_MASK;
351 }
352
GetByMSL(int pos)353 ShapeInMSL const * ShapeInMSL::GetByMSL(int pos)
354 {
355 for (LIF<ShapeInMSL const *> i(&hash_msl[HashMSLFunc(pos)]); !i.done(); i.next())
356 {
357 if (i()->listpos == pos) return i();
358 }
359 return 0;
360 }
361
GetByPtr(SHAPEHEADER * shp)362 ShapeInMSL const * ShapeInMSL::GetByPtr(SHAPEHEADER * shp)
363 {
364 for (LIF<ShapeInMSL const *> i(&hash_ptr[HashPtrFunc(shp)]); !i.done(); i.next())
365 {
366 if (i()->shptr == shp) return i();
367 }
368 return 0;
369 }
370
GetByName(char const * nam)371 ShapeInMSL const * ShapeInMSL::GetByName(char const * nam)
372 {
373 for (LIF<ShapeInMSL const *> i(&hash_name[HashNameFunc(nam)]); !i.done(); i.next())
374 {
375 if (!_stricmp(i()->name,nam)) return i();
376 }
377 return 0;
378 }
379
ShapeInMSL()380 ShapeInMSL::ShapeInMSL()
381 : listpos(GLS_NOTINLIST)
382 , shptr(0)
383 , in_hash_table(FALSE)
384 {
385 }
386
ShapeInMSL(int _p)387 ShapeInMSL::ShapeInMSL(int _p)
388 : listpos(_p)
389 , shptr(0)
390 , in_hash_table(FALSE)
391 {
392 }
393
ShapeInMSL(SHAPEHEADER * _s,char const * _n,int _p)394 ShapeInMSL::ShapeInMSL(SHAPEHEADER * _s, char const * _n, int _p)
395 : listpos(_p)
396 , shptr(_s)
397 , name(_n)
398 , in_hash_table(FALSE)
399 {
400 AddToHashTables();
401 }
402
ShapeInMSL(ShapeInMSL const & sim)403 ShapeInMSL::ShapeInMSL(ShapeInMSL const & sim)
404 : listpos(sim.listpos)
405 , shptr(sim.shptr)
406 , name(sim.name)
407 , in_hash_table(FALSE)
408 {
409 if (sim.in_hash_table) AddToHashTables();
410 }
411
operator =(ShapeInMSL const & sim)412 ShapeInMSL & ShapeInMSL::operator = (ShapeInMSL const & sim)
413 {
414 if (&sim != this)
415 {
416 if (in_hash_table) RemoveFromHashTables();
417 shptr = sim.shptr;
418 name = sim.name;
419 listpos = sim.listpos;
420 if (sim.in_hash_table) AddToHashTables();
421 }
422 return *this;
423 }
424
~ShapeInMSL()425 ShapeInMSL::~ShapeInMSL()
426 {
427 if (in_hash_table) RemoveFromHashTables();
428 }
429
430
431 static List<ShapeInMSL*> msl_shapes;
432
PurgeMSLShapeList()433 void ShapeInMSL::PurgeMSLShapeList()
434 {
435 for(int i=0;i<SIM_HASH_SIZE;i++)
436 {
437 while(hash_msl[i].size())hash_msl[i].delete_first_entry();
438 while(hash_ptr[i].size())hash_ptr[i].delete_first_entry();
439 while(hash_name[i].size())hash_name[i].delete_first_entry();
440 }
441
442 while(msl_shapes.size())
443 {
444 ShapeInMSL* shp_msl=msl_shapes.first_entry();
445 shp_msl->in_hash_table=FALSE;
446 delete shp_msl;
447 msl_shapes.delete_first_entry();
448 }
449 }
PurgeMSLShapeList()450 void PurgeMSLShapeList()
451 {
452 ShapeInMSL::PurgeMSLShapeList();
453 }
454
455 /////////////////////////////////////////
456 /////////////////////////////////////////
457 /////////////////////////////////////////
458
459 extern "C"
460 {
461 extern unsigned char *TextureLightingTable;
462 extern int ScanDrawMode;
463 };
464
465
466 /////////////////////////////////////////
467 // Functions which operate on RIFFHANDLEs
468 /////////////////////////////////////////
469
470 // load a rif file into memory
load_rif(const char * fname)471 RIFFHANDLE load_rif (const char * fname)
472 {
473 File_Chunk * fc = new File_Chunk (fname);
474
475 if (fc->error_code != 0)
476 {
477 delete fc;
478 #if OUTPUT_LOG
479 CL_LogFile.lprintf("FAILED TO LOAD RIF: %s\n",fname);
480 #endif
481 ReleaseDirect3D();
482
483 fprintf(stderr, "load_rif: Error loading %s\n", fname);
484 exit(0x111);
485 return INVALID_RIFFHANDLE;
486 }
487 #if OUTPUT_LOG
488 CL_LogFile.lprintf("Successfully Loaded RIF: %s\n",fname);
489 #endif
490
491 RIFFHANDLE h = current_rif_handle = new _RifHandle;
492 h->fc = Env_Chunk = fc;
493
494 Chunk * pChunk = fc->lookup_single_child("REBENVDT");
495 if (pChunk)
496 {
497 h->envd = (Environment_Data_Chunk *)pChunk;
498 }
499
500 return h;
501 }
502
load_rif_non_env(const char * fname)503 RIFFHANDLE load_rif_non_env (const char * fname)
504 {
505 File_Chunk * fc = new File_Chunk (fname);
506
507 if (fc->error_code != 0)
508 {
509 delete fc;
510 #if OUTPUT_LOG
511 CL_LogFile.lprintf("FAILED TO LOAD RIF: %s\n",fname);
512 #endif
513
514 ReleaseDirect3D();
515 fprintf(stderr, "load_rif_non_env: Error loading %s\n", fname);
516 exit(0x111);
517
518 return INVALID_RIFFHANDLE;
519 }
520 #if OUTPUT_LOG
521 CL_LogFile.lprintf("Successfully Loaded RIF: %s\n",fname);
522 #endif
523
524 RIFFHANDLE h = current_rif_handle = new _RifHandle;
525 h->fc = fc;
526
527 Chunk * pChunk = fc->lookup_single_child("REBENVDT");
528 if (pChunk)
529 {
530 h->envd = (Environment_Data_Chunk *)pChunk;
531 }
532
533 return h;
534 }
535
536
537 // deallocate the shapes, unload the rif, close the handle
undo_rif_load(RIFFHANDLE h)538 void undo_rif_load (RIFFHANDLE h)
539 {
540 deallocate_loaded_shapes(h);
541 unload_rif(h);
542 close_rif_handle(h);
543 }
544
545 // deallocate the shapes copied from the rif
deallocate_loaded_shapes(RIFFHANDLE h)546 void deallocate_loaded_shapes (RIFFHANDLE h)
547 {
548
549 // because the SHAPEHEADER is calloced, we can
550 // just delete the arrays we want
551
552 LIF<ShapeInMSL*> msl_shape_lif(&msl_shapes);
553
554 while (h->shape_nums.size())
555 {
556 #if !StandardShapeLanguage
557 #error Must have standard shape language
558 #endif
559
560 int list_pos = h->shape_nums.first_entry();
561 h->shape_nums.delete_first_entry();
562
563 DeallocateLoadedShapeheader(mainshapelist[list_pos]);
564
565 FreeMSLPos(list_pos);
566
567 for(msl_shape_lif.restart();!msl_shape_lif.done();msl_shape_lif.next())
568 {
569 if(list_pos==msl_shape_lif()->Listpos())
570 {
571 delete msl_shape_lif();
572 msl_shape_lif.delete_current();
573 break;
574 }
575 }
576 }
577
578 // ?????????? FIXME
579 if (Map[0].MapType6Objects)
580 {
581 DeallocateMem (Map[0].MapType6Objects);
582 Map[0].MapType6Objects = 0;
583 }
584 }
585
586 // unloads the rif but keeps the handle and associated copied shapes
unload_rif(RIFFHANDLE h)587 void unload_rif (RIFFHANDLE h)
588 {
589 if (h->fc)
590 {
591 if (h->fc == Env_Chunk)
592 Env_Chunk = 0;
593 delete h->fc;
594 h->fc = 0;
595 }
596 h->envd = 0;
597 h->palparent = 0;
598 h->max_index = 0;
599 if (h->tex_index_nos) delete[] h->tex_index_nos;
600 h->tex_index_nos = 0;
601 }
602
603 // close the handle - performs tidying up and memory deallocation
close_rif_handle(RIFFHANDLE h)604 void close_rif_handle (RIFFHANDLE h)
605 {
606 delete h;
607 }
608
609
610 //////////////////////////////////////////////////////////
611
612
613
614 // copies sprite to msl
copy_sprite_to_mainshapelist(RIFFHANDLE h,Sprite_Header_Chunk * shc,int)615 int copy_sprite_to_mainshapelist(RIFFHANDLE h, Sprite_Header_Chunk * shc, int/* flags*/)
616 {
617 int list_pos = GetMSLPos();
618
619 copy_sprite_to_shapeheader (h, mainshapelist[list_pos], shc, list_pos);
620
621 post_process_shape(mainshapelist[list_pos]);
622
623 h->shape_nums.add_entry(list_pos);
624
625 return list_pos;
626 }
627
setup_tex_conv_array(int & max_indices,int * & conv_array,RIFFHANDLE h,Chunk_With_Children * tmpshp)628 static void setup_tex_conv_array (
629 int & max_indices,
630 int * & conv_array,
631 RIFFHANDLE h,
632 Chunk_With_Children * tmpshp
633 )
634 {
635 String rif_name;
636
637 max_indices = h->max_index;
638 conv_array = h->tex_index_nos;
639
640 // find out if its come from elsewhere!!!!!!!
641 // Doo Dee Doo Doh
642 // Just come back from the pub - sorry
643
644 Chunk * pChunk = tmpshp->lookup_single_child("SHPEXTFL");
645
646 Shape_External_File_Chunk * seflc = 0;
647 Bitmap_List_Store_Chunk * blsc = 0;
648
649
650 if (pChunk)
651 {
652 seflc = (Shape_External_File_Chunk *)pChunk;
653 pChunk = seflc->lookup_single_child("BMPLSTST");
654 if (pChunk)
655 {
656 blsc = (Bitmap_List_Store_Chunk *) pChunk;
657 }
658 pChunk = seflc->lookup_single_child("RIFFNAME");
659 if (pChunk)
660 {
661 rif_name = ((RIF_Name_Chunk *)pChunk)->rif_name;
662 }
663 }
664
665 if (blsc)
666 {
667
668 // load in the textures from the shape
669
670 max_indices = 0;
671 LIF<BMP_Name> bns (&blsc->bmps);
672
673 for (; !bns.done(); bns.next())
674 {
675 max_indices = max(bns().index,max_indices);
676 }
677
678 conv_array = new int [max_indices+1];
679 for (int i=0; i<=max_indices; i++)
680 {
681 conv_array[i] = -1;
682 }
683
684 if (Env_Chunk == 0)
685 Env_Chunk = h->fc;
686 // JH 17-2-97 -- image loaders have changed to avoid loading the same image twice
687 for (bns.restart() ; !bns.done(); bns.next())
688 {
689 if (!(bns().flags & ChunkBMPFlag_NotInPC))
690 {
691 String tex;
692 if (bns().flags & ChunkBMPFlag_IFF)
693 {
694 tex = bns().filename;
695 }
696 else
697 {
698 tex = rif_name;
699 tex += "\\";
700 tex += bns().filename;
701 }
702
703 int imgnum = load_rif_bitmap(tex,bns().flags);
704 if (GEI_NOTLOADED != imgnum)
705 conv_array[bns().index] = imgnum;
706 }
707 }
708
709 }
710
711 }
712
CopyShapeAnimationHeader(SHAPEHEADER * shpfrom,SHAPEHEADER * shpto)713 void CopyShapeAnimationHeader(SHAPEHEADER* shpfrom,SHAPEHEADER* shpto)
714 {
715 GLOBALASSERT(shpfrom->numitems==shpto->numitems);
716 GLOBALASSERT(shpfrom->animation_header);
717 shpto->animation_header=shpfrom->animation_header;
718 shpto->animation_header->num_shapes_using_this++;
719 //find a sequence which has some frames;
720
721 shapeanimationsequence* sas=0;
722 for(int i=0;i<shpto->animation_header->num_sequences;i++)
723 {
724 sas=&shpto->animation_header->anim_sequences[i];
725 if(sas->num_frames)
726 break;
727
728 }
729 GLOBALASSERT(i<shpto->animation_header->num_sequences);
730
731 //copy the pointers for the first frame of this sequence
732 #if !USE_LEVEL_MEMORY_POOL
733 DeallocateMem(shpto->points[0]);
734 DeallocateMem(shpto->sh_normals[0]);
735 DeallocateMem(shpto->sh_vnormals[0]);
736 #endif
737
738 shpto->points[0]=sas->anim_frames[0].vertices;
739 shpto->sh_normals[0]=sas->anim_frames[0].item_normals;
740 shpto->sh_vnormals[0]=sas->vertex_normals;
741
742 }
743
744 // copies shape to msl
copy_to_mainshapelist(RIFFHANDLE h,Shape_Chunk * tmpshp,int flags,const ChunkObject * object)745 CTM_ReturnType copy_to_mainshapelist(RIFFHANDLE h, Shape_Chunk * tmpshp, int flags,const ChunkObject* object)
746 {
747 int local_max_index;
748 int * local_tex_index_nos;
749
750 int list_pos = GetMSLPos();
751 int main_shape_num = list_pos;
752 int start_shape_no = list_pos;
753 String rif_name;
754
755 setup_tex_conv_array (local_max_index, local_tex_index_nos, h, tmpshp);
756
757
758 Shape_Preprocessed_Data_Chunk* spdc=(Shape_Preprocessed_Data_Chunk*)tmpshp->lookup_single_child("SHPPRPRO");
759 if(spdc)
760 {
761 copy_preprocessed_to_shapeheader (
762 h,
763 spdc,
764 mainshapelist[list_pos],
765 tmpshp,
766 flags,
767 local_max_index,
768 local_tex_index_nos,
769 list_pos,
770 object
771 );
772 }
773 else
774 {
775
776 copy_to_shapeheader (
777 h,
778 tmpshp->shape_data,
779 mainshapelist[list_pos],
780 tmpshp,
781 flags,
782 local_max_index,
783 local_tex_index_nos,
784 list_pos,
785 object
786 );
787 }
788
789 Shape_External_File_Chunk * seflc = 0;
790
791 Chunk * pChunk = tmpshp->lookup_single_child("SHPEXTFL");
792
793 if (pChunk)
794 {
795 seflc = (Shape_External_File_Chunk *)pChunk;
796 rif_name = seflc->get_shape_name();
797 msl_shapes.add_entry(new ShapeInMSL(mainshapelist[list_pos],rif_name,list_pos));
798 }
799 else
800 {
801 List<Object_Chunk*> const & oblist=tmpshp->list_assoc_objs();
802 if(oblist.size())
803 {
804 Object_Chunk* oc=oblist.first_entry();
805 if(oc->get_header()->flags & OBJECT_FLAG_PLACED_OBJECT)
806 {
807 msl_shapes.add_entry(new ShapeInMSL(mainshapelist[list_pos],oc->object_data.o_name,list_pos));
808
809 }
810 }
811 }
812
813 post_process_shape(mainshapelist[list_pos]);
814
815 h->shape_nums.add_entry(list_pos);
816
817 if (tmpshp->count_children("ANIMSEQU"))
818 {
819 //look for alternate texture mappings
820 pChunk=tmpshp->lookup_single_child("ASALTTEX");
821 if(pChunk)
822 {
823 List<Chunk *> chlst;
824 ((Chunk_With_Children*)pChunk)->lookup_child("SUBSHAPE",chlst);
825 for(LIF<Chunk*> chlif(&chlst);!chlif.done();chlif.next())
826 {
827 Shape_Sub_Shape_Chunk* sssc=(Shape_Sub_Shape_Chunk*)chlif();
828
829 list_pos=GetMSLPos();
830 copy_to_shapeheader (
831 h,
832 sssc->shape_data,
833 mainshapelist[list_pos],
834 sssc,
835 flags,
836 local_max_index,
837 local_tex_index_nos,
838 list_pos,
839 object
840 );
841 CopyShapeAnimationHeader(mainshapelist[start_shape_no],mainshapelist[list_pos]);
842
843 const char* shpname=sssc->get_shape_name();
844 GLOBALASSERT(shpname);
845 msl_shapes.add_entry(new ShapeInMSL(mainshapelist[list_pos],shpname,list_pos));
846 h->shape_nums.add_entry(list_pos);
847
848 post_process_shape(mainshapelist[list_pos]);
849
850 }
851 }
852 }
853
854 Shape_Fragments_Chunk * sfc = 0;
855
856 pChunk = tmpshp->lookup_single_child ("SHPFRAGS");
857
858 if (pChunk)
859 {
860 sfc = (Shape_Fragments_Chunk *)pChunk;
861
862 pChunk=sfc->lookup_single_child("SHPFRGTP");
863 if(pChunk)
864 {
865 //the shape is using a fragment type
866 Shape_Fragment_Type_Chunk* sftc=(Shape_Fragment_Type_Chunk*)pChunk;
867 ApplyFragTypeToShape(mainshapelist[main_shape_num],sftc->frag_type_name);
868 }
869 else
870 {
871 List<Chunk *> cl;
872 sfc->lookup_child ("SUBSHAPE", cl);
873 if (cl.size())
874 {
875 mainshapelist[main_shape_num]->sh_fragdesc = (SHAPEFRAGMENTDESC *)PoolAllocateMem(sizeof(SHAPEFRAGMENTDESC));
876
877 mainshapelist[main_shape_num]->sh_fragdesc->sh_frags = (SHAPEFRAGMENT *)PoolAllocateMem((cl.size()+1) * sizeof(SHAPEFRAGMENT));
878 mainshapelist[main_shape_num]->sh_fragdesc->sh_fragsound = 0;
879
880 int fragpos = 0;
881
882 for (LIF<Chunk *> cli(&cl); !cli.done(); cli.next(), fragpos++)
883 {
884 Shape_Sub_Shape_Chunk * sssc = ((Shape_Sub_Shape_Chunk *)cli());
885
886 list_pos = GetMSLPos();
887
888
889 copy_to_shapeheader (
890 h,
891 sssc->shape_data,
892 mainshapelist[list_pos],
893 sssc,
894 flags,
895 local_max_index,
896 local_tex_index_nos,
897 list_pos,
898 object
899 );
900 post_process_shape(mainshapelist[list_pos]);
901 h->shape_nums.add_entry(list_pos);
902
903 int num_frags = 1;
904
905 pChunk = sssc->lookup_single_child("FRAGDATA");
906 if (pChunk)
907 {
908 num_frags = ((Shape_Fragments_Data_Chunk *)pChunk)->num_fragments;
909 }
910
911 Shape_Fragment_Location_Chunk * sflc = 0;
912
913 pChunk = sssc->lookup_single_child("FRAGLOCN");
914 if (pChunk)
915 {
916 sflc = (Shape_Fragment_Location_Chunk *)pChunk;
917 }
918
919
920 mainshapelist[main_shape_num]->sh_fragdesc->sh_frags[fragpos].ShapeIndex = list_pos;
921 mainshapelist[main_shape_num]->sh_fragdesc->sh_frags[fragpos].NumFrags = num_frags;
922
923 if (sflc)
924 {
925 mainshapelist[main_shape_num]->sh_fragdesc->sh_frags[fragpos].x_offset = (int)(sflc->frag_loc.x * local_scale);
926 mainshapelist[main_shape_num]->sh_fragdesc->sh_frags[fragpos].y_offset = (int)(sflc->frag_loc.y * local_scale);
927 mainshapelist[main_shape_num]->sh_fragdesc->sh_frags[fragpos].z_offset = (int)(sflc->frag_loc.z * local_scale);
928
929 }
930 else
931 {
932 mainshapelist[main_shape_num]->sh_fragdesc->sh_frags[fragpos].x_offset = 0;
933 mainshapelist[main_shape_num]->sh_fragdesc->sh_frags[fragpos].y_offset = 0;
934 mainshapelist[main_shape_num]->sh_fragdesc->sh_frags[fragpos].z_offset = 0;
935 }
936
937 }
938
939 mainshapelist[main_shape_num]->sh_fragdesc->sh_frags[fragpos].ShapeIndex = -1;
940 mainshapelist[main_shape_num]->sh_fragdesc->sh_frags[fragpos].NumFrags = -1;
941
942 //see if fragment has a sound to go with it
943 Fragment_Type_Sound_Chunk* ftsoc=(Fragment_Type_Sound_Chunk*) sfc->lookup_single_child("FRGSOUND");
944 if(ftsoc)
945 {
946 mainshapelist[main_shape_num]->sh_fragdesc->sh_fragsound=(SHAPEFRAGMENTSOUND*)PoolAllocateMem(sizeof(SHAPEFRAGMENTSOUND));
947 mainshapelist[main_shape_num]->sh_fragdesc->sh_fragsound->sound_loaded=GetSoundForMainRif (ftsoc->wav_name);
948 mainshapelist[main_shape_num]->sh_fragdesc->sh_fragsound->inner_range=(unsigned long)(ftsoc->inner_range*local_scale);
949 mainshapelist[main_shape_num]->sh_fragdesc->sh_fragsound->outer_range=(unsigned long)(ftsoc->outer_range*local_scale);
950 mainshapelist[main_shape_num]->sh_fragdesc->sh_fragsound->pitch=ftsoc->pitch;
951 mainshapelist[main_shape_num]->sh_fragdesc->sh_fragsound->max_volume=ftsoc->max_volume;
952 }
953
954
955 }
956 }
957 }
958
959 #if SupportMorphing && LOAD_MORPH_SHAPES
960
961 /*-------------------**
962 ** Morphing stuff **
963 **-------------------*/
964 MORPHCTRL * mc = 0;
965
966 if (!(flags & CCF_NOMORPH))
967 {
968 pChunk = tmpshp->lookup_single_child ("SHPMORPH");
969 if (pChunk)
970 {
971 // this shape has some morphing data
972
973 // (store the list no. of the shape)
974 Shape_Morphing_Data_Chunk * smdc = (Shape_Morphing_Data_Chunk *)pChunk;
975
976 // set all the subshape list_pos numbers to -1
977 // so later we can check to see if it has already been loaded
978 List<Chunk *> chlst;
979 smdc->lookup_child("SUBSHAPE",chlst);
980 for (LIF<Chunk *> ssi(&chlst); !ssi.done(); ssi.next())
981 {
982 ((Shape_Sub_Shape_Chunk *)ssi())->list_pos_number = -1;
983 }
984
985 pChunk = smdc->lookup_single_child("FRMMORPH");
986 if (pChunk)
987 {
988 Shape_Morphing_Frame_Data_Chunk * smfdc = (Shape_Morphing_Frame_Data_Chunk *)pChunk;
989 // Check there are some frames!!
990 if (smfdc->anim_frames.size())
991 {
992 mc = (MORPHCTRL *)AllocateMem(sizeof(MORPHCTRL));
993 mc->ObMorphFlags = smfdc->a_flags;
994 mc->ObMorphSpeed = smfdc->a_speed;
995 MORPHHEADER * mh = (MORPHHEADER *)AllocateMem(sizeof(MORPHHEADER));
996 mc->ObMorphHeader = mh;
997 mh->mph_numframes = 0;
998 mh->mph_frames = (MORPHFRAME *)AllocateMem(sizeof(MORPHFRAME) * (smfdc->anim_frames.size()) );
999
1000 int frame_no = 0;
1001
1002 for (LIF<a_frame *> afi(&smfdc->anim_frames); !afi.done(); afi.next())
1003 {
1004 if (afi()->shape1a)
1005 {
1006 if (afi()->shape1a->list_pos_number == -1)
1007 {
1008 list_pos = GetMSLPos();
1009
1010 Shape_Preprocessed_Data_Chunk* spdc=(Shape_Preprocessed_Data_Chunk*)afi()->shape1a->lookup_single_child("SHPPRPRO");
1011 if(spdc)
1012 {
1013 copy_preprocessed_to_shapeheader (
1014 h,
1015 spdc,
1016 mainshapelist[list_pos],
1017 afi()->shape1a,
1018 flags,
1019 local_max_index,
1020 local_tex_index_nos,
1021 list_pos,
1022 object
1023 );
1024 }
1025 else
1026 {
1027
1028 copy_to_shapeheader (
1029 h,
1030 afi()->shape1a->shape_data,
1031 mainshapelist[list_pos],
1032 afi()->shape1a,
1033 flags,
1034 local_max_index,
1035 local_tex_index_nos,
1036 list_pos,
1037 object
1038 );
1039 }
1040
1041 post_process_shape(mainshapelist[list_pos]);
1042 afi()->shape1a->list_pos_number = list_pos;
1043 h->shape_nums.add_entry(list_pos);
1044 /*
1045 Copy the item data for this door shape from the main shape. This is largely done to cope
1046 with the problem of the polygons being merged differently in different morph shapes.
1047 */
1048 SHAPEHEADER* main_shape=mainshapelist[main_shape_num];
1049 SHAPEHEADER* this_shape=mainshapelist[list_pos];
1050
1051 this_shape->numitems=main_shape->numitems;
1052 this_shape->items=main_shape->items;
1053 this_shape->sh_textures=main_shape->sh_textures;
1054 this_shape->sh_normals=main_shape->sh_normals;
1055
1056 //update shape instructions (probably not uses anyway)
1057 this_shape->sh_instruction[1].sh_numitems=main_shape->numitems;
1058 this_shape->sh_instruction[1].sh_instr_data=main_shape->sh_normals;
1059
1060 this_shape->sh_instruction[4].sh_numitems=main_shape->numitems;
1061 this_shape->sh_instruction[4].sh_instr_data=main_shape->items;
1062
1063 }
1064 mh->mph_frames[frame_no].mf_shape1 = afi()->shape1a->list_pos_number;
1065 }
1066 else
1067 {
1068 mh->mph_frames[frame_no].mf_shape1 = main_shape_num;
1069 }
1070
1071 if (afi()->shape2a)
1072 {
1073 if (afi()->shape2a->list_pos_number == -1)
1074 {
1075 list_pos = GetMSLPos();
1076
1077 Shape_Preprocessed_Data_Chunk* spdc=(Shape_Preprocessed_Data_Chunk*)afi()->shape2a->lookup_single_child("SHPPRPRO");
1078 if(spdc)
1079 {
1080 copy_preprocessed_to_shapeheader (
1081 h,
1082 spdc,
1083 mainshapelist[list_pos],
1084 afi()->shape1a,
1085 flags,
1086 local_max_index,
1087 local_tex_index_nos,
1088 list_pos,
1089 object
1090 );
1091 }
1092 else
1093 {
1094
1095 copy_to_shapeheader (
1096 h,
1097 afi()->shape2a->shape_data,
1098 mainshapelist[list_pos],
1099 afi()->shape2a,
1100 0,
1101 local_max_index,
1102 local_tex_index_nos,
1103 list_pos,
1104 object
1105 );
1106 }
1107 post_process_shape(mainshapelist[list_pos]);
1108 afi()->shape2a->list_pos_number = list_pos;
1109 h->shape_nums.add_entry(list_pos);
1110
1111 /*
1112 Copy the item data for this door shape from the main shape. This is largely done to cope
1113 with the problem of the polygons being merged differently in different morph shapes.
1114 */
1115 SHAPEHEADER* main_shape=mainshapelist[main_shape_num];
1116 SHAPEHEADER* this_shape=mainshapelist[list_pos];
1117
1118 this_shape->numitems=main_shape->numitems;
1119 this_shape->items=main_shape->items;
1120 this_shape->sh_textures=main_shape->sh_textures;
1121 this_shape->sh_normals=main_shape->sh_normals;
1122
1123 //update shape instructions (probably not uses anyway)
1124 this_shape->sh_instruction[1].sh_numitems=main_shape->numitems;
1125 this_shape->sh_instruction[1].sh_instr_data=main_shape->sh_normals;
1126
1127 this_shape->sh_instruction[4].sh_numitems=main_shape->numitems;
1128 this_shape->sh_instruction[4].sh_instr_data=main_shape->items;
1129 }
1130 mh->mph_frames[frame_no].mf_shape2 = afi()->shape2a->list_pos_number;
1131 }
1132 else
1133 {
1134 mh->mph_frames[frame_no].mf_shape2 = main_shape_num;
1135 }
1136 if (frame_no == 0)
1137 {
1138 start_shape_no = mh->mph_frames[frame_no].mf_shape1;
1139 }
1140 frame_no ++;
1141 }
1142 mh->mph_numframes = frame_no;
1143 mh->mph_maxframes = frame_no << 16;
1144 }
1145 }
1146 }
1147 }
1148
1149 CTM_ReturnType retval = { start_shape_no, main_shape_num, mc };
1150 if(local_tex_index_nos!=h->tex_index_nos) delete [] local_tex_index_nos;
1151 return retval;
1152
1153 #else
1154
1155 if(local_tex_index_nos!=h->tex_index_nos) delete [] local_tex_index_nos;
1156 return list_pos;
1157
1158 #endif
1159 }
1160
1161 // load textures for environment
load_rif_bitmaps(RIFFHANDLE h,int)1162 BOOL load_rif_bitmaps (RIFFHANDLE h, int/* flags*/)
1163 {
1164 Global_BMP_Name_Chunk * gbnc = 0;
1165
1166 if (h->envd)
1167 {
1168 Chunk * pChunk = h->envd->lookup_single_child ("BMPNAMES");
1169 if (pChunk) gbnc = (Global_BMP_Name_Chunk *) pChunk;
1170 }
1171
1172 h->max_index = 0;
1173
1174 if (gbnc)
1175 {
1176 LIF<BMP_Name> bns (&gbnc->bmps);
1177
1178 for (; !bns.done(); bns.next())
1179 {
1180 h->max_index = max(bns().index,h->max_index);
1181 }
1182
1183 if (h->tex_index_nos) delete h->tex_index_nos;
1184 h->tex_index_nos = new int [h->max_index+1];
1185 for (int i=0; i<=h->max_index; i++)
1186 {
1187 h->tex_index_nos[i] = -1;
1188 }
1189
1190 if (Env_Chunk == 0)
1191 Env_Chunk = h->fc;
1192 for (bns.restart() ; !bns.done(); bns.next())
1193 {
1194 if (!(bns().flags & ChunkBMPFlag_NotInPC))
1195 {
1196 // JH 17-2-97 -- image loaders have changed to avoid loading the same image twice
1197 int imgnum = load_rif_bitmap(bns().filename,bns().flags);
1198 if (GEI_NOTLOADED != imgnum)
1199 h->tex_index_nos[bns().index] = imgnum;
1200 }
1201 }
1202
1203 return TRUE;
1204 }
1205 else return FALSE;
1206 }
1207
1208 // set the quantization event depending on cl_pszGameMode
set_quantization_event(RIFFHANDLE h,int)1209 BOOL set_quantization_event(RIFFHANDLE h, int /*flags*/)
1210 {
1211 if (h->envd)
1212 {
1213 h->palparent = h->envd;
1214
1215 if (cl_pszGameMode)
1216 {
1217 List<Chunk *> egmcs;
1218 h->envd->lookup_child("GAMEMODE",egmcs);
1219
1220 for (LIF<Chunk *> egmcLIF(&egmcs); !egmcLIF.done(); egmcLIF.next())
1221 {
1222 Environment_Game_Mode_Chunk * egmcm = (Environment_Game_Mode_Chunk *) egmcLIF();
1223 if (egmcm->id_equals(cl_pszGameMode))
1224 {
1225 h->palparent = egmcm;
1226 break;
1227 }
1228 }
1229
1230 }
1231
1232 return TRUE;
1233 }
1234 else
1235 {
1236 h->palparent = 0;
1237 return FALSE;
1238 }
1239 }
1240
1241 // copy palette
copy_rif_palette(RIFFHANDLE h,int)1242 BOOL copy_rif_palette (RIFFHANDLE h, int /*flags*/)
1243 {
1244 if (h->palparent)
1245 {
1246 List<Chunk *> chlst;
1247 h->palparent->lookup_child("ENVPALET",chlst);
1248 for (LIF<Chunk *> i_ch(&chlst); !i_ch.done(); i_ch.next())
1249 {
1250 Environment_Palette_Chunk * palch = (Environment_Palette_Chunk *)i_ch();
1251 if (!(palch->flags & EnvPalFlag_V2) && palch->width*palch->height <= 256 )
1252 {
1253 for (int i=0; i<palch->width*palch->height*3; i++)
1254 {
1255 TestPalette[i] = (unsigned char)(palch->pixel_data[i] >> 2);
1256 }
1257 return TRUE;
1258 }
1259 }
1260 }
1261
1262 return FALSE;
1263 }
1264
1265 // copy texture lighting table
copy_rif_tlt(RIFFHANDLE h,int)1266 BOOL copy_rif_tlt (RIFFHANDLE h, int /*flags*/)
1267 {
1268 if (h->palparent)
1269 {
1270 List<Chunk *> chlst;
1271 h->palparent->lookup_child("ENVTXLIT",chlst);
1272 if(TextureLightingTable)
1273 {
1274 DeallocateMem(TextureLightingTable);
1275 TextureLightingTable = 0;
1276 }
1277 for (LIF<Chunk *> i_ch(&chlst); !i_ch.done(); i_ch.next())
1278 {
1279 Environment_TLT_Chunk * tltch = (Environment_TLT_Chunk *)i_ch();
1280
1281 if ((tltch->flags & ChunkTLTFlag_V2 &&
1282 ScreenDescriptorBlock.SDB_Flags & SDB_Flag_TLTPalette ||
1283 !(tltch->flags & ChunkTLTFlag_V2) &&
1284 !(ScreenDescriptorBlock.SDB_Flags & SDB_Flag_TLTPalette)) &&
1285 tltch->table
1286 ){
1287 TextureLightingTable = (unsigned char*)AllocateMem(tltch->width * tltch->num_levels);
1288 memcpy(TextureLightingTable,tltch->table,tltch->width*tltch->num_levels);
1289 if (ScreenDescriptorBlock.SDB_Flags & SDB_Flag_TLTPalette)
1290 {
1291 ScreenDescriptorBlock.SDB_Flags &= ~(SDB_Flag_TLTSize|SDB_Flag_TLTShift);
1292 if (tltch->width != 256)
1293 {
1294 int shft;
1295
1296 ScreenDescriptorBlock.SDB_Flags |= SDB_Flag_TLTSize;
1297 ScreenDescriptorBlock.TLTSize = tltch->width;
1298
1299 for (shft = 0; 1<<shft < tltch->width; ++shft)
1300 ;
1301 if (1<<shft==tltch->width)
1302 {
1303 ScreenDescriptorBlock.SDB_Flags |= SDB_Flag_TLTShift;
1304 ScreenDescriptorBlock.TLTShift = shft;
1305 }
1306 }
1307 }
1308 return TRUE;
1309 }
1310
1311 }
1312 }
1313
1314 return FALSE;
1315 }
1316
1317 // copy palette remap table (15-bit) - post_process_shape may use it
get_rif_palette_remap_table(RIFFHANDLE h,int)1318 BOOL get_rif_palette_remap_table (RIFFHANDLE h, int /*flags*/)
1319 {
1320 PaletteMapTable = 0;
1321 if (h->palparent)
1322 {
1323 Chunk * pChunk = h->palparent->lookup_single_child("CLRLOOKP");
1324 if (pChunk)
1325 {
1326 Coloured_Polygons_Lookup_Chunk * cplook = (Coloured_Polygons_Lookup_Chunk *)pChunk;
1327
1328 if (cplook->table)
1329 {
1330 PaletteMapTable = cplook->table;
1331 return TRUE;
1332 }
1333
1334 }
1335 }
1336
1337 return FALSE;
1338 }
1339
1340 // copy one named shape or sprite; intended to go in position listpos
CreateShapeFromRif(RIFFHANDLE h,char const * shapename,int listpos=GLS_NOTINLIST)1341 static SHAPEHEADER * CreateShapeFromRif (RIFFHANDLE h, char const * shapename, int listpos = GLS_NOTINLIST)
1342 {
1343 if (!h->fc) return 0; // no rif file loaded
1344
1345 List<Chunk *> shape_chunks;
1346 h->fc->lookup_child("REBSHAPE",shape_chunks);
1347
1348 for (LIF<Chunk *> search(&shape_chunks); !search.done(); search.next())
1349 {
1350 Shape_Chunk * cur_shape = (Shape_Chunk *) search();
1351
1352 Chunk * pShpextfile = cur_shape->lookup_single_child("SHPEXTFL");
1353
1354 if (pShpextfile)
1355 {
1356 Shape_External_File_Chunk * shexdata = (Shape_External_File_Chunk *) pShpextfile;
1357
1358 Chunk * pRnc = shexdata->lookup_single_child("RIFFNAME");
1359 if (pRnc)
1360 {
1361 RIF_Name_Chunk * rnc = (RIF_Name_Chunk *) pRnc;
1362 if (!_stricmp(rnc->rif_name,shapename)) // haha! matching shape found
1363 {
1364 SHAPEHEADER * shptr = 0;
1365 int local_max_index;
1366 int * local_tex_index_nos;
1367 setup_tex_conv_array (local_max_index, local_tex_index_nos, h, cur_shape);
1368
1369 copy_to_shapeheader(
1370 h,
1371 cur_shape->shape_data,
1372 shptr,
1373 cur_shape,
1374 0,
1375 local_max_index,
1376 local_tex_index_nos,
1377 listpos
1378 );
1379 if(local_tex_index_nos!=h->tex_index_nos) delete [] local_tex_index_nos;
1380
1381 return shptr;
1382 }
1383 }
1384 }
1385 }
1386 //look to see if is a sprite
1387 Chunk * pSprite_chunks = h->fc->lookup_single_child("RSPRITES");
1388 if(pSprite_chunks)
1389 {
1390 AllSprites_Chunk* asc=(AllSprites_Chunk*) pSprite_chunks;
1391 List<Chunk *> sprite_chunks;
1392 asc->lookup_child("SPRIHEAD",sprite_chunks);
1393 for(LIF<Chunk*> slif(&sprite_chunks);!slif.done();slif.next())
1394 {
1395 Sprite_Header_Chunk* shc=(Sprite_Header_Chunk*)slif();
1396 Chunk * pRn=shc->lookup_single_child("RIFFNAME");
1397 if(pRn)
1398 {
1399 RIF_Name_Chunk* rnc=(RIF_Name_Chunk*)pRn;
1400 if (!_stricmp(rnc->rif_name,shapename)) // haha! matching sprite found
1401 {
1402 SHAPEHEADER * shptr = 0;
1403 copy_sprite_to_shapeheader(h,shptr, shc, listpos);
1404 return shptr;
1405 }
1406 }
1407
1408 }
1409 }
1410 return 0; // could not match shape
1411 }
1412
1413 // copy one named shape or sprite; does not put in main shape list
CopyNamedShapePtr(RIFFHANDLE h,char const * shapename)1414 SHAPEHEADER * CopyNamedShapePtr (RIFFHANDLE h, char const * shapename)
1415 {
1416 return CreateShapeFromRif(h,shapename);
1417 }
1418
1419 // copy one named shape or sprite; put it in the main shape list
CopyNamedShapeMSL(RIFFHANDLE h,char const * shapename)1420 int CopyNamedShapeMSL (RIFFHANDLE h, char const * shapename)
1421 {
1422 int listpos = GetMSLPos();
1423 SHAPEHEADER * shp = CreateShapeFromRif(h,shapename,listpos);
1424 if (shp)
1425 {
1426 h->shape_nums.add_entry(listpos);
1427 mainshapelist[listpos] = shp;
1428 return listpos;
1429 }
1430 else
1431 {
1432 FreeMSLPos(listpos);
1433 return GLS_NOTINLIST;
1434 }
1435 }
1436
1437 ////////////////////////////////////////////////////////////////////////
1438 // Functions which do not operate on RIFFHANDLEs and may become obsolete
1439 ////////////////////////////////////////////////////////////////////////
1440
CopyNamedShape(char const * shapename)1441 SHAPEHEADER * CopyNamedShape (char const * shapename)
1442 {
1443 return CopyNamedShapePtr (current_rif_handle,shapename);
1444 }
1445
1446 /////////////////////////////////////////////
1447 // Functions for handling the main shape list
1448 /////////////////////////////////////////////
1449
1450 ////////////////////////////////////////////////
1451 // Functions retrieving data about loaded shapes
1452 ////////////////////////////////////////////////
1453
1454 // gets the main shape list position of a shape loaded into the msl
GetLoadedShapeMSL(char const * shapename)1455 int GetLoadedShapeMSL(char const * shapename)
1456 {
1457 ShapeInMSL const * sim = ShapeInMSL::GetByName(shapename);
1458
1459 if (sim)
1460 return sim->Listpos();
1461 else
1462 return GLS_NOTINLIST;
1463 }
1464
1465 // ditto, but returns a pointer; the shape need not be in the msl
GetLoadedShapePtr(char const * shapename)1466 SHAPEHEADER * GetLoadedShapePtr(char const * shapename)
1467 {
1468 ShapeInMSL const * sim = ShapeInMSL::GetByName(shapename);
1469
1470 if (sim)
1471 return sim->Shptr();
1472 else
1473 return 0;
1474 }
1475
1476 // gets name of shape from msl pos
GetMSLLoadedShapeName(int listpos)1477 char const * GetMSLLoadedShapeName(int listpos)
1478 {
1479 ShapeInMSL const * sim = ShapeInMSL::GetByMSL(listpos);
1480
1481 if (sim)
1482 return sim->Name();
1483 else
1484 return 0;
1485 }
1486
1487 // gets name of shape from pointer; the shape need not be in msl
GetPtrLoadedShapeName(SHAPEHEADER * shptr)1488 char const * GetPtrLoadedShapeName(SHAPEHEADER * shptr)
1489 {
1490 ShapeInMSL const * sim = ShapeInMSL::GetByPtr(shptr);
1491
1492 if (sim)
1493 return sim->Name();
1494 else
1495 return 0;
1496 }
1497
1498 // free a reference to a named shape if it exists - not necessary since these are all tidied up
FreeShapeNameReference(SHAPEHEADER * shptr)1499 void FreeShapeNameReference(SHAPEHEADER * shptr)
1500 {
1501 for (LIF<ShapeInMSL*> search(&msl_shapes); !search.done(); search.next())
1502 {
1503 if (search()->Shptr() == shptr)
1504 {
1505 delete search();
1506 search.delete_current();
1507 break;
1508 }
1509 }
1510
1511 return;
1512 }
1513
1514 //////////////////////////////////////////////////////////////////////////////
1515 // Initializing, deallocating of shapes, mainly hooks for project specific fns
1516 //////////////////////////////////////////////////////////////////////////////
1517
1518 // delete a shape by the shapeheader
DeallocateLoadedShapePtr(SHAPEHEADER * shp)1519 void DeallocateLoadedShapePtr(SHAPEHEADER * shp)
1520 {
1521 DeallocateLoadedShapeheader(shp);
1522
1523 FreeShapeNameReference(shp);
1524 }
1525
1526 // delete a shape by the shape list number
DeallocateLoadedShapeMSL(RIFFHANDLE h,int list_pos)1527 void DeallocateLoadedShapeMSL(RIFFHANDLE h, int list_pos)
1528 {
1529 h->shape_nums.delete_entry(list_pos);
1530
1531 DeallocateLoadedShapeheader(mainshapelist[list_pos]);
1532
1533 FreeMSLPos(list_pos);
1534
1535 for(LIF<ShapeInMSL*> msl_shape_lif(&msl_shapes);!msl_shape_lif.done();msl_shape_lif.next())
1536 {
1537 if(list_pos==msl_shape_lif()->Listpos())
1538 {
1539 delete msl_shape_lif();
1540 msl_shape_lif.delete_current();
1541 break;
1542 }
1543 }
1544 }
1545
DeallocateRifLoadedShapeheader(SHAPEHEADER * shp)1546 void DeallocateRifLoadedShapeheader(SHAPEHEADER * shp)
1547 {
1548 // because the SHAPEHEADER is calloced, we can
1549 // just delete the arrays we want
1550
1551 #if !StandardShapeLanguage
1552 #error Must have standard shape language
1553 #endif
1554
1555 if(shp->animation_header)
1556 {
1557 // so it gets deallocated properly
1558 shp->points[0] = 0;
1559 shp->sh_normals[0] = 0;
1560 shp->sh_vnormals[0] = 0;
1561 }
1562 if (shp->sh_fragdesc)
1563 {
1564 DeallocateFragments(shp,shp->sh_fragdesc);
1565 }
1566
1567 #if !USE_LEVEL_MEMORY_POOL
1568 int max_num_texs = 0;
1569 int i;
1570
1571 if (shp->points)
1572 {
1573 if (*shp->points) DeallocateMem(*shp->points);
1574 DeallocateMem(shp->points);
1575 }
1576 if (shp->sh_normals)
1577 {
1578 if (*shp->sh_normals) DeallocateMem(*shp->sh_normals);
1579 DeallocateMem(shp->sh_normals);
1580 }
1581 if (shp->sh_vnormals)
1582 {
1583 if (*shp->sh_vnormals) DeallocateMem(*shp->sh_vnormals);
1584 DeallocateMem(shp->sh_vnormals);
1585 }
1586 if (shp->sh_extraitemdata)
1587 DeallocateMem(shp->sh_extraitemdata);
1588 /* the items are allocated in one big bunch
1589 // 9 int's per item (to make bsp simple)
1590 // this should be changed if it is to be done
1591 // a different way
1592 */
1593 if (shp->items)
1594 {
1595 if(shp->shapeflags & ShapeFlag_MultiViewSprite)
1596 {
1597 TXANIMHEADER** thlist=(TXANIMHEADER**)shp->sh_textures[0];
1598 for(int j=1;thlist[j]!=0;j++)
1599 {
1600 int k;
1601 TXANIMHEADER* th=thlist[j];
1602 for(k=0;k<th->txa_numframes;k++)
1603 {
1604 txanimframe_mvs* tf=(txanimframe_mvs*)&th->txa_framedata[k];
1605 if(tf->txf_uvdata[0])DeallocateMem(tf->txf_uvdata[0]);
1606 if(tf->txf_uvdata)DeallocateMem(tf->txf_uvdata);
1607 if(tf->txf_images)DeallocateMem(tf->txf_images);
1608 }
1609 if(th->txa_framedata)DeallocateMem (th->txa_framedata);
1610 DeallocateMem (th);
1611 }
1612 DeallocateMem (thlist);
1613 shp->sh_textures[0]=0;
1614 }
1615 else
1616 {
1617 for (i=0; i<shp->numitems; i++)
1618 {
1619 if (is_textured(shp->items[i][0]))
1620 {
1621 int UVIndex = (shp->items[i][3] &0xffff0000) >> 16;
1622 max_num_texs = max (max_num_texs, shp->items[i][3] &0x7fff);
1623 if(shp->items[i][2]& iflag_txanim)
1624 {
1625 int j;
1626 TXANIMHEADER** thlist=(TXANIMHEADER**)shp->sh_textures[UVIndex];
1627 for(j=1;thlist[j]!=0;j++)
1628 {
1629 int k;
1630 TXANIMHEADER* th=thlist[j];
1631 for(k=0;k<th->txa_numframes;k++)
1632 {
1633 if(th->txa_framedata[k].txf_uvdata)DeallocateMem(th->txa_framedata[k].txf_uvdata);
1634 }
1635 if(th->txa_framedata)DeallocateMem (th->txa_framedata);
1636 DeallocateMem (th);
1637 }
1638 DeallocateMem (thlist);
1639 shp->sh_textures[UVIndex]=0;
1640 }
1641 else
1642 {
1643 if(shp->sh_textures[UVIndex])DeallocateMem(shp->sh_textures[UVIndex]);
1644 }
1645 }
1646 }
1647 }
1648 DeallocateMem (*shp->items);
1649 DeallocateMem (shp->items);
1650 }
1651
1652 if (shp->sh_textures)
1653 {
1654 DeallocateMem (shp->sh_textures);
1655 }
1656
1657 if (shp->sh_localtextures)
1658 {
1659 for (i=0; i<(max_num_texs+1); i++)
1660 {
1661 DeallocateMem (shp->sh_localtextures[i]);
1662 }
1663 DeallocateMem (shp->sh_localtextures);
1664 }
1665
1666
1667
1668 #if SupportTrackOptimisation
1669 if (shp->sh_track_data)
1670 DeallocateMem(shp->sh_track_data);
1671 #endif
1672 if (shp->sh_instruction)
1673 DeallocateMem(shp->sh_instruction);
1674 #if SupportBSP
1675 if (shp->sh_bsp_blocks)
1676 DeallocateMem(shp->sh_bsp_blocks);
1677 #endif
1678
1679 if(shp->animation_header)
1680 {
1681 shp->animation_header->num_shapes_using_this--;
1682 if(shp->animation_header->num_shapes_using_this==0)
1683 {
1684 shapeanimationheader* sah=shp->animation_header;
1685 for(int i=0;i<sah->num_sequences;i++)
1686 {
1687 shapeanimationsequence* sas=&sah->anim_sequences[i];
1688 for(int j=0;j<sas->num_frames;j++)
1689 {
1690 shapeanimationframe*saf=&sas->anim_frames[j];
1691 DeallocateMem(saf->vertices);
1692 DeallocateMem(saf->item_normals);
1693 }
1694 if(sas->vertex_normals)DeallocateMem(sas->vertex_normals);
1695 if(sas->anim_frames)DeallocateMem(sas->anim_frames);
1696 }
1697 DeallocateMem(sah->anim_sequences);
1698 DeallocateMem(sah);
1699 }
1700 }
1701
1702 if(shp->shape_degradation_array)
1703 {
1704 DeallocateMem(shp->shape_degradation_array);
1705 }
1706
1707 DeallocateMem(shp);
1708 #endif //!USE_LEVEL_MEMORY_POOL
1709 }
1710
1711 ///////
1712 // Misc
1713 ///////
1714
1715 // return TRUE if the poly item type corresponds to a textured polygon
is_textured(int type)1716 BOOL is_textured (int type)
1717 {
1718 if (
1719 type == I_2dTexturedPolygon
1720 || type == I_Gouraud2dTexturedPolygon
1721 || type == I_3dTexturedPolygon
1722 || type == I_Gouraud3dTexturedPolygon
1723 || type == I_ZB_2dTexturedPolygon
1724 || type == I_ZB_Gouraud2dTexturedPolygon
1725 || type == I_ZB_3dTexturedPolygon
1726 || type == I_ZB_Gouraud3dTexturedPolygon
1727 )
1728 {
1729 return(TRUE);
1730 }
1731 return(FALSE);
1732 }
1733
1734
1735 #if SupportModules
1736
1737 // static Object_Chunk ** o_chunk_array;
1738
copy_to_module(Object_Chunk * ob,int mod_pos,int shplst_pos)1739 void copy_to_module (Object_Chunk * ob, int mod_pos, int shplst_pos)
1740 {
1741 Object_Project_Data_Chunk * opdc = 0;
1742 Map_Block_Chunk * mapblok = 0;
1743 Strategy_Chunk * strat = 0;
1744
1745 MODULEMAPBLOCK * Map = (MODULEMAPBLOCK *) PoolAllocateMem (sizeof(MODULEMAPBLOCK));
1746
1747 *Map = Empty_Module_Map;
1748
1749 MainScene.sm_module[mod_pos].m_mapptr = Map;
1750 MainScene.sm_module[mod_pos].name = (char *) PoolAllocateMem (strlen (ob->object_data.o_name)+1);
1751 strcpy (MainScene.sm_module[mod_pos].name, ob->object_data.o_name);
1752
1753 *((int *)MainScene.sm_module[mod_pos].m_name) = mod_pos + ONE_FIXED;
1754 // add 65536 to this value to this value to preserve 0
1755
1756 Chunk * pChunk = ob->lookup_single_child("OBJPRJDT");
1757 if (pChunk) opdc = (Object_Project_Data_Chunk *)pChunk;
1758 if (opdc)
1759 {
1760 pChunk = opdc->lookup_single_child("MAPBLOCK");
1761 if (pChunk) mapblok = (Map_Block_Chunk *)pChunk;
1762 pChunk = opdc->lookup_single_child("STRATEGY");
1763 if (pChunk) strat = (Strategy_Chunk *)pChunk;
1764 }
1765
1766 if (mapblok)
1767 {
1768 Map->MapType = mapblok->map_data.MapType;
1769 Map->MapFlags= mapblok->map_data.MapFlags;
1770 #if (StandardStrategyAndCollisions || IntermediateSSACM)
1771 Map->MapCType = mapblok->map_data.MapCType;
1772 Map->MapCGameType = mapblok->map_data.MapCGameType;
1773 Map->MapCStrategyS = mapblok->map_data.MapCStrategyS;
1774 Map->MapCStrategyL = mapblok->map_data.MapCStrategyL;
1775 #endif
1776 Map->MapInteriorType = mapblok->map_data.MapInteriorType;
1777 // Map->MapLightType = mapblok->map_data.MapLightType;
1778 // Map->MapMass = mapblok->map_data.MapMass;
1779 // Map->MapNewtonV.vx = mapblok->map_data.MapNewtonV.vx;
1780 // Map->MapNewtonV.vy = mapblok->map_data.MapNewtonV.vy;
1781 // Map->MapNewtonV.vz = mapblok->map_data.MapNewtonV.vz;
1782 // Map->MapOrigin.vx = mapblok->map_data.MapOrigin.vx;
1783 // Map->MapOrigin.vy = mapblok->map_data.MapOrigin.vy;
1784 // Map->MapOrigin.vz = mapblok->map_data.MapOrigin.vz;
1785 // Map->MapViewType = mapblok->map_data.MapViewType;
1786 }
1787
1788 #if (StandardStrategyAndCollisions || IntermediateSSACM)
1789 if (strat)
1790 {
1791 Map->MapStrategy = strat->strategy_data.Strategy;
1792 }
1793 #endif
1794
1795 Map->MapShape = shplst_pos;
1796
1797 Map->MapWorld.vx = (int) (ob->object_data.location.x*local_scale);
1798 Map->MapWorld.vy = (int) (ob->object_data.location.y*local_scale);
1799 Map->MapWorld.vz = (int) (ob->object_data.location.z*local_scale);
1800
1801 #if 0
1802 QUAT q;
1803
1804 q.quatx = (int) (ob->object_data.orientation.x*ONE_FIXED);
1805 q.quaty = (int) (ob->object_data.orientation.y*ONE_FIXED);
1806 q.quatz = (int) (ob->object_data.orientation.z*ONE_FIXED);
1807 q.quatw = (int) (ob->object_data.orientation.w*ONE_FIXED);
1808
1809
1810 MATRIXCH m;
1811
1812 QuatToMat (&q, &m);
1813
1814 EULER e;
1815
1816 MatrixToEuler(&m, &e);
1817
1818 Map->MapEuler.EulerX = -e.EulerX;
1819 Map->MapEuler.EulerY = -e.EulerY;
1820 Map->MapEuler.EulerZ = -e.EulerZ;
1821
1822 #endif
1823
1824
1825 }
1826
1827 #endif
1828
SetupAnimOnTriangle(SHAPEHEADER * shp,TEXANIM * ta,int poly,int * local_tex_index_nos)1829 void SetupAnimOnTriangle(SHAPEHEADER* shp,TEXANIM* ta,int poly, int * local_tex_index_nos)
1830 {
1831 if(!is_textured(shp->items[poly][0]))return;
1832 txanimheader** thlist=(txanimheader**)PoolAllocateMem((ta->NumSeq+2)*sizeof(txanimheader*));
1833 thlist[0]=0;
1834 thlist[ta->NumSeq+1]=0;
1835 for(int i=0;i<ta->NumSeq;i++)
1836 {
1837 thlist[i+1]=(txanimheader*)PoolAllocateMem(sizeof(txanimheader));
1838 txanimheader* th=thlist[i+1];
1839
1840 FrameList* fl=ta->Seq[i];
1841 th->txa_flags=fl->Flags;
1842 if(!(ta->AnimFlags & AnimFlag_NotPlaying))th->txa_flags|=txa_flag_play;
1843 th->txa_numframes=fl->NumFrames+1;
1844 if(fl->Flags & txa_flag_nointerptofirst)
1845 {
1846 th->txa_flags&=~txa_flag_nointerptofirst;
1847 th->txa_numframes--;
1848 }
1849 th->txa_currentframe=0;
1850 th->txa_state=0;
1851 th->txa_maxframe=(th->txa_numframes-1)<<16;
1852 th->txa_speed=fl->Speed;
1853 th->txa_framedata=(txanimframe*)PoolAllocateMem(th->txa_numframes*sizeof(txanimframe));
1854 th->txa_anim_id=ta->Identifier;
1855
1856 txanimframe* tf;
1857 for(int j=0;j<th->txa_numframes;j++)
1858 {
1859 tf=&th->txa_framedata[j];
1860 tf->txf_flags=0;
1861 tf->txf_scale=ONE_FIXED;
1862 tf->txf_scalex=0;
1863 tf->txf_scaley=0;
1864 tf->txf_orient=0;
1865 tf->txf_orientx=0;
1866 tf->txf_orienty=0;
1867 tf->txf_numuvs=3;
1868 tf->txf_uvdata=(int*)PoolAllocateMem(6*sizeof(int));
1869 if(j==fl->NumFrames)
1870 {
1871 tf->txf_image=local_tex_index_nos[fl->Textures[0]];
1872 for(int k=0;k<6;k++)
1873 {
1874 tf->txf_uvdata[k]=fl->UVCoords[k]<<16;
1875 }
1876 }
1877 else
1878 {
1879 tf->txf_image=local_tex_index_nos[fl->Textures[j]];
1880 for(int k=0;k<6;k++)
1881 {
1882 tf->txf_uvdata[k]=fl->UVCoords[j*6+k]<<16;
1883 }
1884 }
1885 }
1886 }
1887 int UVIndex=shp->items[poly][3]>>16;
1888 #if !USE_LEVEL_MEMORY_POOL
1889 if(shp->sh_textures[UVIndex])DeallocateMem(shp->sh_textures[UVIndex]);
1890 #endif
1891 shp->sh_textures[UVIndex]=(int*)thlist;
1892 shp->items[poly][2]|=iflag_txanim;
1893 shp->items[poly][3]=UVIndex<<16;
1894
1895 }
SetupAnimOnQuad(Shape_Chunk * sc,SHAPEHEADER * shp,TEXANIM * ta1,TEXANIM * ta2,int poly,int * local_tex_index_nos)1896 void SetupAnimOnQuad(Shape_Chunk* sc,SHAPEHEADER* shp,TEXANIM* ta1,TEXANIM* ta2,int poly, int * local_tex_index_nos)
1897 {
1898 if(!is_textured(shp->items[poly][0]))return;
1899 if(ta1->ID!=ta2->ID)return;
1900 int VertConv[3];//conversion between vert nos in triangles and vert nos in quad
1901 int VertFrom,VertTo;//for remaining vert in second poly
1902 int i;
1903
1904 VertTo=6;
1905 for(i=0;i<3;i++)
1906 {
1907 int j;
1908
1909 for(j=0;j<4;j++)
1910 {
1911 if(sc->shape_data.poly_list[ta1->poly].vert_ind[i]==(shp->items[poly][j+4]))break;
1912 }
1913 if(j==4)return;
1914 VertConv[i]=j;
1915 VertTo-=j;
1916 }
1917 for(i=0;i<3;i++)
1918 {
1919 if(sc->shape_data.poly_list[ta2->poly].vert_ind[i]==(shp->items[poly][4+VertTo]))break;
1920 }
1921 if(i==3)return;
1922 VertFrom=i;
1923
1924 txanimheader** thlist=(txanimheader**)PoolAllocateMem((ta1->NumSeq+2)*sizeof(txanimheader*));
1925 thlist[0]=0;
1926 thlist[ta1->NumSeq+1]=0;
1927 for(i=0;i<ta1->NumSeq;i++)
1928 {
1929 thlist[i+1]=(txanimheader*)PoolAllocateMem(sizeof(txanimheader));
1930 txanimheader* th=thlist[i+1];
1931 FrameList* fl1=ta1->Seq[i];
1932 FrameList* fl2=ta2->Seq[i];
1933 th->txa_flags=fl1->Flags;
1934 if(!(ta1->AnimFlags & AnimFlag_NotPlaying))th->txa_flags|=txa_flag_play;
1935 th->txa_numframes=fl1->NumFrames+1;
1936 if(fl1->Flags & txa_flag_nointerptofirst)
1937 {
1938 th->txa_flags&=~txa_flag_nointerptofirst;
1939 th->txa_numframes--;
1940 }
1941 th->txa_currentframe=0;
1942 th->txa_state=0;
1943 th->txa_maxframe=(th->txa_numframes-1)<<16;
1944 th->txa_speed=fl1->Speed;
1945 th->txa_framedata=(txanimframe*)PoolAllocateMem(th->txa_numframes*sizeof(txanimframe));
1946 th->txa_anim_id=ta1->Identifier;
1947
1948 txanimframe* tf;
1949 for(int j=0;j<th->txa_numframes;j++)
1950 {
1951 tf=&th->txa_framedata[j];
1952 tf->txf_flags=0;
1953 tf->txf_scale=ONE_FIXED;
1954 tf->txf_scalex=0;
1955 tf->txf_scaley=0;
1956 tf->txf_orient=0;
1957 tf->txf_orientx=0;
1958 tf->txf_orienty=0;
1959 tf->txf_numuvs=4;
1960 tf->txf_uvdata=(int*)PoolAllocateMem(8*sizeof(int));
1961 if(j==fl1->NumFrames)
1962 {
1963 tf->txf_image=local_tex_index_nos[fl1->Textures[0]];
1964 for(int k=0;k<3;k++)
1965 {
1966 tf->txf_uvdata[VertConv[k]*2]=fl1->UVCoords[k*2]<<16;
1967 tf->txf_uvdata[VertConv[k]*2+1]=fl1->UVCoords[k*2+1]<<16;
1968 }
1969 tf->txf_uvdata[VertTo*2]=fl2->UVCoords[VertFrom*2]<<16;
1970 tf->txf_uvdata[VertTo*2+1]=fl2->UVCoords[VertFrom*2+1]<<16;
1971
1972 }
1973 else
1974 {
1975 tf->txf_image=local_tex_index_nos[fl1->Textures[j]];
1976 for(int k=0;k<3;k++)
1977 {
1978 tf->txf_uvdata[VertConv[k]*2]=fl1->UVCoords[j*6+k*2]<<16;
1979 tf->txf_uvdata[VertConv[k]*2+1]=fl1->UVCoords[j*6+k*2+1]<<16;
1980 }
1981 tf->txf_uvdata[VertTo*2]=fl2->UVCoords[j*6+VertFrom*2]<<16;
1982 tf->txf_uvdata[VertTo*2+1]=fl2->UVCoords[j*6+VertFrom*2+1]<<16;
1983 }
1984 }
1985 }
1986 int UVIndex=shp->items[poly][3]>>16;
1987 #if !USE_LEVEL_MEMORY_POOL
1988 if(shp->sh_textures[UVIndex])DeallocateMem(shp->sh_textures[UVIndex]);
1989 #endif
1990 shp->sh_textures[UVIndex]=(int*)thlist;
1991 shp->items[poly][2]|=iflag_txanim;
1992 shp->items[poly][3]=UVIndex<<16;
1993
1994
1995 }
SetupAnimatedTextures(Shape_Chunk * sc,SHAPEHEADER * shp,Animation_Chunk * ac,Shape_Merge_Data_Chunk * smdc,int * local_tex_index_nos)1996 void SetupAnimatedTextures(Shape_Chunk* sc,SHAPEHEADER* shp,Animation_Chunk* ac,Shape_Merge_Data_Chunk* smdc, int * local_tex_index_nos)
1997 {
1998 //create conversion between unmerged poly nos and merged poly nos
1999 int* PolyConv=0;
2000 int* mgd=0;
2001
2002 if(smdc)
2003 {
2004 mgd=smdc->merge_data;
2005 PolyConv=new int[smdc->num_polys];
2006 for(int i=0, j=0;i<smdc->num_polys;i++)
2007 {
2008 if(mgd[i]==-1)
2009 {
2010 PolyConv[i]=j;
2011 j++;
2012 }
2013 else if(mgd[i]>i)
2014 {
2015 if(shp->items[j][7]==-1)
2016 {
2017 //quad in merge data,but not actually merged;
2018 PolyConv[i]=j;
2019 j++;
2020 PolyConv[mgd[i]]=j;
2021 j++;
2022 }
2023 else
2024 {
2025 PolyConv[i]=j;
2026 PolyConv[mgd[i]]=j;
2027 j++;
2028 }
2029 }
2030
2031 }
2032
2033 for(int i=0;i<ac->NumPolys;i++)
2034 {
2035 TEXANIM* ta1,*ta2;
2036 ta1=ac->AnimList[i];
2037 if(mgd[ta1->poly]==-1)
2038 {
2039 SetupAnimOnTriangle(shp,ta1,PolyConv[ta1->poly], local_tex_index_nos);
2040 }
2041 else if(mgd[ta1->poly]>ta1->poly)
2042 {
2043 int j;
2044
2045 for(j=0;j<ac->NumPolys;j++)
2046 {
2047 if(ac->AnimList[j]->poly==mgd[ta1->poly])break;
2048 }
2049 if(j<ac->NumPolys)
2050 {
2051 ta2=ac->AnimList[j];
2052 if(PolyConv[ta1->poly]==PolyConv[ta2->poly])
2053 {
2054 SetupAnimOnQuad(sc,shp,ta1,ta2,PolyConv[ta1->poly], local_tex_index_nos);
2055 }
2056 else
2057 {
2058 SetupAnimOnTriangle(shp,ta1,PolyConv[ta1->poly], local_tex_index_nos);
2059 SetupAnimOnTriangle(shp,ta2,PolyConv[ta2->poly], local_tex_index_nos);
2060 }
2061 }
2062 else if(PolyConv[ta1->poly]!=PolyConv[mgd[ta1->poly]])
2063 {
2064 SetupAnimOnTriangle(shp,ta1,PolyConv[ta1->poly], local_tex_index_nos);
2065 }
2066 }
2067 }
2068 if(PolyConv)delete [] PolyConv;
2069 }
2070 else
2071 {
2072 for(int i=0;i<ac->NumPolys;i++)
2073 {
2074 SetupAnimOnTriangle(shp,ac->AnimList[i],ac->AnimList[i]->poly, local_tex_index_nos);
2075 }
2076 }
2077 shp->shapeflags|=ShapeFlag_HasTextureAnimation;
2078 }
2079
2080
SetupAnimatingShape(Shape_Chunk * sc,SHAPEHEADER * shp,Shape_Merge_Data_Chunk * smdc)2081 void SetupAnimatingShape(Shape_Chunk* sc,SHAPEHEADER* shp, Shape_Merge_Data_Chunk* smdc)
2082 {
2083 //create conversion between unmerged poly nos and merged poly nos
2084 int* PolyConv=0;
2085 int* mgd=0;
2086
2087 PolyConv=new int[smdc->num_polys];
2088
2089 if(smdc)
2090 {
2091 mgd=smdc->merge_data;
2092 for(int i=0, j=0;i<smdc->num_polys;i++)
2093 {
2094 if(mgd[i]==-1)
2095 {
2096 PolyConv[i]=j;
2097 j++;
2098 }
2099 else if(mgd[i]>i)
2100 {
2101 if(shp->items[j][7]==-1)
2102 {
2103 //quad in merge data,but not actually merged;
2104 PolyConv[i]=j;
2105 j++;
2106 PolyConv[mgd[i]]=j;
2107 j++;
2108 }
2109 else
2110 {
2111 PolyConv[i]=j;
2112 PolyConv[mgd[i]]=j;
2113 j++;
2114 }
2115 }
2116
2117 }
2118
2119 }
2120 else
2121 {
2122 for(int i=0;i<smdc->num_polys;i++)
2123 {
2124 PolyConv[i]=i;
2125 }
2126 }
2127
2128 ChunkVectorInt Centre={0,0,0};
2129 Chunk * pChunk = sc->lookup_single_child("ANSHCEN2");
2130 if(pChunk)
2131 Centre=((Anim_Shape_Centre_Chunk*)pChunk)->Centre;
2132
2133 int numseq=0;
2134 List<Chunk *> chlist;
2135 sc->lookup_child("ANIMSEQU",chlist);
2136
2137 LIF<Chunk*> chlif(&chlist);
2138 for(;!chlif.done();chlif.next())
2139 {
2140 Anim_Shape_Sequence_Chunk* assc=(Anim_Shape_Sequence_Chunk*)chlif();
2141 numseq=max(assc->sequence_data.SequenceNum+1,numseq);
2142 }
2143
2144 shapeanimationheader* sah=(shapeanimationheader*)PoolAllocateMem(sizeof(shapeanimationheader));
2145 shp->animation_header=sah;
2146 sah->num_sequences=numseq;
2147 sah->anim_sequences=(shapeanimationsequence*)PoolAllocateMem(sizeof(shapeanimationsequence)*numseq);
2148 sah->num_shapes_using_this=1;
2149 //sah->vertices_store = shp->points[0];
2150 //sah->item_normals_store = shp->sh_normals[0];
2151 //sah->vertex_normals_store = shp->sh_vnormals[0];
2152
2153 for( int i=0;i<numseq;i++)
2154 {
2155 sah->anim_sequences[i].num_frames=0;
2156 sah->anim_sequences[i].anim_frames=0;
2157 }
2158
2159
2160
2161 for(chlif.restart();!chlif.done();chlif.next())
2162 {
2163 Anim_Shape_Sequence_Chunk* assc=(Anim_Shape_Sequence_Chunk*)chlif();
2164 assc->GenerateInterpolatedFrames();
2165 const ChunkAnimSequence * cas=& assc->sequence_data;
2166 if(!cas->NumFrames)continue;
2167 shapeanimationsequence* sas =&sah->anim_sequences[cas->SequenceNum];
2168
2169 sas->max_x=(int)((cas->max.x-Centre.x)*local_scale);
2170 sas->min_x=(int)((cas->min.x-Centre.x)*local_scale);
2171 sas->max_y=(int)((cas->max.y-Centre.y)*local_scale);
2172 sas->min_y=(int)((cas->min.y-Centre.y)*local_scale);
2173 sas->max_z=(int)((cas->max.z-Centre.z)*local_scale);
2174 sas->min_z=(int)((cas->min.z-Centre.z)*local_scale);
2175
2176 int x=max(-sas->min_x,sas->max_x);
2177 int y=max(-sas->min_y,sas->max_y);
2178 int z=max(-sas->min_z,sas->max_z);
2179 sas->radius=(int)sqrt((double)(x*x+y*y+z*z));
2180
2181
2182 sas->vertex_normals=(int*)PoolAllocateMem(sizeof(VECTORCH)*cas->num_verts);
2183 for(int i=0;i<cas->num_verts;i++)
2184 {
2185 sas->vertex_normals[i*3]=(int)(cas->v_normal_list[i].x*ONE_FIXED);
2186 sas->vertex_normals[i*3+1]=(int)(cas->v_normal_list[i].y*ONE_FIXED);
2187 sas->vertex_normals[i*3+2]=(int)(cas->v_normal_list[i].z*ONE_FIXED);
2188 }
2189
2190 sas->num_frames=cas->NumFrames;
2191 sas->anim_frames=(shapeanimationframe*)PoolAllocateMem(sizeof(shapeanimationframe)*cas->NumFrames);
2192
2193 for(int i=0;i<cas->NumFrames;i++)
2194 {
2195 const ChunkAnimFrame* caf=cas->Frames[i];
2196 shapeanimationframe* saf=&sas->anim_frames[i];
2197
2198 saf->vertices=(int*)PoolAllocateMem(sizeof(VECTORCH)*caf->num_verts);
2199 for(int j=0;j<caf->num_verts;j++)
2200 {
2201 saf->vertices[j*3]=(int)((caf->v_list[j].x-Centre.x)*local_scale);
2202 saf->vertices[j*3+1]=(int)((caf->v_list[j].y-Centre.y)*local_scale);
2203 saf->vertices[j*3+2]=(int)((caf->v_list[j].z-Centre.z)*local_scale);
2204 }
2205
2206 saf->item_normals=(int*) PoolAllocateMem(sizeof(VECTORCH)*shp->numitems);
2207 for(int j=0;j<caf->num_polys;j++)
2208 {
2209 saf->item_normals[PolyConv[j]*3]=(int)(caf->p_normal_list[j].x*ONE_FIXED);
2210 saf->item_normals[PolyConv[j]*3+1]=(int)(caf->p_normal_list[j].y*ONE_FIXED);
2211 saf->item_normals[PolyConv[j]*3+2]=(int)(caf->p_normal_list[j].z*ONE_FIXED);
2212
2213 }
2214 }
2215 }
2216
2217 delete [] PolyConv;
2218
2219
2220 //find a sequence which has some frames;
2221 shapeanimationsequence* sas=0;
2222 int i;
2223
2224 for(i=0;i<shp->animation_header->num_sequences;i++)
2225 {
2226 sas=&shp->animation_header->anim_sequences[i];
2227 if(sas->num_frames)
2228 break;
2229
2230 }
2231 GLOBALASSERT(i<shp->animation_header->num_sequences);
2232
2233 //copy the pointers for the first frame of this sequence
2234 #if !USE_LEVEL_MEMORY_POOL
2235 DeallocateMem(shp->points[0]);
2236 DeallocateMem(shp->sh_normals[0]);
2237 DeallocateMem(shp->sh_vnormals[0]);
2238 #endif
2239
2240 shp->points[0]=sas->anim_frames[0].vertices;
2241 shp->sh_normals[0]=sas->anim_frames[0].item_normals;
2242 shp->sh_vnormals[0]=sas->vertex_normals;
2243 }
2244
2245
copy_to_shapeheader(RIFFHANDLE h,ChunkShape const & cshp,SHAPEHEADER * & shphd,Chunk_With_Children * shape,int flags,int local_max_index,int * local_tex_index_nos,int,const ChunkObject * object)2246 BOOL copy_to_shapeheader (
2247 RIFFHANDLE h,
2248 ChunkShape const & cshp,
2249 SHAPEHEADER *& shphd,
2250 Chunk_With_Children * shape,
2251 int flags,
2252 int local_max_index,
2253 int * local_tex_index_nos,
2254 int /*listpos*/,
2255 const ChunkObject* object
2256 )
2257 {
2258 ChunkShape merged_cshp;
2259 const ChunkShape* cshp_ptr;
2260
2261 if(shape->lookup_single_child("SHPMRGDT"))
2262 {
2263 merged_cshp=cshp;
2264 pre_process_shape(h,merged_cshp,shape,flags);
2265
2266 cshp_ptr=&merged_cshp;
2267 }
2268 else
2269 {
2270 cshp_ptr=&cshp;
2271 }
2272
2273 shphd = (SHAPEHEADER *) PoolAllocateMem(sizeof(SHAPEHEADER));
2274 memset(shphd,0,sizeof(SHAPEHEADER));
2275
2276 int i,j;
2277 int * tptr;
2278
2279 // header data (note shapeheader is calloced)
2280
2281 shphd->numpoints = cshp_ptr->num_verts;
2282 shphd->numitems = cshp_ptr->num_polys;
2283
2284
2285 shphd->shaperadius = (int) (cshp_ptr->radius*local_scale);
2286
2287 shphd->shapemaxx = (int) (cshp_ptr->max.x*local_scale);
2288 shphd->shapeminx = (int) (cshp_ptr->min.x*local_scale);
2289 shphd->shapemaxy = (int) (cshp_ptr->max.y*local_scale);
2290 shphd->shapeminy = (int) (cshp_ptr->min.y*local_scale);
2291 shphd->shapemaxz = (int) (cshp_ptr->max.z*local_scale);
2292 shphd->shapeminz = (int) (cshp_ptr->min.z*local_scale);
2293
2294 // AllocateMem arrays
2295
2296 shphd->points = (int **) PoolAllocateMem (sizeof(int *));
2297 *(shphd->points) = (int *) PoolAllocateMem (sizeof(int) * shphd->numpoints * 3);
2298
2299 shphd->sh_vnormals = (int **) PoolAllocateMem (sizeof(int *));
2300 *(shphd->sh_vnormals) = (int *) PoolAllocateMem (sizeof(int) * shphd->numpoints * 3);
2301
2302 shphd->sh_normals = (int **) PoolAllocateMem (sizeof(int *));
2303 *(shphd->sh_normals) = (int *) PoolAllocateMem (sizeof(int) * shphd->numitems * 3);
2304
2305 // for textures
2306 if (cshp_ptr->num_uvs)
2307 shphd->sh_textures = (int **) PoolAllocateMem (sizeof(int *) * cshp_ptr->num_uvs);
2308 if (cshp_ptr->num_texfiles)
2309 shphd->sh_localtextures = (char **) PoolAllocateMem (sizeof(char *) * (cshp_ptr->num_texfiles+1));
2310
2311 int * item_list;
2312
2313 shphd->items = (int **) PoolAllocateMem (sizeof(int *) * shphd->numitems);
2314 item_list = (int *) PoolAllocateMem (sizeof(int) * shphd->numitems * 9);
2315
2316 tptr = *(shphd->points);
2317
2318
2319
2320 if(object && local_scale!=1)
2321 {
2322 //convert from floating point to integers using world coordinates in an attempt to stop
2323 //tears from being generated
2324 ChunkVector object_float;
2325 object_float.x=(double)object->location.x;
2326 object_float.y=(double)object->location.y;
2327 object_float.z=(double)object->location.z;
2328
2329 VECTORCH object_int;
2330 object_int.vx=(int)(object_float.x*local_scale);
2331 object_int.vy=(int)(object_float.y*local_scale);
2332 object_int.vz=(int)(object_float.z*local_scale);
2333
2334 for (i=0; i<shphd->numpoints; i++) {
2335 tptr[i*3] = (int) ((cshp_ptr->v_list[i].x+object_float.x)*local_scale);
2336 tptr[i*3 + 1] = (int) ((cshp_ptr->v_list[i].y+object_float.y)*local_scale);
2337 tptr[i*3 + 2] = (int) ((cshp_ptr->v_list[i].z+object_float.z)*local_scale);
2338
2339 tptr[i*3]-=object_int.vx;
2340 tptr[i*3+1]-=object_int.vy;
2341 tptr[i*3+2]-=object_int.vz;
2342 }
2343
2344 }
2345 else
2346 {
2347 for (i=0; i<shphd->numpoints; i++) {
2348 tptr[i*3] = (int) (cshp_ptr->v_list[i].x*local_scale);
2349 tptr[i*3 + 1] = (int) (cshp_ptr->v_list[i].y*local_scale);
2350 tptr[i*3 + 2] = (int) (cshp_ptr->v_list[i].z*local_scale);
2351 }
2352 }
2353
2354 tptr = *(shphd->sh_vnormals);
2355
2356 for (i=0; i<shphd->numpoints; i++) {
2357 tptr[i*3] =(int) (cshp_ptr->v_normal_list[i].x*ONE_FIXED);
2358 tptr[i*3 + 1] =(int) (cshp_ptr->v_normal_list[i].y*ONE_FIXED);
2359 tptr[i*3 + 2] =(int) (cshp_ptr->v_normal_list[i].z*ONE_FIXED);
2360 }
2361
2362 tptr = *(shphd->sh_normals);
2363
2364 for (i=0; i<shphd->numitems; i++) {
2365 tptr[i*3] =(int) (cshp_ptr->p_normal_list[i].x*ONE_FIXED);
2366 tptr[i*3 + 1] =(int) (cshp_ptr->p_normal_list[i].y*ONE_FIXED);
2367 tptr[i*3 + 2] =(int) (cshp_ptr->p_normal_list[i].z*ONE_FIXED);
2368 }
2369
2370
2371 for (i=0; i<shphd->numitems; i++)
2372 shphd->items[i] = &item_list[i*9];
2373
2374 int * uv_imnums = 0;
2375 if (cshp_ptr->num_uvs)
2376 {
2377 uv_imnums = new int[cshp_ptr->num_uvs];
2378 for (i=0; i<cshp_ptr->num_uvs; ++i)
2379 {
2380 uv_imnums[i]=-1;
2381 shphd->sh_textures[i]=0;
2382 }
2383 }
2384
2385 for (i=0; i<shphd->numitems; i++) {
2386
2387 item_list[i*9] = (cshp_ptr->poly_list[i].engine_type);
2388 item_list[i*9 + 1] = (cshp_ptr->poly_list[i].normal_index * 3);
2389 item_list[i*9 + 2] = (cshp_ptr->poly_list[i].flags&~ChunkInternalItemFlags);
2390 item_list[i*9 + 3] = (cshp_ptr->poly_list[i].colour);
2391
2392 if ( is_textured(item_list[i*9]) && !( item_list[i*9 + 3] & 0x8000 ) )
2393 {
2394 int texno = item_list[i*9 + 3] & 0x7fff;
2395 int UVIndex= item_list[i*9 + 3]>>16;
2396
2397 if (texno <= local_max_index &&
2398 local_tex_index_nos[texno] != -1 &&
2399 cshp_ptr->uv_list[UVIndex].num_verts)
2400
2401 {
2402 item_list[i*9 + 3] &= 0xffff0000;
2403 uv_imnums[item_list[i*9+3]>>16]=local_tex_index_nos[texno];
2404 item_list[i*9 + 3] += local_tex_index_nos[texno];
2405
2406 shphd->sh_textures[UVIndex] = (int *) PoolAllocateMem (sizeof(int *) * cshp_ptr->uv_list[UVIndex].num_verts * 2);
2407 for (j=0; j<cshp_ptr->uv_list[UVIndex].num_verts; j++) {
2408 (shphd->sh_textures[UVIndex])[(j*2)] = ProcessUVCoord(h,UVC_POLY_U,(int)cshp_ptr->uv_list[UVIndex].vert[j].u,uv_imnums[UVIndex]);
2409 (shphd->sh_textures[UVIndex])[(j*2)+1] = ProcessUVCoord(h,UVC_POLY_V,(int)cshp_ptr->uv_list[UVIndex].vert[j].v,uv_imnums[UVIndex]);
2410 }
2411
2412
2413 }
2414 else
2415 {
2416 item_list[i*9] = I_Polyline;
2417 item_list[i*9 + 2] = (cshp_ptr->poly_list[i].flags&~ChunkInternalItemFlags) | iflag_nolight;
2418 item_list[i*9 + 3] = 0xffffffff;
2419 }
2420 }
2421
2422
2423 for (j=0;j<cshp_ptr->poly_list[i].num_verts;j++)
2424 // item_list[i*9 + 4 +j] = (cshp_ptr->poly_list[i].vert_ind[j] *3);
2425 /* KJL 12:21:58 9/17/97 - I've removed the annoying *3 */
2426 item_list[i*9 + 4 +j] = (cshp_ptr->poly_list[i].vert_ind[j]);
2427 for (;j<5;j++)
2428 item_list[i*9 + 4 +j] = -1;
2429 }
2430
2431 if (uv_imnums) delete[] uv_imnums;
2432
2433 if (cshp_ptr->num_texfiles)
2434 {
2435 for (i=0; i<cshp_ptr->num_texfiles; i++) {
2436 #if john
2437 shphd->sh_localtextures[i] =
2438 (char *) PoolAllocateMem (sizeof(char) * (strlen(cshp_ptr->texture_fns[i]) + strlen(TexturesRoot) + 1) );
2439 sprintf (shphd->sh_localtextures[i],"%s%s",TexturesRoot, cshp_ptr->texture_fns[i]);
2440 char * dotpos;
2441 dotpos = strrchr (shphd->sh_localtextures[i], '.');
2442 sprintf (dotpos,".pg0");
2443 #else
2444 shphd->sh_localtextures[i] =
2445 (char *) PoolAllocateMem (sizeof(char) * (strlen(cshp_ptr->texture_fns[i]) + 1) );
2446 strcpy (shphd->sh_localtextures[i], cshp_ptr->texture_fns[i]);
2447 #endif
2448 }
2449 shphd->sh_localtextures[i] = 0;
2450 }
2451
2452
2453
2454
2455 SHAPEINSTR * instruct = (SHAPEINSTR *)PoolAllocateMem(sizeof(SHAPEINSTR)*6);
2456
2457 shphd->sh_instruction = instruct;
2458
2459
2460 instruct[0].sh_instr = I_ShapePoints; /*I_shapepoints*/
2461 instruct[0].sh_numitems = shphd->numpoints;
2462 instruct[0].sh_instr_data = shphd->points;
2463
2464 instruct[1].sh_instr = I_ShapeNormals; /*I_shapenormals*/
2465 instruct[1].sh_numitems = shphd->numitems;
2466 instruct[1].sh_instr_data = shphd->sh_normals;
2467
2468 instruct[2].sh_instr = I_ShapeProject; /*I_shapeproject*/
2469 instruct[2].sh_numitems = shphd->numpoints;
2470 instruct[2].sh_instr_data = shphd->points;
2471
2472 instruct[3].sh_instr = I_ShapeVNormals; /*I_shapevnormals*/
2473 instruct[3].sh_numitems = shphd->numpoints;
2474 instruct[3].sh_instr_data = shphd->sh_vnormals;
2475
2476 instruct[4].sh_instr = I_ShapeItems;
2477 instruct[4].sh_numitems = shphd->numitems;
2478 instruct[4].sh_instr_data = shphd->items;
2479
2480 instruct[5].sh_instr = I_ShapeEnd; /*I_shapeEND*/
2481 instruct[5].sh_numitems = 0;
2482 instruct[5].sh_instr_data = 0;
2483
2484
2485 Chunk * pchAnim = shape->lookup_single_child("TEXTANIM");
2486 if(pchAnim)
2487 {
2488 Animation_Chunk* ac=(Animation_Chunk*)pchAnim;
2489 Shape_Merge_Data_Chunk* smdc=0;
2490 Chunk * pCh = shape->lookup_single_child("SHPMRGDT");
2491 if(pCh) smdc=(Shape_Merge_Data_Chunk*)pCh;
2492 SetupAnimatedTextures((Shape_Chunk*)shape,shphd,ac,smdc, local_tex_index_nos);
2493 }
2494
2495 if(shape->count_children("ANIMSEQU"))
2496 {
2497 Shape_Merge_Data_Chunk* smdc=0;
2498 Chunk * pCh=shape->lookup_single_child("SHPMRGDT");
2499 if(pCh) smdc=(Shape_Merge_Data_Chunk*)pCh;
2500 SetupAnimatingShape((Shape_Chunk*)shape,shphd,smdc);
2501 }
2502
2503 return TRUE;
2504
2505
2506 }
copy_preprocessed_to_shapeheader(RIFFHANDLE h,Shape_Preprocessed_Data_Chunk * spdc,SHAPEHEADER * & shphd,Chunk_With_Children * shape,int,int local_max_index,int * local_tex_index_nos,int,const ChunkObject * object)2507 BOOL copy_preprocessed_to_shapeheader (
2508 RIFFHANDLE h,
2509 Shape_Preprocessed_Data_Chunk* spdc,
2510 SHAPEHEADER *& shphd,
2511 Chunk_With_Children * shape,
2512 int /*flags*/,
2513 int local_max_index,
2514 int * local_tex_index_nos,
2515 int /*listpos*/,
2516 const ChunkObject* object
2517 )
2518 {
2519 shphd = (SHAPEHEADER*)spdc->GetMemoryBlock();
2520
2521 for (int i=0; i<shphd->numitems; i++)
2522 {
2523 if(is_textured(shphd->items[i][0]))
2524 {
2525 int texno = shphd->items[i][3] & 0x7fff;
2526 if (texno <= local_max_index &&
2527 local_tex_index_nos[texno] != -1)
2528
2529 {
2530 shphd->items[i][3] &= 0xffff0000;
2531 shphd->items[i][3] += local_tex_index_nos[texno];
2532
2533
2534 }
2535 else
2536 {
2537 shphd->items[i][0] = I_Polyline;
2538 shphd->items[i][2] |=iflag_nolight;
2539 shphd->items[i][3] = 0xffffffff;
2540 }
2541 }
2542 }
2543
2544
2545 return TRUE;
2546
2547
2548 }
2549
copy_sprite_to_shapeheader(RIFFHANDLE h,SHAPEHEADER * & shphd,Sprite_Header_Chunk * shc,int listpos)2550 BOOL copy_sprite_to_shapeheader (RIFFHANDLE h, SHAPEHEADER *& shphd,Sprite_Header_Chunk* shc, int listpos)
2551 {
2552 Chunk * pChunk=shc->lookup_single_child("SPRITEPC");
2553 if(!pChunk)
2554 {
2555 return 0;
2556 }
2557 PC_Sprite_Chunk* sc=(PC_Sprite_Chunk*)pChunk;
2558
2559 pChunk = shc->lookup_single_child("SPRISIZE");
2560 if(!pChunk)
2561 {
2562 return 0;
2563 }
2564 Sprite_Size_Chunk* ssc=(Sprite_Size_Chunk*)pChunk;
2565
2566 Sprite_Extent_Chunk* sec=0;
2567 pChunk=shc->lookup_single_child("SPREXTEN");
2568 if(pChunk)
2569 sec=(Sprite_Extent_Chunk*)pChunk;
2570
2571 pChunk=shc->lookup_single_child("SPRBMPSC");
2572 if(!pChunk)
2573 {
2574 return 0;
2575 }
2576 Sprite_Bitmap_Scale_Chunk* sbsc=(Sprite_Bitmap_Scale_Chunk*)pChunk;
2577
2578 shphd = (SHAPEHEADER *) PoolAllocateMem(sizeof(SHAPEHEADER));
2579 memset(shphd,0,sizeof(SHAPEHEADER));
2580
2581 int i;
2582 int * tptr;
2583 int * BmpConv=0;
2584 int local_max_index;
2585 String sprite_name;
2586
2587
2588
2589 Bitmap_List_Store_Chunk * blsc = 0;
2590
2591
2592 pChunk = shc->lookup_single_child("BMPLSTST");
2593 if (pChunk)
2594 {
2595 blsc = (Bitmap_List_Store_Chunk *) pChunk;
2596 }
2597 pChunk = shc->lookup_single_child("RIFFNAME");
2598 if (pChunk)
2599 {
2600 sprite_name = ((RIF_Name_Chunk *)pChunk)->rif_name;
2601 msl_shapes.add_entry(new ShapeInMSL(shphd,sprite_name,listpos));
2602 }
2603
2604 if (blsc)
2605 {
2606 // load in the textures from the shape
2607
2608 local_max_index = 0;
2609 LIF<BMP_Name> bns (&blsc->bmps);
2610 for (; !bns.done(); bns.next())
2611 {
2612 local_max_index = max(bns().index,local_max_index);
2613 }
2614
2615 BmpConv = new int [local_max_index+1];
2616 for (i=0; i<=local_max_index; i++)
2617 {
2618 BmpConv[i] = -1;
2619 }
2620
2621 if (Env_Chunk == 0)
2622 Env_Chunk = h->fc;
2623 // JH 17-2-97 -- image loaders have changed to avoid loading the same image twice
2624 for (bns.restart() ; !bns.done(); bns.next())
2625 {
2626 if(bns().flags & ChunkBMPFlag_NotInPC) continue;
2627
2628 String tex;
2629 if (bns().flags & ChunkBMPFlag_IFF)
2630 {
2631 tex = bns().filename;
2632 }
2633 else
2634 {
2635 tex = sprite_name;
2636 tex += "\\";
2637 tex += bns().filename;
2638 }
2639
2640 int imgnum = load_rif_bitmap(bns().filename,bns().flags);
2641 if (GEI_NOTLOADED != imgnum)
2642 BmpConv[bns().index] = imgnum;
2643 }
2644
2645 }
2646 // header data (note shapeheader is calloced)
2647
2648 shphd->numpoints = 4;
2649 shphd->numitems = 1;
2650
2651
2652 shphd->shaperadius =ssc->radius*GlobalScale;
2653
2654 if(sec)
2655 {
2656 shphd->shapemaxx =(int)(sec->maxx*GlobalScale);
2657 shphd->shapeminx =(int)(sec->minx*GlobalScale);
2658 shphd->shapemaxy =(int)(sec->maxy*GlobalScale);
2659 shphd->shapeminy =(int)(sec->miny*GlobalScale);
2660
2661 }
2662 else
2663 {
2664 shphd->shapemaxx =(int)(ssc->maxx*GlobalScale);
2665 shphd->shapeminx =(int)(-ssc->maxx*GlobalScale);
2666 shphd->shapemaxy =(int)(ssc->maxy*GlobalScale);
2667 shphd->shapeminy =(int)(-ssc->maxy*GlobalScale);
2668 }
2669 shphd->shapemaxz =501*GlobalScale;
2670 shphd->shapeminz =-501*GlobalScale;
2671
2672 // AllocateMem arrays
2673
2674 shphd->points = (int **) PoolAllocateMem (sizeof(int *));
2675 *(shphd->points) = (int *) PoolAllocateMem (sizeof(int) * shphd->numpoints * 3);
2676
2677 shphd->sh_vnormals = (int **) PoolAllocateMem (sizeof(int *));
2678 *(shphd->sh_vnormals) = (int *) PoolAllocateMem (sizeof(int) * shphd->numpoints * 3);
2679
2680 shphd->sh_normals = (int **) PoolAllocateMem (sizeof(int *));
2681 *(shphd->sh_normals) = (int *) PoolAllocateMem (sizeof(int) * shphd->numitems * 3);
2682
2683 shphd->sh_textures = (int **) PoolAllocateMem (sizeof(int *));
2684
2685 int * item_list;
2686
2687 shphd->items = (int **) PoolAllocateMem (sizeof(int *) * shphd->numitems);
2688 item_list = (int *) PoolAllocateMem (sizeof(int) * shphd->numitems * 9);
2689
2690 tptr = *(shphd->points);
2691
2692 tptr[0]=shphd->shapemaxx;
2693 tptr[1]=shphd->shapeminy;
2694 tptr[2]=0;
2695 tptr[3]=shphd->shapemaxx;
2696 tptr[4]=shphd->shapemaxy;
2697 tptr[5]=0;
2698 tptr[6]=shphd->shapeminx;
2699 tptr[7]=shphd->shapemaxy;
2700 tptr[8]=0;
2701 tptr[9]=shphd->shapeminx;
2702 tptr[10]=shphd->shapeminy;
2703 tptr[11]=0;
2704
2705 tptr = *(shphd->sh_vnormals);
2706
2707 for (i=0; i<shphd->numpoints; i++) {
2708 tptr[i*3] = 0;
2709 tptr[i*3 + 1] = 0;
2710 tptr[i*3 + 2] = ONE_FIXED;
2711 }
2712
2713 tptr = *(shphd->sh_normals);
2714
2715 for (i=0; i<shphd->numitems; i++) {
2716 tptr[i*3] = 0;
2717 tptr[i*3 + 1] = 0;
2718 tptr[i*3 + 2] = ONE_FIXED;
2719 }
2720
2721
2722 for (i=0; i<shphd->numitems; i++)
2723 shphd->items[i] = &item_list[i*9];
2724
2725
2726 item_list[0]=I_2dTexturedPolygon;
2727 item_list[1]=0;
2728 item_list[2]=iflag_ignore0| iflag_txanim|iflag_no_bfc;
2729 if(ssc->Flags & SpriteFlag_NoLight) item_list[2]|=iflag_nolight;
2730 if(ssc->Flags & SpriteFlag_SemiTrans) item_list[2]|=iflag_transparent;
2731 item_list[3]=0;
2732 item_list[4]=0;
2733 item_list[5]=1;
2734 item_list[6]=2;
2735 item_list[7]=3;
2736 item_list[8]=-1;
2737
2738 SHAPEINSTR * instruct = (SHAPEINSTR *)PoolAllocateMem(sizeof(SHAPEINSTR)*6);
2739
2740 shphd->sh_instruction = instruct;
2741
2742 instruct[0].sh_instr = I_ShapeSpriteRPoints; /*I_shapepoints*/
2743 instruct[0].sh_numitems = 4;
2744 instruct[0].sh_instr_data = shphd->points;
2745
2746 instruct[1].sh_instr = I_ShapeNormals; /*I_shapenormals*/
2747 instruct[1].sh_numitems = shphd->numitems;
2748 instruct[1].sh_instr_data = shphd->sh_normals;
2749
2750 instruct[2].sh_instr = I_ShapeProject; /*I_shapeproject*/
2751 instruct[2].sh_numitems = shphd->numpoints;
2752 instruct[2].sh_instr_data = shphd->points;
2753
2754 instruct[3].sh_instr = I_ShapeVNormals; /*I_shapevnormals*/
2755 instruct[3].sh_numitems = shphd->numpoints;
2756 instruct[3].sh_instr_data = shphd->sh_vnormals;
2757
2758 instruct[4].sh_instr = I_ShapeItems;
2759 instruct[4].sh_numitems = shphd->numitems;
2760 instruct[4].sh_instr_data = shphd->items;
2761
2762 instruct[5].sh_instr = I_ShapeEnd; /*I_shapeEND*/
2763 instruct[5].sh_numitems = 0;
2764 instruct[5].sh_instr_data = 0;
2765
2766 shphd->shapeflags=ShapeFlag_MultiViewSprite|ShapeFlag_SpriteResizing|ShapeFlag_Sprite;
2767
2768 List<Chunk *> chlist;
2769 sc->lookup_child("SPRACTIO",chlist);
2770
2771 int MaxSeq=0;
2772 for(LIF<Chunk*>chlif(&chlist);!chlif.done();chlif.next())
2773 {
2774 MaxSeq=max(MaxSeq,((Sprite_Action_Chunk*)chlif())->Action);
2775 }
2776 txanimheader** thlist=(txanimheader**)PoolAllocateMem((3+MaxSeq)*sizeof(txanimheader));
2777 thlist[0]=thlist[MaxSeq+2]=0;
2778 for(i=1;i<MaxSeq+2;i++)
2779 {
2780 thlist[i]=(txanimheader*)PoolAllocateMem(sizeof(txanimheader));
2781 thlist[i]->txa_numframes=0;
2782 thlist[i]->txa_maxframe=0;
2783 thlist[i]->txa_num_mvs_images=0;
2784 thlist[i]->txa_framedata=0;
2785 }
2786 while(chlist.size())
2787 {
2788 Sprite_Action_Chunk* sac=(Sprite_Action_Chunk*) chlist.first_entry();
2789 txanimheader* th=thlist[sac->Action+1];
2790
2791 th->txa_flags=txa_flag_play;
2792 th->txa_numframes=sac->NumFrames+1;
2793 th->txa_currentframe=0;
2794 th->txa_state=0;
2795 th->txa_maxframe=(th->txa_numframes-1)<<16;
2796 if(sac->FrameTime)
2797 th->txa_speed=65536000/sac->FrameTime;
2798 else
2799 th->txa_speed=65536*8;
2800
2801 th->txa_num_mvs_images=sac->NumYaw*sac->NumPitch*2;
2802
2803 th->txa_eulerxshift=12;
2804 int j=sac->NumPitch;
2805 while(j)
2806 {
2807 j=j>>1;
2808 th->txa_eulerxshift--;
2809 }
2810 th->txa_euleryshift=12;
2811 j=sac->NumYaw;
2812 while(j)
2813 {
2814 j=j>>1;
2815 th->txa_euleryshift--;
2816 }
2817 if(sac->NumYaw==1)
2818 {
2819 th->txa_euleryshift=12;
2820 th->txa_num_mvs_images=sac->NumPitch;
2821 }
2822
2823 th->txa_framedata=(txanimframe*)PoolAllocateMem(th->txa_numframes*sizeof(txanimframe_mvs));
2824
2825 txanimframe_mvs* tf;
2826 for(j=0;j<th->txa_numframes;j++)
2827 {
2828 int framefrom=j;
2829 if(j==sac->NumFrames) framefrom=0;
2830 tf=(txanimframe_mvs*)&th->txa_framedata[j];
2831 tf->txf_flags=0;
2832 tf->txf_scale=ONE_FIXED;
2833 tf->txf_scalex=0;
2834 tf->txf_scaley=0;
2835 tf->txf_orient=0;
2836 tf->txf_orientx=0;
2837 tf->txf_orienty=0;
2838 tf->txf_numuvs=4;
2839
2840 tf->txf_uvdata=(int**)PoolAllocateMem((th->txa_num_mvs_images)*sizeof(int*));
2841 int* uvdata=(int*)PoolAllocateMem(th->txa_num_mvs_images*16*sizeof(int));
2842 for(int k=0;k<th->txa_num_mvs_images;k++)
2843 {
2844 tf->txf_uvdata[k]=&uvdata[16*k];
2845 }
2846
2847 tf->txf_images=(int*)PoolAllocateMem(th->txa_num_mvs_images*sizeof(int));
2848 int ny=2*sac->NumYaw;
2849 if(sac->NumYaw==1) ny=1;
2850 int y,y2;
2851 int pos,pos2;
2852 for(y=0;y<ny;y+=2)
2853 {
2854 for(int p=0;p<sac->NumPitch;p++)
2855 {
2856 y2=(y-1+ny)%ny;
2857 pos=y*sac->NumPitch+p;
2858 pos2=y2*sac->NumPitch+p;
2859 Frame* f=&sac->FrameList[y/2][p][framefrom];
2860
2861 GLOBALASSERT(f->Texture<=local_max_index);
2862 GLOBALASSERT(f->Texture>=0);
2863 GLOBALASSERT(BmpConv[f->Texture]!=-1);
2864
2865 tf->txf_images[pos]=BmpConv[f->Texture];
2866 tf->txf_images[pos2]=BmpConv[f->Texture];
2867
2868 float bmpscale=sbsc->Scale[f->Texture];
2869 if(y>ny/2 && (sac->Flags & SpriteActionFlag_FlipSecondSide))
2870 {
2871 for(int l=0;l<4;l++)
2872 {
2873 tf->txf_uvdata[pos][l*2]=ProcessUVCoord(h,UVC_SPRITE_U,f->UVCoords[3-l][0]<<16,BmpConv[f->Texture]);
2874 tf->txf_uvdata[pos][l*2+1]=ProcessUVCoord(h,UVC_SPRITE_V,f->UVCoords[3-l][1]<<16,BmpConv[f->Texture]);
2875 tf->txf_uvdata[pos2][l*2]=ProcessUVCoord(h,UVC_SPRITE_U,f->UVCoords[3-l][0]<<16,BmpConv[f->Texture]);
2876 tf->txf_uvdata[pos2][l*2+1]=ProcessUVCoord(h,UVC_SPRITE_V,f->UVCoords[3-l][1]<<16,BmpConv[f->Texture]);
2877
2878
2879 tf->txf_uvdata[pos][l*2+8]=(int)(-(f->UVCoords[3-l][0]-f->CentreX)*bmpscale*GlobalScale);
2880 tf->txf_uvdata[pos][l*2+9]=(int)((f->UVCoords[3-l][1]-f->CentreY)*bmpscale*GlobalScale);
2881 tf->txf_uvdata[pos2][l*2+8]=(int)(-(f->UVCoords[3-l][0]-f->CentreX)*bmpscale*GlobalScale);
2882 tf->txf_uvdata[pos2][l*2+9]=(int)((f->UVCoords[3-l][1]-f->CentreY)*bmpscale*GlobalScale);
2883
2884 }
2885 }
2886 else
2887 {
2888 for(int l=0;l<4;l++)
2889 {
2890 tf->txf_uvdata[pos][l*2]=ProcessUVCoord(h,UVC_SPRITE_U,f->UVCoords[l][0]<<16,BmpConv[f->Texture]);
2891 tf->txf_uvdata[pos][l*2+1]=ProcessUVCoord(h,UVC_SPRITE_V,f->UVCoords[l][1]<<16,BmpConv[f->Texture]);
2892 tf->txf_uvdata[pos2][l*2]=ProcessUVCoord(h,UVC_SPRITE_U,f->UVCoords[l][0]<<16,BmpConv[f->Texture]);
2893 tf->txf_uvdata[pos2][l*2+1]=ProcessUVCoord(h,UVC_SPRITE_V,f->UVCoords[l][1]<<16,BmpConv[f->Texture]);
2894
2895
2896 tf->txf_uvdata[pos][l*2+8]=(int)((f->UVCoords[l][0]-f->CentreX)*bmpscale*GlobalScale);
2897 tf->txf_uvdata[pos][l*2+9]=(int)((f->UVCoords[l][1]-f->CentreY)*bmpscale*GlobalScale);
2898 tf->txf_uvdata[pos2][l*2+8]=(int)((f->UVCoords[l][0]-f->CentreX)*bmpscale*GlobalScale);
2899 tf->txf_uvdata[pos2][l*2+9]=(int)((f->UVCoords[l][1]-f->CentreY)*bmpscale*GlobalScale);
2900
2901 }
2902 }
2903 }
2904 }
2905 }
2906
2907 chlist.delete_first_entry();
2908 }
2909 shphd->sh_textures[0]=(int*)thlist;
2910 delete [] BmpConv;
2911 return TRUE;
2912 }
2913
2914
2915
copy_to_map6(Object_Chunk * ob,MAPBLOCK6 * mapblock,int shplst_pos)2916 BOOL copy_to_map6(Object_Chunk * ob,MAPBLOCK6* mapblock, int shplst_pos)
2917 {
2918
2919 Object_Project_Data_Chunk * opdc = 0;
2920 Map_Block_Chunk * mapblok = 0;
2921 Strategy_Chunk * strat = 0;
2922
2923 if (ob->object_data.is_base_object)
2924 *mapblock = Empty_Landscape_Type6;
2925 else *mapblock = Empty_Object_Type6;
2926
2927
2928
2929 Chunk * pChunk = ob->lookup_single_child("OBJPRJDT");
2930 if (pChunk) opdc = (Object_Project_Data_Chunk *)pChunk;
2931 if (opdc)
2932 {
2933 pChunk = opdc->lookup_single_child("MAPBLOCK");
2934 if (pChunk) mapblok = (Map_Block_Chunk *)pChunk;
2935 pChunk = opdc->lookup_single_child("STRATEGY");
2936 if (pChunk) strat = (Strategy_Chunk *)pChunk;
2937 }
2938
2939 if (mapblok)
2940 {
2941 mapblock->MapType = mapblok->map_data.MapType;
2942 mapblock->MapFlags= mapblok->map_data.MapFlags;
2943
2944 #if (StandardStrategyAndCollisions || IntermediateSSACM)
2945 mapblock->MapCType = mapblok->map_data.MapCType;
2946 mapblock->MapCGameType = mapblok->map_data.MapCGameType;
2947 mapblock->MapCStrategyS = mapblok->map_data.MapCStrategyS;
2948 mapblock->MapCStrategyL = mapblok->map_data.MapCStrategyL;
2949 #endif
2950
2951 mapblock->MapInteriorType = mapblok->map_data.MapInteriorType;
2952 // mapblock->MapLightType = mapblok->map_data.MapLightType;
2953 // mapblock->MapMass = mapblok->map_data.MapMass;
2954 // mapblock->MapNewtonV.vx = mapblok->map_data.MapNewtonV.vx;
2955 // mapblock->MapNewtonV.vy = mapblok->map_data.MapNewtonV.vy;
2956 // mapblock->MapNewtonV.vz = mapblok->map_data.MapNewtonV.vz;
2957 // mapblock->MapOrigin.vx = mapblok->map_data.MapOrigin.vx;
2958 // mapblock->MapOrigin.vy = mapblok->map_data.MapOrigin.vy;
2959 // mapblock->MapOrigin.vz = mapblok->map_data.MapOrigin.vz;
2960 // mapblock->MapViewType = mapblok->map_data.MapViewType;
2961 }
2962
2963 #if (StandardStrategyAndCollisions || IntermediateSSACM)
2964 if (strat)
2965 {
2966 mapblock->MapStrategy = strat->strategy_data.Strategy;
2967 }
2968 #endif
2969
2970 mapblock->MapShape = shplst_pos;
2971
2972 mapblock->MapWorld.vx = (int) (ob->object_data.location.x*local_scale);
2973 mapblock->MapWorld.vy = (int) (ob->object_data.location.y*local_scale);
2974 mapblock->MapWorld.vz = (int) (ob->object_data.location.z*local_scale);
2975
2976 QUAT q;
2977
2978 q.quatx = (int)(-ob->object_data.orientation.x*ONE_FIXED);
2979 q.quaty = (int)(-ob->object_data.orientation.y*ONE_FIXED);
2980 q.quatz = (int)(-ob->object_data.orientation.z*ONE_FIXED);
2981 q.quatw = (int)(ob->object_data.orientation.w*ONE_FIXED);
2982
2983 MATRIXCH m;
2984
2985 QuatToMat (&q, &m);
2986
2987 EULER e;
2988
2989 MatrixToEuler(&m, &e);
2990
2991 /*
2992 This function is only being used by the tools.
2993 At least for the moment I need the Euler to contain
2994 the 'inverse' rotation ,until I get round to sorting things
2995 out properly. Richard
2996 */
2997
2998 mapblock->MapEuler.EulerX = e.EulerX;
2999 mapblock->MapEuler.EulerY = e.EulerY;
3000 mapblock->MapEuler.EulerZ = e.EulerZ;
3001
3002 return TRUE;
3003 }
3004
3005
3006
3007
3008
tex_merge_polys(ChunkPoly & p1,ChunkPoly & p2,ChunkPoly & p,ChunkShape & shp,int *)3009 BOOL tex_merge_polys ( ChunkPoly & p1, ChunkPoly & p2, ChunkPoly & p, ChunkShape & shp, int * /*mgd*/)
3010 {
3011 int j;
3012
3013 if (p1.engine_type != p2.engine_type)
3014 return(FALSE);
3015
3016 if ((p1.colour & 0xffff) != (p2.colour & 0xffff))
3017 return(FALSE);
3018
3019 if (p1.flags != p2.flags)
3020 return(FALSE);
3021
3022
3023 int p1_uvind = p1.colour >> 16;
3024 int p2_uvind = p2.colour >> 16;
3025
3026 ChunkUV_List uv;
3027 p = p1;
3028 p.num_verts = 4;
3029 uv.num_verts = 4;
3030
3031 int num_ins = 0;
3032 int p_onv = 0;
3033 int new_p_onv;
3034 int * p_on = p1.vert_ind;
3035 int * p_oth = p2.vert_ind;
3036 int * temp;
3037
3038 ChunkUV * uv_on = shp.uv_list[p1_uvind].vert;
3039 ChunkUV * uv_oth = shp.uv_list[p2_uvind].vert;
3040 ChunkUV * uvtemp;
3041
3042 while (num_ins < 4)
3043 {
3044 uv.vert[num_ins] = uv_on[p_onv];
3045 p.vert_ind[num_ins++] = p_on[p_onv];
3046 for (j=0; j<3; j++)
3047 {
3048 if (p_on[p_onv] == p_oth[j] &&
3049 (uv_on[p_onv].u != uv_oth[j].u || uv_on[p_onv].v != uv_oth[j].v))
3050 {
3051 return(FALSE);
3052 }
3053 if (p_on[p_onv] == p_oth[j])
3054 break;
3055 }
3056 if (j==3) p_onv = (p_onv+1)%3;
3057 else
3058 {
3059 new_p_onv = j;
3060 for (j=0; j<3; j++)
3061 {
3062 if (p_on[(p_onv+1)%3] == p_oth[j] &&
3063 (uv_on[(p_onv+1)%3].u != uv_oth[j].u || uv_on[(p_onv+1)%3].v != uv_oth[j].v))
3064 {
3065 return (FALSE);
3066 }
3067 if (p_on[(p_onv+1)%3] == p_oth[j])
3068 break;
3069 }
3070 if (j==3) p_onv = (p_onv+1)%3;
3071 else
3072 {
3073 temp = p_on;
3074 p_on = p_oth;
3075 p_oth = temp;
3076 p_onv = (new_p_onv+1)%3;
3077
3078 uvtemp = uv_on;
3079 uv_on = uv_oth;
3080 uv_oth = uvtemp;
3081 }
3082 }
3083 }
3084
3085 shp.uv_list[p1_uvind] = uv;
3086
3087 return(TRUE);
3088
3089
3090 }
3091
merge_polys(ChunkPoly & p1,ChunkPoly & p2,ChunkPoly & p,int *)3092 BOOL merge_polys ( ChunkPoly & p1, ChunkPoly & p2, ChunkPoly & p, int * /*mgd*/)
3093 {
3094 int j;
3095
3096 if (p1.engine_type != p2.engine_type)
3097 return(FALSE);
3098
3099 if (p1.colour != p2.colour)
3100 return(FALSE);
3101
3102 if (p1.flags != p2.flags)
3103 return(FALSE);
3104
3105
3106 p = p1;
3107 p.num_verts = 4;
3108 int num_ins = 0;
3109 int p_onv = 0;
3110 int new_p_onv;
3111 int * p_on = p1.vert_ind;
3112 int * p_oth = p2.vert_ind;
3113 int * temp;
3114
3115 while (num_ins < 4)
3116 {
3117 p.vert_ind[num_ins++] = p_on[p_onv];
3118 for (j=0; j<3; j++)
3119 {
3120 if (p_on[p_onv] == p_oth[j])
3121 break;
3122 }
3123 if (j==3) p_onv = (p_onv+1)%3;
3124 else
3125 {
3126 new_p_onv = j;
3127 for (j=0; j<3; j++)
3128 {
3129 if (p_on[(p_onv+1)%3] == p_oth[j])
3130 break;
3131 }
3132 if (j==3) p_onv = (p_onv+1)%3;
3133 else
3134 {
3135 temp = p_on;
3136 p_on = p_oth;
3137 p_oth = temp;
3138 p_onv = (new_p_onv+1)%3;
3139 }
3140 }
3141 }
3142 return(TRUE);
3143 }
3144
3145
merge_polygons_in_chunkshape(ChunkShape & shp,Shape_Merge_Data_Chunk * smdc)3146 void merge_polygons_in_chunkshape (ChunkShape & shp, Shape_Merge_Data_Chunk * smdc)
3147 {
3148 int * mgd = smdc->merge_data;
3149
3150 int p_no = 0;
3151
3152
3153 ChunkPoly * new_polys = new ChunkPoly [shp.num_polys];
3154 ChunkVectorFloat * new_pnorms = new ChunkVectorFloat [shp.num_polys];
3155
3156 for (int i = 0; i<shp.num_polys; i++)
3157 {
3158 if (mgd[i] == -1)
3159 {
3160 new_polys[p_no] = shp.poly_list[i];
3161 new_polys[p_no].normal_index = p_no;
3162 new_pnorms[p_no] = shp.p_normal_list[i];
3163 p_no ++;
3164 }
3165 else if (mgd[i]>i)
3166 {
3167 ChunkPoly p;
3168
3169 BOOL merged = FALSE;
3170
3171 //make sure points are within 10mm of being planar
3172
3173 int mpoly=mgd[i];
3174 //find the 'unique vertex' in the second triangle
3175 int j, k;
3176 for(j=0;j<3;j++)
3177 {
3178 for(k=0;k<3;k++)
3179 {
3180 if(shp.poly_list[mpoly].vert_ind[j]==shp.poly_list[i].vert_ind[k])break;
3181 }
3182 if(k==3)
3183 {
3184 break;
3185 }
3186 }
3187 GLOBALASSERT(j!=3);
3188 int vert1=shp.poly_list[mpoly].vert_ind[j];
3189 int vert2=shp.poly_list[mpoly].vert_ind[(j+1)%3];
3190 ChunkVectorInt diff=shp.v_list[vert1]-shp.v_list[vert2];
3191 ChunkVectorFloat* norm=&shp.p_normal_list[i];
3192
3193 //take the dot product of the normal and the difference to find the distance form the first
3194 //triangles plane
3195 float distance= (float)diff.x*norm->x + (float)diff.y*norm->y + (float)diff.z*norm->z;
3196
3197 if(distance>-1 && distance <1)
3198 {
3199 if (is_textured(shp.poly_list[i].engine_type))
3200 {
3201 merged = tex_merge_polys ( shp.poly_list[i], shp.poly_list[mgd[i]], p, shp, mgd);
3202 }
3203 else
3204 {
3205 merged = merge_polys ( shp.poly_list[i], shp.poly_list[mgd[i]], p, mgd);
3206 }
3207 }
3208 if (merged)
3209 {
3210 p.normal_index = p_no;
3211 new_polys[p_no] = p;
3212 new_pnorms[p_no] = shp.p_normal_list[i];
3213 p_no++;
3214 }
3215 else
3216 {
3217 new_polys[p_no] = shp.poly_list[i];
3218 new_polys[p_no].normal_index = p_no;
3219 new_pnorms[p_no] = shp.p_normal_list[i];
3220 p_no ++;
3221
3222 new_polys[p_no] = shp.poly_list[mgd[i]];
3223 new_polys[p_no].normal_index = p_no;
3224 new_pnorms[p_no] = shp.p_normal_list[mgd[i]];
3225 p_no ++;
3226 }
3227
3228 }
3229 }
3230
3231 delete [] shp.poly_list;
3232 delete [] shp.p_normal_list;
3233 shp.poly_list = new_polys;
3234 shp.p_normal_list = new_pnorms;
3235 shp.num_polys = p_no;
3236
3237 }
3238
3239
3240
3241
3242
3243
3244 #if 0
3245 BOOL copy_to_mainshpl (Shape_Chunk * shp, int list_pos)
3246 {
3247 SHAPEHEADER * shphd = (SHAPEHEADER *) AllocateMem(sizeof(SHAPEHEADER));
3248 memset(shphd,0,sizeof(SHAPEHEADER));
3249
3250 ChunkShape cshp = shp->shape_data;
3251
3252 Shape_Merge_Data_Chunk * smdc = 0;
3253
3254 Chunk * pChunk = shp->lookup_single_child("SHPMRGDT");
3255 if (pChunk)
3256 {
3257 smdc = (Shape_Merge_Data_Chunk *) pChunk;
3258 }
3259
3260 merge_polygons_in_chunkshape (cshp,smdc);
3261
3262 int i,j, * tptr;
3263
3264 mainshapelist[list_pos] = shphd;
3265
3266 // header data (note shapeheader is calloced)
3267
3268 shphd->shapeflags = shphd->shapeflags | (ShapeFlag_AugZ | ShapeFlag_AugZ_Lite |
3269 ShapeFlag_SizeSortItems); // SIZE HACK!!!
3270 shphd->numpoints = cshp.num_verts;
3271 shphd->numitems = cshp.num_polys;
3272
3273 shphd->shaperadius = (int) (cshp.radius*local_scale);
3274
3275 shphd->shapemaxx = (int) (cshp.max.x*local_scale);
3276 shphd->shapeminx = (int) (cshp.min.x*local_scale);
3277 shphd->shapemaxy = (int) (cshp.max.y*local_scale);
3278 shphd->shapeminy = (int) (cshp.min.y*local_scale);
3279 shphd->shapemaxz = (int) (cshp.max.z*local_scale);
3280 shphd->shapeminz = (int) (cshp.min.z*local_scale);
3281
3282 // AllocateMem arrays
3283
3284 shphd->points = (int **) AllocateMem (sizeof(int *));
3285 *(shphd->points) = (int *) AllocateMem (sizeof(int) * shphd->numpoints * 3);
3286
3287 shphd->sh_vnormals = (int **) AllocateMem (sizeof(int *));
3288 *(shphd->sh_vnormals) = (int *) AllocateMem (sizeof(int) * shphd->numpoints * 3);
3289
3290 shphd->sh_normals = (int **) AllocateMem (sizeof(int *));
3291 *(shphd->sh_normals) = (int *) AllocateMem (sizeof(int) * shphd->numitems * 3);
3292
3293 // for textures
3294 if (cshp.num_uvs)
3295 shphd->sh_textures = (int **) AllocateMem (sizeof(int *) * cshp.num_uvs);
3296 if (cshp.num_texfiles)
3297 shphd->sh_localtextures = (char **) AllocateMem (sizeof(char *) * (cshp.num_texfiles+1));
3298
3299 int * item_list;
3300
3301 shphd->items = (int **) AllocateMem (sizeof(int *) * shphd->numitems);
3302 item_list = (int *) AllocateMem (sizeof(int) * shphd->numitems * 9);
3303
3304 tptr = *(shphd->points);
3305
3306 for (i=0; i<shphd->numpoints; i++) {
3307 tptr[i*3] = (int) (cshp.v_list[i].x*local_scale);
3308 tptr[i*3 + 1] = (int) (cshp.v_list[i].y*local_scale);
3309 tptr[i*3 + 2] = (int) (cshp.v_list[i].z*local_scale);
3310 }
3311
3312 tptr = *(shphd->sh_vnormals);
3313
3314 for (i=0; i<shphd->numpoints; i++) {
3315 tptr[i*3] = (int) (cshp.v_normal_list[i].x*ONE_FIXED);
3316 tptr[i*3 + 1] = (int) (cshp.v_normal_list[i].y*ONE_FIXED);
3317 tptr[i*3 + 2] = (int) (cshp.v_normal_list[i].z*ONE_FIXED);
3318 }
3319
3320 tptr = *(shphd->sh_normals);
3321
3322 for (i=0; i<shphd->numitems; i++) {
3323 tptr[i*3] = (int) (cshp.p_normal_list[i].x*ONE_FIXED);
3324 tptr[i*3 + 1] = (int) (cshp.p_normal_list[i].y*ONE_FIXED);
3325 tptr[i*3 + 2] = (int) (cshp.p_normal_list[i].z*ONE_FIXED);
3326 }
3327
3328
3329 for (i=0; i<shphd->numitems; i++)
3330 shphd->items[i] = &item_list[i*9];
3331
3332
3333
3334 for (i=0; i<shphd->numitems; i++) {
3335
3336
3337 item_list[i*9] = (cshp.poly_list[i].engine_type);
3338 // item_list[i*9] = I_Polyline;
3339
3340 /* trap for polylines*/
3341 if((item_list[i*9] < 2 ) || (item_list[i*9] > 9))
3342 {
3343 item_list[i*9] = I_Polygon;
3344 }
3345 #if 1
3346 /* try to set gouraud, for hazing*/
3347
3348 if(item_list[i*9] == I_Polygon)
3349 {
3350 item_list[i*9] = I_GouraudPolygon;
3351 }
3352
3353 if(item_list[i*9] == I_2dTexturedPolygon)
3354 {
3355 item_list[i*9] = I_Gouraud2dTexturedPolygon;
3356 }
3357
3358 if(item_list[i*9] == I_3dTexturedPolygon)
3359 {
3360 item_list[i*9] = I_Gouraud2dTexturedPolygon;
3361 }
3362 #endif
3363
3364 // if(item_list[i*9] == I_Polygon)
3365 // {
3366 // item_list[i*9] = I_ZB_Polygon;
3367 // /*HACK HACK ROXHACK*/
3368 // }
3369
3370 #if SupportZBuffering
3371 #else
3372 if(item_list[i*9] == I_ZB_Polygon)
3373 item_list[i*9] = I_Polygon;
3374
3375 if(item_list[i*9] == I_ZB_GouraudPolygon)
3376 item_list[i*9] = I_GouraudPolygon;
3377
3378 if(item_list[i*9] == I_ZB_PhongPolygon)
3379 item_list[i*9] = I_PhongPolygon;
3380
3381 if(item_list[i*9] == I_ZB_2dTexturedPolygon)
3382 item_list[i*9] = I_2dTexturedPolygon;
3383
3384 if(item_list[i*9] == I_ZB_Gouraud2dTexturedPolygon)
3385 item_list[i*9] = I_Gouraud2dTexturedPolygon;
3386
3387 if(item_list[i*9] == I_ZB_3dTexturedPolygon)
3388 item_list[i*9] = I_3dTexturedPolygon;
3389 #endif
3390
3391
3392
3393 item_list[i*9 + 1] = (cshp.poly_list[i].normal_index * 3);
3394 item_list[i*9 + 2] = (cshp.poly_list[i].flags&~ChunkInternalItemFlags);
3395 // item_list[i*9 + 2] = (cshp.poly_list[i].flags) | iflag_nolight;
3396 item_list[i*9 + 3] = (cshp.poly_list[i].colour);
3397
3398 #if 1
3399 if ( (item_list[i*9] == I_2dTexturedPolygon
3400 || item_list[i*9] == I_Gouraud2dTexturedPolygon
3401 || item_list[i*9] == I_3dTexturedPolygon
3402 || item_list[i*9] == I_Gouraud3dTexturedPolygon
3403 ) &&
3404 !( item_list[i*9 + 3] & 0x8000 ) )
3405 {
3406 int texno = item_list[i*9 + 3] & 0x7fff;
3407
3408 if (texno <= max_index)
3409 if ((tex_index_nos[texno] != -1))
3410 {
3411 item_list[i*9 + 3] &= 0xffff0000;
3412 item_list[i*9 + 3] += tex_index_nos[texno];
3413
3414 /* hack in iflag_no_light */
3415 item_list[i*9 + 2] |= iflag_gsort_ptest /*| iflag_nolight*/ | iflag_linear_s | iflag_tx2dor3d;
3416
3417 }
3418 else
3419 {
3420 item_list[i*9] = I_Polygon;
3421 item_list[i*9 + 2] = (cshp.poly_list[i].flags&~ChunkInternalItemFlags) | iflag_nolight;
3422 item_list[i*9 + 3] = 0xffffffff;
3423 }
3424 else
3425 {
3426 item_list[i*9] = I_Polygon;
3427 item_list[i*9 + 2] = (cshp.poly_list[i].flags&~ChunkInternalItemFlags) | iflag_nolight;
3428 item_list[i*9 + 3] = 0xffffffff;
3429 }
3430 }
3431 #endif
3432
3433 // item_list[i*9 + 3] = 0xffffffff;
3434
3435
3436 for (j=0;j<cshp.poly_list[i].num_verts;j++)
3437 // item_list[i*9 + 4 +j] = (cshp.poly_list[i].vert_ind[j] *3);
3438 /* KJL 12:21:58 9/17/97 - I've removed the annoying *3 */
3439 item_list[i*9 + 4 +j] = (cshp.poly_list[i].vert_ind[j]);
3440 for (;j<5;j++)
3441 item_list[i*9 + 4 +j] = -1;
3442 }
3443
3444 if (cshp.num_uvs)
3445 {
3446 for (i=0; i<cshp.num_uvs; i++) {
3447 shphd->sh_textures[i] = (int *) AllocateMem (sizeof(int *) * cshp.uv_list[i].num_verts * 2);
3448 for (j=0; j<cshp.uv_list[i].num_verts; j++) {
3449 (shphd->sh_textures[i])[(j*2)] = (int)cshp.uv_list[i].vert[j].u;
3450 (shphd->sh_textures[i])[(j*2)+1] = (int)cshp.uv_list[i].vert[j].v;
3451 }
3452 }
3453 }
3454
3455 if (cshp.num_texfiles)
3456 {
3457 for (i=0; i<cshp.num_texfiles; i++) {
3458 #if john
3459 shphd->sh_localtextures[i] =
3460 (char *) AllocateMem (sizeof(char) * (strlen(cshp.texture_fns[i]) + strlen(TexturesRoot) + 1) );
3461 sprintf (shphd->sh_localtextures[i],"%s%s",TexturesRoot, cshp.texture_fns[i]);
3462 char * dotpos;
3463 dotpos = strrchr (shphd->sh_localtextures[i], '.');
3464 sprintf (dotpos,".pg0");
3465 #else
3466 shphd->sh_localtextures[i] =
3467 (char *) AllocateMem (sizeof(char) * (strlen(cshp.texture_fns[i]) + 1) );
3468 strcpy (shphd->sh_localtextures[i], cshp.texture_fns[i]);
3469 #endif
3470 }
3471 shphd->sh_localtextures[i] = 0;
3472 }
3473
3474
3475
3476
3477 SHAPEINSTR * instruct = (SHAPEINSTR *)AllocateMem(sizeof(SHAPEINSTR)*6);
3478
3479 shphd->sh_instruction = instruct;
3480
3481
3482
3483 instruct[0].sh_instr = I_ShapePoints; /*I_shapepoints*/
3484 instruct[0].sh_numitems = shphd->numpoints;
3485 instruct[0].sh_instr_data = shphd->points;
3486
3487 instruct[1].sh_instr = I_ShapeNormals; /*I_shapenormals*/
3488 instruct[1].sh_numitems = shphd->numitems;
3489 instruct[1].sh_instr_data = shphd->sh_normals;
3490
3491 instruct[2].sh_instr = I_ShapeProject; /*I_shapeproject*/
3492 instruct[2].sh_numitems = shphd->numpoints;
3493 instruct[2].sh_instr_data = shphd->points;
3494
3495 instruct[3].sh_instr = I_ShapeVNormals; /*I_shapevnormals*/
3496 instruct[3].sh_numitems = shphd->numpoints;
3497 instruct[3].sh_instr_data = shphd->sh_vnormals;
3498
3499 instruct[4].sh_instr = I_ShapeItems;
3500 instruct[4].sh_numitems = shphd->numitems;
3501 instruct[4].sh_instr_data = shphd->items;
3502
3503 instruct[5].sh_instr = I_ShapeEnd; /*I_shapeEND*/
3504 instruct[5].sh_numitems = 0;
3505 instruct[5].sh_instr_data = 0;
3506
3507
3508 Chunk * pchAnim = shp->lookup_single_child("TEXTANIM");
3509 if (pchAnim)
3510 {
3511 Shape_Merge_Data_Chunk* smdc=0;
3512 Chunk * pChunk=shp->lookup_single_child("SHPMRGDT");
3513 if(pChunk) smdc=(Shape_Merge_Data_Chunk*)pChunk;
3514 SetupAnimatedTextures(shp,shphd,(Animation_Chunk*)pchAnim,smdc);
3515 }
3516
3517
3518
3519 return TRUE;
3520
3521 }
3522 #endif
3523
3524 #if 0
3525 BOOL copy_to_mainshpl (Shape_Sub_Shape_Chunk * shp, int list_pos)
3526 {
3527 SHAPEHEADER * shphd = (SHAPEHEADER *) AllocateMem(sizeof(SHAPEHEADER));
3528 memset(shphd,0,sizeof(SHAPEHEADER));
3529
3530 ChunkShape cshp = shp->shape_data;
3531
3532 Shape_Merge_Data_Chunk * smdc = 0;
3533
3534 Chunk * pChunk = shp->lookup_single_child("SHPMRGDT");
3535 if (pChunk)
3536 {
3537 smdc = (Shape_Merge_Data_Chunk *) pChunk;
3538 }
3539
3540 merge_polygons_in_chunkshape (cshp,smdc);
3541
3542 int i,j, * tptr;
3543
3544 mainshapelist[list_pos] = shphd;
3545
3546 // header data (note shapeheader is calloced)
3547
3548 shphd->shapeflags = shphd->shapeflags | (ShapeFlag_AugZ | ShapeFlag_AugZ_Lite |
3549 ShapeFlag_SizeSortItems); // SIZE HACK!!!
3550 shphd->numpoints = cshp.num_verts;
3551 shphd->numitems = cshp.num_polys;
3552
3553 shphd->shaperadius = (int) (cshp.radius*local_scale);
3554
3555 shphd->shapemaxx = (int) (cshp.max.x*local_scale);
3556 shphd->shapeminx = (int) (cshp.min.x*local_scale);
3557 shphd->shapemaxy = (int) (cshp.max.y*local_scale);
3558 shphd->shapeminy = (int) (cshp.min.y*local_scale);
3559 shphd->shapemaxz = (int) (cshp.max.z*local_scale);
3560 shphd->shapeminz = (int) (cshp.min.z*local_scale);
3561
3562 // AllocateMem arrays
3563
3564 shphd->points = (int **) AllocateMem (sizeof(int *));
3565 *(shphd->points) = (int *) AllocateMem (sizeof(int) * shphd->numpoints * 3);
3566
3567 shphd->sh_vnormals = (int **) AllocateMem (sizeof(int *));
3568 *(shphd->sh_vnormals) = (int *) AllocateMem (sizeof(int) * shphd->numpoints * 3);
3569
3570 shphd->sh_normals = (int **) AllocateMem (sizeof(int *));
3571 *(shphd->sh_normals) = (int *) AllocateMem (sizeof(int) * shphd->numitems * 3);
3572
3573 // for textures
3574 if (cshp.num_uvs)
3575 shphd->sh_textures = (int **) AllocateMem (sizeof(int *) * cshp.num_uvs);
3576 if (cshp.num_texfiles)
3577 shphd->sh_localtextures = (char **) AllocateMem (sizeof(char *) * (cshp.num_texfiles+1));
3578
3579 int * item_list;
3580
3581 shphd->items = (int **) AllocateMem (sizeof(int *) * shphd->numitems);
3582 item_list = (int *) AllocateMem (sizeof(int) * shphd->numitems * 9);
3583
3584 tptr = *(shphd->points);
3585
3586 for (i=0; i<shphd->numpoints; i++) {
3587 tptr[i*3] = (int) (cshp.v_list[i].x*local_scale);
3588 tptr[i*3 + 1] = (int) (cshp.v_list[i].y*local_scale);
3589 tptr[i*3 + 2] = (int) (cshp.v_list[i].z*local_scale);
3590 }
3591
3592 tptr = *(shphd->sh_vnormals);
3593
3594 for (i=0; i<shphd->numpoints; i++) {
3595 tptr[i*3] = (int) (cshp.v_normal_list[i].x*ONE_FIXED);
3596 tptr[i*3 + 1] = (int) (cshp.v_normal_list[i].y*ONE_FIXED);
3597 tptr[i*3 + 2] = (int) (cshp.v_normal_list[i].z*ONE_FIXED);
3598 }
3599
3600 tptr = *(shphd->sh_normals);
3601
3602 for (i=0; i<shphd->numitems; i++) {
3603 tptr[i*3] = (int) (cshp.p_normal_list[i].x*ONE_FIXED);
3604 tptr[i*3 + 1] = (int) (cshp.p_normal_list[i].y*ONE_FIXED);
3605 tptr[i*3 + 2] = (int) (cshp.p_normal_list[i].z*ONE_FIXED);
3606 }
3607
3608
3609 for (i=0; i<shphd->numitems; i++)
3610 shphd->items[i] = &item_list[i*9];
3611
3612
3613
3614 for (i=0; i<shphd->numitems; i++) {
3615
3616
3617 item_list[i*9] = (cshp.poly_list[i].engine_type);
3618 // item_list[i*9] = I_Polyline;
3619 #if 1
3620 /* try to set gouraud, for hazing*/
3621
3622 if(item_list[i*9] == I_Polygon)
3623 {
3624 item_list[i*9] = I_GouraudPolygon;
3625 }
3626
3627 if(item_list[i*9] == I_2dTexturedPolygon)
3628 {
3629 item_list[i*9] = I_Gouraud2dTexturedPolygon;
3630 }
3631
3632 if(item_list[i*9] == I_3dTexturedPolygon)
3633 {
3634 item_list[i*9] = I_Gouraud2dTexturedPolygon;
3635 }
3636 #endif
3637
3638 // if((item_list[i*9] < 2 ) || (item_list[i*9] > 9))
3639 // {
3640 // item_list[i*9] = I_Polygon;
3641 // }
3642 #if 1
3643 /* try to set gouraud, for hazing*/
3644
3645 if(item_list[i*9] == I_Polygon)
3646 {
3647 item_list[i*9] = I_GouraudPolygon;
3648 }
3649
3650 if(item_list[i*9] == I_2dTexturedPolygon)
3651 {
3652 item_list[i*9] = I_Gouraud2dTexturedPolygon;
3653 }
3654
3655 if(item_list[i*9] == I_3dTexturedPolygon)
3656 {
3657 item_list[i*9] = I_Gouraud2dTexturedPolygon;
3658 }
3659 #endif
3660
3661 // if(item_list[i*9] == I_Polygon)
3662 // {
3663 // item_list[i*9] = I_ZB_Polygon;
3664 // /*HACK HACK ROXHACK*/
3665 // }
3666
3667 #if SupportZBuffering
3668 #else
3669 if(item_list[i*9] == I_ZB_Polygon)
3670 item_list[i*9] = I_Polygon;
3671
3672 if(item_list[i*9] == I_ZB_GouraudPolygon)
3673 item_list[i*9] = I_GouraudPolygon;
3674
3675 if(item_list[i*9] == I_ZB_PhongPolygon)
3676 item_list[i*9] = I_PhongPolygon;
3677
3678 if(item_list[i*9] == I_ZB_2dTexturedPolygon)
3679 item_list[i*9] = I_2dTexturedPolygon;
3680
3681 if(item_list[i*9] == I_ZB_Gouraud2dTexturedPolygon)
3682 item_list[i*9] = I_Gouraud2dTexturedPolygon;
3683
3684 if(item_list[i*9] == I_ZB_3dTexturedPolygon)
3685 item_list[i*9] = I_3dTexturedPolygon;
3686 #endif
3687
3688
3689
3690 item_list[i*9 + 1] = (cshp.poly_list[i].normal_index * 3);
3691 item_list[i*9 + 2] = (cshp.poly_list[i].flags&~ChunkInternalItemFlags);
3692 // item_list[i*9 + 2] = (cshp.poly_list[i].flags) | iflag_nolight;
3693 item_list[i*9 + 3] = (cshp.poly_list[i].colour);
3694
3695 #if 1
3696 if ( (item_list[i*9] == 5 || item_list[i*9] == 6
3697 || item_list[i*9] == 7) &&
3698 !( item_list[i*9 + 3] & 0x8000 ) )
3699 {
3700 int texno = item_list[i*9 + 3] & 0x7fff;
3701
3702 if (texno <= max_index)
3703 if ((tex_index_nos[texno] != -1))
3704 {
3705 item_list[i*9 + 3] &= 0xffff0000;
3706 item_list[i*9 + 3] += tex_index_nos[texno];
3707
3708 /* hack in iflag_no_light */
3709 item_list[i*9 + 2] |= iflag_gsort_ptest /*| iflag_nolight*/ | iflag_linear_s | iflag_tx2dor3d;
3710
3711 }
3712 else
3713 {
3714 item_list[i*9] = I_Polygon;
3715 item_list[i*9 + 2] = (cshp.poly_list[i].flags&~ChunkInternalItemFlags) | iflag_nolight;
3716 item_list[i*9 + 3] = 0xffffffff;
3717 }
3718 else
3719 {
3720 item_list[i*9] = I_Polygon;
3721 item_list[i*9 + 2] = (cshp.poly_list[i].flags &~ChunkInternalItemFlags) | iflag_nolight;
3722 item_list[i*9 + 3] = 0xffffffff;
3723 }
3724 }
3725 #endif
3726
3727 // item_list[i*9 + 3] = 0xffffffff;
3728
3729
3730 for (j=0;j<cshp.poly_list[i].num_verts;j++)
3731 // item_list[i*9 + 4 +j] = (cshp.poly_list[i].vert_ind[j] *3);
3732 /* KJL 12:23:02 9/17/97 - I've removed the annoying *3 */
3733 item_list[i*9 + 4 +j] = (cshp.poly_list[i].vert_ind[j]);
3734 for (;j<5;j++)
3735 item_list[i*9 + 4 +j] = -1;
3736 }
3737
3738 if (cshp.num_uvs)
3739 {
3740 for (i=0; i<cshp.num_uvs; i++) {
3741 shphd->sh_textures[i] = (int *) AllocateMem (sizeof(int *) * cshp.uv_list[i].num_verts * 2);
3742 for (j=0; j<cshp.uv_list[i].num_verts; j++) {
3743 (shphd->sh_textures[i])[(j*2)] = (int)cshp.uv_list[i].vert[j].u;
3744 (shphd->sh_textures[i])[(j*2)+1] = (int)cshp.uv_list[i].vert[j].v;
3745 }
3746 }
3747 }
3748
3749 if (cshp.num_texfiles)
3750 {
3751 for (i=0; i<cshp.num_texfiles; i++) {
3752 #if john
3753 shphd->sh_localtextures[i] =
3754 (char *) AllocateMem (sizeof(char) * (strlen(cshp.texture_fns[i]) + strlen(TexturesRoot) + 1) );
3755 sprintf (shphd->sh_localtextures[i],"%s%s",TexturesRoot, cshp.texture_fns[i]);
3756 char * dotpos;
3757 dotpos = strrchr (shphd->sh_localtextures[i], '.');
3758 sprintf (dotpos,".pg0");
3759 #else
3760 shphd->sh_localtextures[i] =
3761 (char *) AllocateMem (sizeof(char) * (strlen(cshp.texture_fns[i]) + 1) );
3762 strcpy (shphd->sh_localtextures[i], cshp.texture_fns[i]);
3763 #endif
3764 }
3765 shphd->sh_localtextures[i] = 0;
3766 }
3767
3768
3769
3770
3771 SHAPEINSTR * instruct = (SHAPEINSTR *)AllocateMem(sizeof(SHAPEINSTR)*6);
3772
3773 shphd->sh_instruction = instruct;
3774
3775
3776 instruct[0].sh_instr = I_ShapePoints; /*I_shapepoints*/
3777 instruct[0].sh_numitems = shphd->numpoints;
3778 instruct[0].sh_instr_data = shphd->points;
3779
3780 instruct[1].sh_instr = I_ShapeNormals; /*I_shapenormals*/
3781 instruct[1].sh_numitems = shphd->numitems;
3782 instruct[1].sh_instr_data = shphd->sh_normals;
3783
3784 instruct[2].sh_instr = I_ShapeProject; /*I_shapeproject*/
3785 instruct[2].sh_numitems = shphd->numpoints;
3786 instruct[2].sh_instr_data = shphd->points;
3787
3788 instruct[3].sh_instr = I_ShapeVNormals; /*I_shapevnormals*/
3789 instruct[3].sh_numitems = shphd->numpoints;
3790 instruct[3].sh_instr_data = shphd->sh_vnormals;
3791
3792 instruct[4].sh_instr = I_ShapeItems;
3793 instruct[4].sh_numitems = shphd->numitems;
3794 instruct[4].sh_instr_data = shphd->items;
3795
3796 instruct[5].sh_instr = I_ShapeEnd; /*I_shapeEND*/
3797 instruct[5].sh_numitems = 0;
3798 instruct[5].sh_instr_data = 0;
3799
3800
3801
3802 return TRUE;
3803 #if 0
3804 SHAPEHEADER * shphd = (SHAPEHEADER *) AllocateMem(sizeof(SHAPEHEADER));
3805 memset(shphd,0,sizeof(SHAPEHEADER));
3806
3807 ChunkShape cshp = shp->shape_data;
3808
3809 Shape_Merge_Data_Chunk * smdc = 0;
3810
3811 Chunk * pChunk = shp->lookup_single_child("SHPMRGDT");
3812 if (pChunk)
3813 {
3814 smdc = (Shape_Merge_Data_Chunk *) pChunk;
3815 }
3816
3817 merge_polygons_in_chunkshape (cshp,smdc);
3818
3819 int i,j, * tptr;
3820
3821 mainshapelist[list_pos] = shphd;
3822
3823 // header data (note shapeheader is calloced)
3824
3825 shphd->numpoints = cshp.num_verts;
3826 shphd->numitems = cshp.num_polys;
3827
3828 shphd->shaperadius = (int) (cshp.radius*local_scale);
3829
3830 shphd->shapeflags = shphd->shapeflags | (ShapeFlag_AugZ | ShapeFlag_AugZ_Lite |
3831 ShapeFlag_SizeSortItems); // SIZE HACK!!!
3832
3833 shphd->shapemaxx = (int) (cshp.max.x*local_scale);
3834 shphd->shapeminx = (int) (cshp.min.x*local_scale);
3835 shphd->shapemaxy = (int) (cshp.max.y*local_scale);
3836 shphd->shapeminy = (int) (cshp.min.y*local_scale);
3837 shphd->shapemaxz = (int) (cshp.max.z*local_scale);
3838 shphd->shapeminz = (int) (cshp.min.z*local_scale);
3839
3840 // AllocateMem arrays
3841
3842 shphd->points = (int **) AllocateMem (sizeof(int *));
3843 *(shphd->points) = (int *) AllocateMem (sizeof(int) * shphd->numpoints * 3);
3844
3845 shphd->sh_vnormals = (int **) AllocateMem (sizeof(int *));
3846 *(shphd->sh_vnormals) = (int *) AllocateMem (sizeof(int) * shphd->numpoints * 3);
3847
3848 shphd->sh_normals = (int **) AllocateMem (sizeof(int *));
3849 *(shphd->sh_normals) = (int *) AllocateMem (sizeof(int) * shphd->numitems * 3);
3850
3851 // for textures
3852 if (cshp.num_uvs)
3853 shphd->sh_textures = (int **) AllocateMem (sizeof(int *) * cshp.num_uvs);
3854 if (cshp.num_texfiles)
3855 shphd->sh_localtextures = (char **) AllocateMem (sizeof(char *) * (cshp.num_texfiles+1));
3856
3857 int * item_list;
3858
3859 shphd->items = (int **) AllocateMem (sizeof(int *) * shphd->numitems);
3860 item_list = (int *) AllocateMem (sizeof(int) * shphd->numitems * 9);
3861
3862 tptr = *(shphd->points);
3863
3864 for (i=0; i<shphd->numpoints; i++) {
3865 tptr[i*3] = (int) (cshp.v_list[i].x*local_scale);
3866 tptr[i*3 + 1] = (int) (cshp.v_list[i].y*local_scale);
3867 tptr[i*3 + 2] = (int) (cshp.v_list[i].z*local_scale);
3868 }
3869
3870 tptr = *(shphd->sh_vnormals);
3871
3872 for (i=0; i<shphd->numpoints; i++) {
3873 tptr[i*3] = (int) (cshp.v_normal_list[i].x*ONE_FIXED);
3874 tptr[i*3 + 1] = (int) (cshp.v_normal_list[i].y*ONE_FIXED);
3875 tptr[i*3 + 2] = (int) (cshp.v_normal_list[i].z*ONE_FIXED);
3876 }
3877
3878 tptr = *(shphd->sh_normals);
3879
3880 for (i=0; i<shphd->numitems; i++) {
3881 tptr[i*3] = (int) (cshp.p_normal_list[i].x*ONE_FIXED);
3882 tptr[i*3 + 1] = (int) (cshp.p_normal_list[i].y*ONE_FIXED);
3883 tptr[i*3 + 2] = (int) (cshp.p_normal_list[i].z*ONE_FIXED);
3884 }
3885
3886
3887 for (i=0; i<shphd->numitems; i++)
3888 shphd->items[i] = &item_list[i*9];
3889
3890
3891 for (i=0; i<shphd->numitems; i++) {
3892 item_list[i*9] = (cshp.poly_list[i].engine_type);
3893 // item_list[i*9] = I_Polyline;
3894
3895
3896 if((item_list[i*9] < 2 ) || (item_list[i*9] > 9))
3897 {
3898 item_list[i*9] = I_Polygon;
3899 }
3900
3901 if(item_list[i*9] == I_2dTexturedPolygon)
3902 {
3903 item_list[i*9] = I_Polygon;
3904 }
3905
3906 if(item_list[i*9] == I_3dTexturedPolygon)
3907 {
3908 item_list[i*9] = I_2dTexturedPolygon;
3909 }
3910
3911 // if(item_list[i*9] == I_Polygon)
3912 // {
3913 // item_list[i*9] = I_ZB_Polygon;
3914 // /*HACK HACK ROXHACK*/
3915 // }
3916
3917 item_list[i*9 + 1] = (cshp.poly_list[i].normal_index * 3);
3918 item_list[i*9 + 2] = (cshp.poly_list[i].flags&~ChunkInternalItemFlags);
3919 // item_list[i*9 + 2] = (cshp.poly_list[i].flags) | iflag_nolight;
3920 item_list[i*9 + 3] = (cshp.poly_list[i].colour);
3921
3922 if ( (item_list[i*9] == 5 || item_list[i*9] == 6) &&
3923 !( item_list[i*9 + 3] & 0x8000 ) )
3924 {
3925 int texno = item_list[i*9 + 3] & 0x7fff;
3926
3927 if (texno < max_index)
3928 if (tex_index_nos[texno] != -1)
3929 {
3930 item_list[i*9 + 3] &= 0xffff0000;
3931 item_list[i*9 + 3] += tex_index_nos[texno];
3932 }
3933 else
3934 {
3935 item_list[i*9] = I_Polyline;
3936 item_list[i*9 + 2] = (cshp.poly_list[i].flags &~ChunkInternalItemFlags) /*| iflag_nolight*/;
3937 item_list[i*9 + 3] = 0xffffffff;
3938 }
3939 else
3940 {
3941 item_list[i*9] = I_Polyline;
3942 item_list[i*9 + 2] = (cshp.poly_list[i].flags &~ChunkInternalItemFlags) /*| iflag_nolight*/;
3943 item_list[i*9 + 3] = 0xffffffff;
3944 }
3945 }
3946
3947
3948 // item_list[i*9 + 3] = 0xffffffff;
3949 for (j=0;j<cshp.poly_list[i].num_verts;j++)
3950 // item_list[i*9 + 4 +j] = (cshp.poly_list[i].vert_ind[j] *3);
3951 /* KJL 12:23:02 9/17/97 - I've removed the annoying *3 */
3952 item_list[i*9 + 4 +j] = (cshp.poly_list[i].vert_ind[j]);
3953 for (;j<5;j++)
3954 item_list[i*9 + 4 +j] = -1;
3955 }
3956
3957 if (cshp.num_uvs)
3958 {
3959 for (i=0; i<cshp.num_uvs; i++) {
3960 shphd->sh_textures[i] = (int *) AllocateMem (sizeof(int *) * cshp.uv_list[i].num_verts * 2);
3961 for (j=0; j<cshp.uv_list[i].num_verts; j++) {
3962 (shphd->sh_textures[i])[(j*2)] = (int)cshp.uv_list[i].vert[j].u;
3963 (shphd->sh_textures[i])[(j*2)+1] = (int)cshp.uv_list[i].vert[j].v;
3964 }
3965 }
3966 }
3967 /*
3968 * FILENAME: e:\avpcode\3dc\win95\chnkload.cpp
3969 *
3970 * PARAMETERS:
3971 *
3972 * DESCRIPTION:
3973 *
3974 * RETURNS:
3975 *
3976 */
3977
3978
3979 if (cshp.num_texfiles)
3980 {
3981 for (i=0; i<cshp.num_texfiles; i++) {
3982 #if john
3983 shphd->sh_localtextures[i] =
3984 (char *) AllocateMem (sizeof(char) * (strlen(cshp.texture_fns[i]) + strlen(TexturesRoot) + 1) );
3985 sprintf (shphd->sh_localtextures[i],"%s%s",TexturesRoot, cshp.texture_fns[i]);
3986 char * dotpos;
3987 dotpos = strrchr (shphd->sh_localtextures[i], '.');
3988 sprintf (dotpos,".pg0");
3989 #else
3990 shphd->sh_localtextures[i] =
3991 (char *) AllocateMem (sizeof(char) * (strlen(cshp.texture_fns[i]) + 1) );
3992 strcpy (shphd->sh_localtextures[i], cshp.texture_fns[i]);
3993 #endif
3994 }
3995 shphd->sh_localtextures[i] = 0;
3996 }
3997
3998
3999
4000
4001 SHAPEINSTR * instruct = (SHAPEINSTR *)AllocateMem(sizeof(SHAPEINSTR)*6);
4002
4003 shphd->sh_instruction = instruct;
4004
4005
4006 instruct[0].sh_instr = I_ShapePoints; /*I_shapepoints*/
4007 instruct[0].sh_numitems = shphd->numpoints;
4008 instruct[0].sh_instr_data = shphd->points;
4009
4010 instruct[1].sh_instr = I_ShapeNormals; /*I_shapenormals*/
4011 instruct[1].sh_numitems = shphd->numitems;
4012 instruct[1].sh_instr_data = shphd->sh_normals;
4013
4014 instruct[2].sh_instr = I_ShapeProject; /*I_shapeproject*/
4015 instruct[2].sh_numitems = shphd->numpoints;
4016 instruct[2].sh_instr_data = shphd->points;
4017
4018 instruct[3].sh_instr = I_ShapeVNormals; /*I_shapevnormals*/
4019 instruct[3].sh_numitems = shphd->numpoints;
4020 instruct[3].sh_instr_data = shphd->sh_vnormals;
4021
4022 instruct[4].sh_instr = I_ShapeItems;
4023 instruct[4].sh_numitems = shphd->numitems;
4024 instruct[4].sh_instr_data = shphd->items;
4025
4026 instruct[5].sh_instr = I_ShapeEnd; /*I_shapeEND*/
4027 instruct[5].sh_numitems = 0;
4028 instruct[5].sh_instr_data = 0;
4029
4030
4031
4032 return TRUE;
4033 #endif
4034 }
4035 #endif
4036
4037
4038
4039
4040
4041