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