Subversion Repositories spk

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
11 cycrow 1
// TextureFile.cpp: implementation of the CTextureFile class.
2
//
3
//////////////////////////////////////////////////////////////////////
4
 
5
#include "TextureFile.h"
6
 
7
#include <stdlib.h>
8
#include <stdio.h>
9
 
10
//////////////////////////////////////////////////////////////////////
11
// Construction/Destruction
12
//////////////////////////////////////////////////////////////////////
13
 
14
CTextureFile::CTextureFile( bool editor )
15
{
16
	m_data			= NULL;
17
	m_numData		= 0;
18
	m_height		= 0;
19
	m_width			= 0;
20
	m_frames.x		= 0;
21
	m_frames.y		= 0;
22
	m_frames.rows	= 1; 
23
	m_frames.cols	= 1; 
24
	m_alpha			= false;
25
	m_alphamap[0]	= 0;
26
	m_alphamap[1]	= 0;
27
	m_alphamap[2]	= 0;
28
	m_animNum		= 0;
29
	m_anim			= NULL;
30
	m_collisionMap	= false;
31
	m_collisionData = NULL;
32
	m_numframes		= 0;
33
	m_framebounds	= NULL;
34
 
35
	m_editor		= editor;
36
}
37
 
38
CTextureFile::~CTextureFile()
39
{
40
	if ( m_data )
41
		delete[] m_data;
42
 
43
	if ( m_collisionData )
44
		delete[] m_collisionData;
45
 
46
	if ( m_anim )
47
	{
48
		for ( int i = 0; i < m_animNum; i++ )
49
		{
50
			if ( m_anim[i].frames )
51
				delete[] m_anim[i].frames;
52
			if ( m_anim[i].name )
53
				delete[] m_anim[i].name;
54
		}
55
 
56
		if ( m_editor )
57
			free ( m_anim );
58
		else
59
			delete[] m_anim;
60
	}
61
 
62
	//if ( m_framebounds )
63
	//	delete [] m_framebounds;
64
}
65
 
66
STextureData *CTextureFile::CreateData(int width, int height, STextureSize *size )
67
{
68
	if ( (!height) || (!width) )
69
		return NULL;
70
 
71
	size->height  = height;
72
	size->width   = width;
73
	size->num = (height * width);
74
 
75
	STextureData *data = new STextureData[size->num];
76
 
77
	for ( int i = 0; i < size->num; i++ )
78
	{
79
		data[i].r = 0;
80
		data[i].g = 0;
81
		data[i].b = 0;
82
		data[i].alpha = 255;
83
	}
84
 
85
	return data;
86
}
87
 
88
int CTextureFile::LoadTextureTGA(const char *filename )
89
{
90
	STextureSize *size = new STextureSize;
91
 
92
	int error;
93
	m_data = LoadTGA ( filename, size, &error );
94
 
95
	if ( error == TEXTURELOAD_OK )
96
	{
97
		m_height = size->height;
98
		m_width = size->width;
99
		m_numData = size->num;
100
	}
101
	else
102
	{
103
		delete [] m_data;
104
		m_data = NULL;
105
	}
106
 
107
	if ( m_collisionData )
108
		delete [] m_collisionData;
109
	m_collisionMap = false;
110
 
111
	delete [] size;
112
 
113
	return error;
114
}
115
 
116
int CTextureFile::LoadCollisionTGA(const char *filename )
117
{
118
	STextureSize *size = new STextureSize;
119
 
120
	int error;
121
	STextureData *data = LoadTGA ( filename, size, &error );
122
 
123
	if ( error == TEXTURELOAD_OK )
124
	{
125
		if ( (size->height != m_height) || (size->width != m_width) )
126
			error = TEXTURELOAD_SIZEMISMATCH;
127
		else
128
		{
129
			if ( m_collisionData )
130
				delete [] m_collisionData;
131
 
132
			m_collisionData = new bool[size->num];
133
			for ( int i = 0; i < size->num; i++ )
134
				m_collisionData[i] = (data[i].alpha) ? false : true;
135
 
136
			m_collisionMap = true;
137
		}
138
	}
139
 
140
 
141
	delete [] data;
142
	delete [] size;
143
 
144
	return error;
145
}
146
 
