/******************************************************************************************
	CRTEST PS   (c) 1999-2001 ISL

	debris.h:			3D Sprite specal effects
******************************************************************************************/

#ifndef _DEBRIS_H_
#define _DEBRIS_H_

// values for masking into "flags.whole"
#define DEB_PRIORITY	1
#define DEB_MOVING		2
#define DEB_ANIMATING	4
#define DEB_COLORCHANGE	8
#define DEB_SPECIAL		16
#define DEB_SELFALPHA	32
#define DEB_TRUEALPHA	64

extern int	DEBRISDISTANCE;



enum								
{
	DEBRIS_FREE,		// 0
	DEBRIS_DUST,		// 1
	DEBRIS_SMOKE,		// 2
	DEBRIS_SMOKE2,		// 3
	DEBRIS_GRAVY,		// 4
	DEBRIS_GRAVYCHILD,	// 5
	DEBRIS_STEAM,		// 6
	DEBRIS_CANDLE,		// 7
	DEBRIS_SPLASH,		// 8
	DEBRIS_WATER,		// 9
	DEBRIS_WATERCHILD,	// 10
	DEBRIS_GENERIC_WATER, //11

	MAX_DEBRIS_TYPES
};

enum
{
	VENT_STEAM,
	VENT_CANDLE,
	VENT_WATER,
	VENT_GRAVY,
	MAX_VENT_TYPES
};

typedef struct _DEBRIS_FLAG_SUB_TYPE
{
	unsigned int priority:1;		// 1 is high
	unsigned int change_pos:1;
	unsigned int animating:1;
	unsigned int change_col:1;
	unsigned int special:1;
	unsigned int transp_type:2;
} DEBRIS_FLAG_SUB_TYPE;

typedef union _DEBRIS_FLAG_TYPE
{
	DEBRIS_FLAG_SUB_TYPE part;
	unsigned int whole;
} DEBRIS_FLAG_TYPE;

#define MAX_DEBRIS 100

typedef struct DEBRISSTR
{
	struct	DEBRISSTR *next;	// next free, or next active, deb

	DEBRIS_FLAG_TYPE flags;

	TextureType	*spr;
	short	x;			// world position
	short	y;
	short	z;
	short	dx;			// position deltas
	short	dy;
	short	dz;
	short	gravity;		// y-only acceleration


	unsigned int colour;	// plot colour

	unsigned int colour1;	// changing colours
	unsigned int colour2;

	short	size;			// scale value. default = 256
	short	dsize;

//	short	depthoffset;

	short	anim_frames;	// no of frames of animation in the sprite

	short	age_countdown;	// duration
	short	anim_start;		// value of "age_countdown" to animate from
	short	fade_start;		// value of "age_countdown" to start the colour fade

	short	lifetime;
	short	pad;

	union{
		struct{
			short rot1;
			short rot2;
			short rot1speed;
			short rot2speed;
		}smoke;
		struct{
			short height;
			short rot;
			short spare1;
			short spare2;
		}gravy;
		// CPW: put other special stuff in here
	}special;

	unsigned char type;		// so we can still do specials

}DEBRISSTR;

//VENT	*vents;

extern DEBRISSTR *debris;


// "flat" as in 3d-flat
#define P3DS_ADD	(0x20000000)
#define P3DS_SUB	(0x40000000)
#define P3DS_ADD2	(0x60000000)
#define P3DS_SEMI	(0x80000000)






/******************************************************************************************/

void debrisInit();
void debrisFree();

void debrisCycle();
void debrisDraw();

void debrisNewSmoke(VECTOR *pPos, TextureType *pT, short fadeStart, short lifeTime);


void	ventProccessAll(void);
/*
void debrisNewGravy(VECTOR *pPos, VECTOR *vel, TextureType *pT, short lifeTime ,short height);
void debrisNewGravySplash(VECTOR *pPos, VECTOR *vel, TextureType *pT, short lifeTime ,short height);
void debrisNewSteam(VECTOR *pPos, TextureType *pT, short fadeStart, short lifeTime);
void debrisNewSmoke2(VECTOR *pPos, TextureType *pT, short fadeStart, short lifeTime);
void debrisNewCandle(VECTOR *pPos, TextureType *pT, short fadeStart, short lifeTime);
*/