147
bool CTextureFile::SaveTGA ( const char *filename )
148
{
149
	FILE *fileID = NULL;
150
	unsigned char header[18];
151
	unsigned char *imagedata;
152
	int i;
153
	int num;
154
 
155
#ifdef CY_USESECURE
156
	if ( fopen_s ( &fileID, filename, "wb" ) )
157
		return false;
158
#else
159
	fileID = fopen ( filename, "wb" );
160
	if ( !fileID )
161
		return false;
162
#endif
163
 
164
	for ( i = 0; i < 18; i++ ) //initilise header to all 0's
165
		header[i] = 0;
166
 
167
	// setup header
168
	header[2] = 2;
169
	header[12] = m_width % 256;
170
	header[13] = (int) (m_width / 256);
171
	header[14] = m_height % 256;
172
	header[15] = (int) (m_height / 256);
173
 
174
	header[16] = 32; // 32 bit
175
	int bitSize = header[16] / 8;
176
 
177
	fwrite(header, sizeof (unsigned char), 22, fileID);   // write header to the file
178
 
179
	imagedata = (unsigned char *)malloc(sizeof(unsigned char) * (m_width * m_height * bitSize));
180
	num = 0;
181
	// write colour data
182
	for ( i = 0; i < (m_width * m_height); i++)
183
	{
184
		imagedata[num]		= m_data[i].b;
185
		imagedata[num +	1]	= m_data[i].g;
186
		imagedata[num + 2]	= m_data[i].r;
187
		if ( bitSize == 4 )
188
			imagedata[num + 3]	= (unsigned char) m_data[i].alpha;
189
 
190
		num += bitSize;
191
	}
192
 
193
	fwrite ( imagedata, sizeof (unsigned char), m_width * m_height * bitSize, fileID );
194
	fclose ( fileID );
195
 
196
	return true;
197
}
198
 
199
STextureData *CTextureFile::LoadTGA(const char *filename, STextureSize *tsize, int *error )
200
{
201
    unsigned char type[4];
202
    unsigned char info[7];
203
    unsigned char *imageData = NULL;
204
    int imageWidth, imageHeight;
205
    int imageBits, size;
206
 
207
	FILE *fileID;
208
	// open the filename
209
#ifdef CY_USESECURE
210
    if ( fopen_s ( &fileID, filename, "r+bt") )
211
	{
212
        *error = TEXTURELOAD_NOFILE;
213
		return NULL;
214
	}
215
#else
216
    if (!(fileID = fopen (filename, "r+bt")))
217
	{
218
        *error = TEXTURELOAD_NOFILE;
219
		return NULL;
220
	}
221
#endif
222
 
223
	// get the heading data
224
    fread (&type, sizeof (char), 3, fileID); // read in colormap info and image type
225
    fseek (fileID, 12, SEEK_SET);			// seek past the header
226
    fread (&info, sizeof (char), 6, fileID);
227
 
228
	/*
229
    if (type[1] != 0 || (type[2] != 2 && type[2] != 3))
230
	{
231
		fclose ( fileID );
232
		return false;
233
	}*/
234
 
235
	// convert heading to data
236
    imageWidth = info[0] + info[1] * 256; // get image size from the header
237
    imageHeight = info[2] + info[3] * 256;
238
    imageBits =	info[4]; 
239
    size = imageWidth * imageHeight;  // number of bits in image file
240
 
241
	// check for right format to load
242
    if ( (imageBits != 32) && (imageBits != 24) ) // invalid format
243
	{
244
		*error = TEXTURELOAD_INVALIDFORMAT;
245
		fclose ( fileID );
246
		return false;
247
	}
248
 
249
/*	if ( imageBits != 32 )
250
	{
251
		fclose ( fileID );
252
		*error = TEXTURELOAD_INVALIDFORMAT;
253
		return NULL;
254
	}*/
255
 
256
	int bitSize = (imageBits / 8);
257
 
258
	// read the data
259
    imageData = (unsigned char *)malloc (size * bitSize); 
260
    if (imageData == NULL)
261
	{
262
		fclose ( fileID );
263
		*error = TEXTURELOAD_INVALIDFORMAT;
264
		return NULL;
265
	}
266
    if ( (int)fread (imageData, sizeof (unsigned char), size * bitSize, fileID) != (int)(size * bitSize) )
267
	{
268
        free (imageData);
269
        *error = TEXTURELOAD_INVALIDFORMAT;
270
		return NULL;
271
    }
272
 
273
	// dont use greyscale ?
274
 
275
	// create the data storage
276
	STextureData *data = CreateData ( imageWidth, imageHeight, tsize );
277
	if ( !data )
278
	{
279
        free (imageData);
280
        *error = TEXTURELOAD_INVALIDFORMAT;
281
		return NULL;
282
	}
283
 
284
	// copy to data storage
285
	int tempI;
286
	for ( int i = 0; i < size; i++ )
287
	{
288
		tempI = i * bitSize;
289
		data[i].b = imageData[tempI];
290
		data[i].g = imageData[tempI + 1];
291
		data[i].r = imageData[tempI + 2];
292
 
293
		if ( imageBits == 32 )
294
			data[i].alpha = imageData[tempI + 3];
295
	}
296
 
297
	free ( imageData );
298
 
299
    fclose (fileID);	
300
 
301
	*error = TEXTURELOAD_OK;
302
 
303
	return data;
304
}
305
 