DEBRISSTR *debrisDust(VECTOR *pos, short lifeTime ,short size);

//void debrisNewGravy(VECTOR *pPos, VECTOR *vel, short lifeTime ,short height);
DEBRISSTR * debrisNewGravyChild(VECTOR *pPos, VECTOR *vel, short lifeTime ,short height);

//void debrisNewWater(VECTOR *pPos, VECTOR *vel, short lifeTime ,short height);
void debrisNewWaterChild(VECTOR *pPos, VECTOR *vel, short lifeTime ,short height);

//void debrisNewSteam(VECTOR *pPos, short fadeStart, short lifeTime);
typedef struct tag_VENT * VENTHANDLE;

void debrisNewSteam(VENTHANDLE	vent);
void debrisNewCandle(VENTHANDLE	vent);
void debrisNewWater(VENTHANDLE	vent);
void debrisNewGravy(VENTHANDLE	vent);

void debrisNewSmoke2(VECTOR *pPos, short fadeStart, short lifeTime);
//void debrisNewCandle(VECTOR *pPos, short fadeStart, short lifeTime);

void debrisNewWaterSplash(VECTOR *pos);
void debrisNewGenericWaterSplash(TextureType *tex, VECTOR *pos, int sizeStart, int sizeSpeed, int lifetime);



// DebrisNew will set off a solid sprite, immobile, at the specified position,
// with the specified lifetime, returning null if
// (a) there isn't a spare one.
// (b) the requested position is way offscreen & not worth bothering with.

// Check for null returns, and then set the animating/moving/colour-changing flags/values as required.
// Note - the values aren't initialised.

// eg - If you set the "change_pos" flag, you also need to initialise "dx,dy,dz,gravity",
// because they're not zeroed.

// For simple additive colour, set the colour to "P3DS_ADD | 0x808080"
// For fading, set "fade_start" = "lifetime", colour1 = starting colour, colour2 = ending colour
// (both need to include the "P3DS" value)

// Setting "transp_type" results in various flavours of alpha, using the top byte of the colour
// = 0...255

DEBRISSTR *debrisNew(VECTOR *pos, TextureType *spr, int lifetime);

unsigned int effectsGetPrimary(int hex, int dist, int pastel);

// high byte of colour is set from "0,""P3DS_ADD","P3DS_SUB","P3DS_SEMI"
int Print3DSprite(TextureType *spr,VERT *vect,SHORT scale, unsigned long colour);
int Print3DSpriteFlipped(TextureType *spr,VERT *vect,SHORT scale, unsigned long colour);

// The high byte of "colour" is used as the brightness (r=g=b) of the subtractive sprite
// The remaining 3 bytes are used as the colour of the additive
// Damping r,g,b down to (usually to match the alpha value) is left to the caller.
int	Print3DSelfAlphaSpriteRot(TextureType *spr,VERT *vect,SHORT scale, unsigned long colour, short rot);
int Print3DSelfAlphaSprite(TextureType *spr,VERT *vect,SHORT scale, unsigned long colour);
int Print3DPaletteAlphaSprite(TextureType *spr,VERT *vect,SHORT scale, unsigned long colour);
int Print3DAlphaChannelSprite(TextureType *spr,TextureType *sprM,VERT *vect,SHORT scale, unsigned long colour);

int Print3DPaletteAlphaSpriteRot(TextureType *spr,VERT *vect,SHORT scale, unsigned long colour, short rot);

void	cogChaseGravy(void);

VENTHANDLE 	ventFind(int tag);

void 	ventEnable(VENTHANDLE vent, int enable);
// Here's the defines for quick & easy functions
#define ventEnable(vent, enable) (vent)->flags = (enable);

#endif