306
#ifdef DIRECT3D
307
LPDIRECT3DTEXTURE9 CTextureFile::CreateTexture(LPDIRECT3DDEVICE9 device)
308
{
309
	if ( m_numData < 1 )
310
		return NULL;
311
 
312
	LPDIRECT3DTEXTURE9 texture;
313
	if ( FAILED (D3DXCreateTexture ( device, m_width, m_height, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture )) )
314
		return NULL;
315
 
316
    D3DSURFACE_DESC surfDesc;
317
	texture->GetLevelDesc( 0, &surfDesc );
318
 
319
	int h = surfDesc.Height;
320
 
321
    D3DLOCKED_RECT LockedRect;
322
    texture->LockRect( 0, &LockedRect, NULL, 0 );
323
 
324
    DWORD* pBits;
325
    for( DWORD iTexelZ=0; iTexelZ < surfDesc.Height; iTexelZ++ )
326
    {
327
        pBits = (DWORD*) ((BYTE*)LockedRect.pBits + (LockedRect.Pitch * iTexelZ));
328
 
329
        for( DWORD iTexelX = 0; iTexelX < surfDesc.Width; iTexelX++ )
330
        {
331
			int num = m_numData - ((iTexelZ * surfDesc.Width) + (surfDesc.Width - iTexelX));
332
 
333
            DWORD nRed   = (DWORD)  m_data[num].r;
334
            DWORD nGreen = (DWORD)  m_data[num].g;
335
            DWORD nBlue  = (DWORD)  m_data[num].b;
336
            DWORD nAlpha = (DWORD)  m_data[num].alpha;
337
 
338
			if ( m_alpha )
339
			{
340
				if ( (m_data[num].r == m_alphamap[0]) && (m_data[num].g == m_alphamap[1]) && (m_data[num].b == m_alphamap[2]) )
341
					nAlpha = 0;
342
			}
343
 
344
            if( nRed > 0xFF )
345
                nRed = 0xFF;
346
            if( nGreen > 0xFF )
347
                nGreen = 0xFF;
348
            if( nBlue > 0xFF )
349
                nBlue = 0xFF;
350
            if( nAlpha > 0xFF )
351
                nAlpha = 0xFF;
352
 
353
            *pBits = (nAlpha << 24) + (nRed << 16) + (nGreen << 8) + (nBlue << 0);
354
            pBits++;
355
		}
356
	}
357
 
358
	texture->UnlockRect ( 0 );
359
 
360
	return texture;
361
}
362
LPDIRECT3DTEXTURE9 CTextureFile::CreateCollisionTexture(LPDIRECT3DDEVICE9 device, DWORD nRed, DWORD nGreen, DWORD nBlue)
363
{
364
	if ( (m_numData < 1) || (!m_collisionMap) || (!m_collisionData) )
365
		return NULL;
366
 
367
	LPDIRECT3DTEXTURE9 texture;
368
	if ( FAILED (D3DXCreateTexture ( device, m_width, m_height, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture )) )
369
		return NULL;
370
 
371
    D3DSURFACE_DESC surfDesc;
372
	texture->GetLevelDesc( 0, &surfDesc );
373
 
374
	int h = surfDesc.Height;
375
 
376
    D3DLOCKED_RECT LockedRect;
377
    texture->LockRect( 0, &LockedRect, NULL, 0 );
378
 
379
    DWORD* pBits;
380
    for( DWORD iTexelZ=0; iTexelZ < surfDesc.Height; iTexelZ++ )
381
    {
382
        pBits = (DWORD*) ((BYTE*)LockedRect.pBits + (LockedRect.Pitch * iTexelZ));
383
 
384
        for( DWORD iTexelX = 0; iTexelX < surfDesc.Width; iTexelX++ )
385
        {
386
			int num = m_numData - ((iTexelZ * surfDesc.Width) + (surfDesc.Width - iTexelX));
387
 
388
			DWORD nAlpha = 0xFF;
389
			if ( m_collisionData[num] )
390
				nAlpha = 0x00;
391
 
392
            if( nRed > 0xFF )
393
                nRed = 0xFF;
394
            if( nGreen > 0xFF )
395
                nGreen = 0xFF;
396
            if( nBlue > 0xFF )
397
                nBlue = 0xFF;
398
            if( nAlpha > 0xFF )
399
                nAlpha = 0xFF;
400
 
401
            *pBits = (nAlpha << 24) + (nRed << 16) + (nGreen << 8) + (nBlue << 0);
402
            pBits++;
403
		}
404
	}
405
 
406
	texture->UnlockRect ( 0 );
407
 
408
	return texture;
409
}
410
#endif
411
 
412
bool CTextureFile::Save(const char *filename)
413
{
414
	// create header
415
	SFileHeader header;
416
 
417
	ClearHeader ( &header );
418
 
419
 
420
	// open file
421
	FILE *id;
422
#ifdef CY_USESECURE
423
	if ( fopen_s ( &id, filename, "wb" )  )
424
		return false;
425
#else
426
	if ( (id = fopen ( filename, "wb" )) == NULL )
427
		return false;
428
#endif
429
 
430
	// write version numbers (used incase header needs to change in later versions)
431
	float version = (float) TEXTUREFILE_VERSION;
432
	fwrite ( &version, sizeof ( float ), 1, id );
433
 
434
	// write header to file
435
	header.width		= m_width;
436
	header.height		= m_height;
437
	header.frames		= false;
438
	header.alpha		= m_alpha;
439
	header.alphamap[0]	= m_alphamap[0];
440
	header.alphamap[1]	= m_alphamap[1];
441
	header.alphamap[2]	= m_alphamap[2];
442
	if ( m_animNum )
443
		header.frames = true;
444
 
445
	fwrite ( &header, sizeof ( SFileHeader ), 1, id );
446
 
447
	// * Added since verison 1.20
448
	fwrite ( &m_collisionMap, sizeof ( bool ), 1, id );
449
 
450
	// write all the data
451
	fwrite ( m_data, sizeof ( STextureData ), m_numData, id );
452
 
453
	// write frames data
454
	fwrite ( &m_frames, sizeof ( STextureFrames ), 1, id );
455
 
456
	int animNum = 0;
457
	int i;
458
	for ( i = 0; i < m_animNum; i++ )
459
	{
460
		if ( !m_anim[i].remove )
461
			animNum++;
462
	}
463
	fwrite ( &animNum, sizeof ( int ), 1, id );
464
 
465
	SAnimation *anim;
466
	for ( i = 0; i < m_animNum; i++ )
467
	{
468
		anim = &m_anim[i];
469
 
470
		if ( !anim->remove )
471
		{
472
			int size = (int)strlen ( anim->name ) + 1;
473
			fwrite ( &size, sizeof ( int ), 1, id );
474
			fwrite ( anim->name, sizeof ( char ), size, id );
475
 
476
			fwrite ( &anim->amt, sizeof ( int ), 1, id );
477
			fwrite ( &anim->delay, sizeof ( int ), 1, id );
478
			fwrite ( &anim->cont, sizeof ( bool ), 1, id );
479
 
480
			fwrite ( anim->frames, sizeof ( int ), anim->amt, id );
481
		}
482
	}
483
 
484
	if ( m_collisionMap )
485
		fwrite ( m_collisionData, sizeof ( bool ), m_numData, id );
486
 
487
	fclose ( id );
488
 
489
	return true;
490
}
491
 
492
void CTextureFile::ClearHeader(SFileHeader *header)
493
{
494
	header->alpha = false;
495
	header->alphamap[0] = 0;
496
	header->alphamap[1] = 0;
497
	header->alphamap[2] = 0;
498
 
499
	header->frames = false;
500
	header->height = 0;
501
	header->width = 0;
502
}
503
 
504
bool CTextureFile::Load(const char *filename)
505
{
506
	// create header
507
	SFileHeader header;
508
	ClearHeader ( &header );
509
 
510
	// open file
511
	FILE *id;
512
#ifdef CY_USESECURE
513
	if ( fopen_s ( &id, filename, "rb" ) )
514
		return false;
515
#else
516
	if ( (id = fopen ( filename, "rb" )) == NULL )
517
		return false;
518
#endif
519
 
520
 
521
	// read version numbers (used incase header needs to change in later versions)
522
	float version;
523
	fread ( &version, sizeof ( float ), 1, id );
524
 
525
	if ( version < 1.00 )
526
		return false;
527
 
528
	// read header from file
529
	fread ( &header, sizeof ( SFileHeader ), 1, id );
530
	m_width			= header.width;
531
	m_height		= header.height;
532
	m_numData		= m_width * m_height;
533
	m_alpha			= header.alpha;
534
	m_alphamap[0]   = header.alphamap[0];
535
	m_alphamap[1]   = header.alphamap[1];
536
	m_alphamap[2]   = header.alphamap[2];
537
	m_alpha			= header.alpha;
538
 
539
	// * Added since version 1.20
540
	if ( version > 1.20 )
541
		fread ( &m_collisionMap, sizeof ( bool ), 1, id );
542
 
543
	// read all the data
544
	m_data = new STextureData[m_numData];	
545
 
546
	if ( fread ( m_data, sizeof ( STextureData ), m_numData, id ) != m_numData )
547
		return false;
548
 
549
 
550
	fread ( &m_frames, sizeof ( STextureFrames ), 1, id );
551
 
552
	if ( (version >= 1.1) && (header.frames) )
553
	{
554
		// read number of animations
555
		int fnum, size;
556
		fread ( &fnum, sizeof ( int ), 1, id );
557
 
558
		if ( m_anim )
559
		{
560
			if ( m_editor )
561
				free ( m_anim );
562
			else
563
				delete []m_anim;
564
		}
565
 
566
		if ( !fnum )
567
			m_anim = NULL;
568
		else
569
		{
570
			if ( m_editor )
571
				m_anim = (SAnimation *)malloc(sizeof ( SAnimation ) * fnum);
572
			else
573
				m_anim = new SAnimation[fnum];
574
		}
575
 
576
		SAnimation *anim;
577
		for ( int i = 0; i < fnum; i++ )
578
		{
579
			anim = &m_anim[i];
580
 
581
			fread ( &size, sizeof ( int ), 1, id );
582
			anim->name = new char[size];
583
			fread ( anim->name, sizeof ( char ), size, id );
584
 
585
			fread ( &anim->amt, sizeof ( int ), 1, id );
586
			fread ( &anim->delay, sizeof ( int ), 1, id );
587
			fread ( &anim->cont, sizeof ( bool ), 1, id );
588
			anim->remove = false;
589
			anim->frames = new int[anim->amt];
590
			fread ( anim->frames, sizeof ( int ), anim->amt, id );
591
		}
592
		m_animNum = fnum;
593
	}
594
 
595
	if ( m_collisionMap )
596
	{
597
		m_collisionData = new bool[m_numData];	
598
 
599
		if ( fread ( m_collisionData, sizeof ( bool ), m_numData, id ) != m_numData )
600
			return false;
601
	}
602
 
603
	fclose ( id );
604
 
605
	m_numframes = m_frames.x * m_frames.y;
606
	m_framebounds = new SFrameBounds[m_numframes];
607
 
608
	for ( int i = 0; i < m_numframes; i++ )
609
	{
610
		m_framebounds[i].minx = ComputeMinAlphaX ( i );
611
		m_framebounds[i].maxx = ComputeMaxAlphaX ( i );
612
		m_framebounds[i].miny = ComputeMinAlphaY ( i );
613
		m_framebounds[i].maxy = ComputeMaxAlphaY ( i );
614
	}
615
 
616
	return true;
617
}
618
 
619
void CTextureFile::SetFrameSize(int width, int height)
620
{
621
	m_frames.x = width;
622
	m_frames.y = height;
623
}
624
 
625
const STextureFrames *CTextureFile::GetFrames()
626
{
627
	return &m_frames;
628
}
629
 
630
int CTextureFile::GetFrameWidth()
631
{
632
	return m_frames.x;
633
}
634
 
635
int CTextureFile::GetFrameHeight()
636
{
637
 
638
	return m_frames.y;
639
}
640
 
641
void CTextureFile::SetFrames(int rows, int cols)
642
{
643
	m_frames.rows = rows;
644
	m_frames.cols = cols;
645
}
646
 
647
void CTextureFile::EnableAlphamap(bool enable)
648
{
649
	m_alpha = enable;
650
}
651
 
652
bool CTextureFile::GetAlphaMap()
653
{
654
	return m_alpha;
655
}
656
 
657
void CTextureFile::SetAlphaMap(int red, int green, int blue)
658
{
659
	m_alphamap[0] = red;
660
	m_alphamap[1] = green;
661
	m_alphamap[2] = blue;
662
}
663
 
664
bool CTextureFile::GetAlphaMap(int *red, int *green, int *blue)
665
{
666
	*red   = m_alphamap[0];
667
	*green = m_alphamap[1];
668
	*blue  = m_alphamap[2];
669
 
670
	return m_alpha;
671
}
672
 
673
SAnimation * CTextureFile::AddNewAnimation(const char *name)
674
{
675
	SAnimation *anim = NULL;
676
	// first, find if theres any free slots
677
	for ( int i = 0; i < m_animNum; i++ )
678
	{
679
		// found a free slot
680
		if ( m_anim[i].remove )
681
		{
682
			anim = &m_anim[i];
683
 
684
			// make sure old data is cleared before using
685
			if ( anim->frames )
686
				delete []anim->frames;
687
			if ( anim->name )
688
				delete []anim->name;
689
			break;
690
		}
691
	}
692
 
693
	// no free slot ? add a new one to the end of the array
694
	if ( !anim )
695
	{
696
		++m_animNum;
697
		m_anim = (SAnimation *)realloc(m_anim, sizeof ( SAnimation ) * m_animNum);
698
 
699
		anim = &m_anim[m_animNum - 1];
700
	}
701
 
702
	// set default data for animation
703
	anim->amt = 1;
704
	anim->frames = new int[1];
705
	anim->remove = false;
706
	anim->frames[0] = 1;
707
	anim->cont = false;
708
	anim->delay = 1;
709
	anim->name = new char[strlen (name) + 1];
710
#ifdef CY_USESECURE
711
	strcpy_s ( anim->name, strlen (name) + 1, name );
712
#else
713
	strcpy ( anim->name, name );
714
#endif
715
 
716
	// return pointer to created animation
717
	return anim;
718
}
719
 
720
int CTextureFile::GetAnimationNum()
721
{
722
	return m_animNum;
723
}	
724
 
725
SAnimation * CTextureFile::FindAnimation(const char *search)
726
{
727
	Utils::String sSearch(search);
728
 
729
	for ( int i = 0; i < m_animNum; i++ ) {
730
		if ( !m_anim[i].remove ) {
731
			if ( sSearch.Compare(m_anim[i].name) ) {
732
				return &m_anim[i];
733
			}
734
		}
735
	}
736
 
737
	return NULL;
738
}
739
 
740
SAnimation * CTextureFile::GetAnimation(int num)
741
{
742
	if ( (m_animNum < num) || (num < 0) )
743
		return NULL;
744
 
745
	return &m_anim[num];
746
}
747
 
748
void CTextureFile::SetEditor()
749
{
750
	m_editor = true;
751
}
752
 
753
 
754
void IncAnimationFrame ( SPlayAnimation *anim, int *times )
755
{
756
	IncAnimationFrame ( anim, false, times );
757
}
758
void IncAnimationFrame ( SPlayAnimation *anim, bool endstop, int *times )
759
{
760
	if ( !anim )
761
		return;
762
 
763
	if ( !anim->anim )
764
		return;
765
 
766
	++anim->delay;
767
 
768
	if ( anim->delay >= anim->anim->delay )
769
	{
770
		anim->delay = 0;
771
		++anim->curframe;
772
 
773
		if ( anim->curframe > anim->anim->amt )
774
		{
775
			if ( anim->anim->cont )
776
			{
777
				anim->curframe = 1;
778
				if ( times )
779
					++(*times);
780
			}
781
			else if ( endstop )
782
				--anim->curframe;
783
			else
784
				anim->anim = NULL;
785
		}
786
	}
787
}
788
void DecAnimationFrame ( SPlayAnimation *anim, int *times )
789
{
790
	DecAnimationFrame ( anim, false, times );
791
}
792
void DecAnimationFrame ( SPlayAnimation *anim, bool endstop, int *times )
793
{
794
	if ( !anim )
795
		return;
796
 
797
	if ( !anim->anim )
798
		return;
799
 
800
	++anim->delay;
801
 
802
	if ( anim->delay >= anim->anim->delay )
803
	{
804
		anim->delay = 0;
805
		--anim->curframe;
806
 
807
		if ( anim->curframe < 1 )
808
		{
809
			if ( anim->anim->cont )
810
			{
811
				anim->curframe = anim->anim->amt;
812
				if ( times )
813
					++(*times);
814
			}
815
			else if ( endstop )
816
				anim->curframe = 1;
817
			else
818
				anim->anim = NULL;
819
		}
820
	}
821
}
822
void ResetAnimation ( SPlayAnimation *anim )
823
{
824
	if ( !anim )
825
		return;
826
 
827
	anim->anim = NULL;
828
	anim->delay = 0;
829
	anim->curframe = 1;
830
	anim->reverse = false;
831
}
832
 
833
 
834
void DoAnimation ( SPlayAnimation *anim, bool endstopinc, bool endstopdec, int *times )
835
{
836
	if ( !anim )
837
		return;
838
 
839
	if ( anim->reverse )
840
		DecAnimationFrame ( anim, endstopdec, times );
841
	else
842
		IncAnimationFrame ( anim, endstopinc, times );
843
}
844
 
845
bool CTextureFile::CheckAlpha(int x, int y, int frame, bool inccollisionmap)
846
{
847
	int row = ((frame - 1) / m_frames.cols) + 1;
848
	int col = frame % m_frames.cols;
849
	if ( col == 0)
850
		col = m_frames.cols;
851
 
852
	int newx = ((col - 1) * m_frames.x) + x;
853
	int newy = ((row - 1) * m_frames.y) + y;
854
 
855
	int num = (newy * m_width) + newx;
856
	if ( (num < 0) || (num > (m_width * m_height)) )
857
		return false;
858
 
859
	if ( (inccollisionmap) && (m_collisionMap) && (m_collisionData) )
860
		return m_collisionData[num];
861
 
862
	int r = m_data[num].r;
863
	int g = m_data[num].g;
864
	int b = m_data[num].b;
865
	int a = m_data[num].alpha;
866
 
867
	if ( m_data[num].alpha == 0 )
868
		return true;
869
 
870
	if ( m_alpha )
871
	{
872
		if ( (m_data[num].r == m_alphamap[0]) && (m_data[num].g == m_alphamap[1]) && (m_data[num].b == m_alphamap[2]) )
873
			return true;
874
	}
875
 
876
	return false;
877
}
878
 
879
std::string CTextureFile::GetErrorText ( int error )
880
{
881
	switch ( error )
882
	{
883
		case TEXTURELOAD_OK:
884
			return "";
885
		case TEXTURELOAD_NOFILE:
886
			return "unable to open file";
887
		case TEXTURELOAD_SIZEMISMATCH:
888
			return "size mismatch";
889
		case TEXTURELOAD_INVALIDFORMAT:
890
			return "Invalid Format";
891
	}
892
	return "Unknown Error";
893
}
894
 
895
 
896
int CTextureFile::ComputeMinAlphaX ( int frame )
897
{
898
	for ( unsigned int x = 0; x < m_frames.x; x++ )
899
	{
900
		for ( unsigned int y = 0; y < m_frames.y; y++ )
901
		{
902
			if ( !CheckAlpha ( x, y, frame ) )
903
				return x;
904
 
905
		}
906
	}
907
	return 0;
908
}
909
 
910
int CTextureFile::ComputeMaxAlphaX ( int frame )
911
{
912
	for ( unsigned int x = m_frames.x - 1; x >= 0; x-- )
913
	{
914
		for ( unsigned int y = 0; y < m_frames.y; y++ )
915
		{
916
			if ( !CheckAlpha ( x, y, frame ) )
917
				return x;
918
 
919
		}
920
	}
921
	return m_frames.x - 1;
922
}
923
 
924
int CTextureFile::ComputeMinAlphaY ( int frame )
925
{
926
	for ( unsigned int y = 0; y < m_frames.y; y++ )
927
	{
928
		for ( unsigned int x = 0; x < m_frames.x; x++ )
929
		{
930
			if ( !CheckAlpha ( x, y, frame ) )
931
				return y;
932
 
933
		}
934
	}
935
	return 0;
936
}
937
 
938
int CTextureFile::ComputeMaxAlphaY ( int frame )
939
{
940
	for ( unsigned int y = m_frames.y - 1; y >= 0; y-- )
941
	{
942
		for ( unsigned int x = 0; x < m_frames.x; x++ )
943
		{
944
			if ( !CheckAlpha ( x, y, frame ) )
945
				return y;
946
 
947
		}
948
	}
949
	return m_frames.y - 1;
950
}