/*-----------------17/04/97 10:11-------------------

playstation FX by Dan, updated by Del...

// blasts&rings in ASM
// draw_fx_sprites in ASM
// do_rain_fx in ASM

--------------------------------------------------*/
#include "..\gamecode\machine.h"


char	splashshortatab[] = {	S_SPLASH1,
								S_SPLASH2,
								S_SPLASH3,
								S_SPLASH4,
								S_SPLASH5,
								S_SPLASH6,
								S_SPLASH7,
								S_SPLASH8,	FXSPRKILL } ;

char	splashmediumatab[] = { 	S_SPLASH1,S_SPLASH1,
								S_SPLASH2,S_SPLASH2,
								S_SPLASH3,S_SPLASH3,
								S_SPLASH4,S_SPLASH4,
								S_SPLASH5,S_SPLASH5,
								S_SPLASH6,S_SPLASH6,
								S_SPLASH7,S_SPLASH7,
								S_SPLASH8,S_SPLASH8,	FXSPRKILL } ;

char	splashlongatab[] = { 	S_SPLASH1,S_SPLASH1,S_SPLASH1,
								S_SPLASH2,S_SPLASH2,S_SPLASH2,
								S_SPLASH3,S_SPLASH3,S_SPLASH3,
								S_SPLASH4,S_SPLASH4,S_SPLASH4,
								S_SPLASH5,S_SPLASH5,S_SPLASH5,
								S_SPLASH6,S_SPLASH6,S_SPLASH6,
								S_SPLASH7,S_SPLASH7,S_SPLASH7,
								S_SPLASH8,S_SPLASH8,S_SPLASH8,	FXSPRKILL } ;


char	lightningstrikeatab[] = { 	S_LIGHT,NULLFXSPR,
									S_LIGHT,NULLFXSPR,
									S_LIGHT,NULLFXSPR,
									S_LIGHT,NULLFXSPR,
									S_LIGHT,NULLFXSPR,
									S_LIGHT,NULLFXSPR,
									S_LIGHT,NULLFXSPR,
									S_LIGHT,NULLFXSPR,
									S_LIGHT,NULLFXSPR,
									S_LIGHT,	FXSPRKILL } ;

char	sparkleatab[] = { 		S_SPARKLE1,S_SPARKLE2,
								S_SPARKLE3,S_SPARKLE4,
								S_SPARKLE3,S_SPARKLE4,
								S_SPARKLE3,S_SPARKLE2,
								S_SPARKLE1,		FXSPRKILL } ;

char	explode1atab[] = {		S_EXPLODE1,S_EXPLODE2,S_EXPLODE3,S_EXPLODE4,
								S_EXPLODE5,S_EXPLODE6,S_EXPLODE7,S_EXPLODE8,
								S_EXPLODE9,S_EXPLODE10,S_EXPLODE11,S_EXPLODE12,
								S_EXPLODE13,S_EXPLODE14,S_EXPLODE15,S_EXPLODE16,	FXSPRKILL } ;


char	explode4atab[] = {		S_EXPLODE1,S_EXPLODE2,S_EXPLODE3,S_EXPLODE4,
								S_EXPLODE5,S_EXPLODE6,S_EXPLODE7,S_EXPLODE8,
								FXSPRKILL } ;


// same as above, half the frames...!
char	explode2atab[] = {		S_EXPLODE1,S_EXPLODE3,
								S_EXPLODE5,S_EXPLODE7,
								S_EXPLODE9,S_EXPLODE11,
								S_EXPLODE13,S_EXPLODE15,	FXSPRKILL } ;
// a bit extended...!
char	explode3atab[] = {		S_EXPLODE1,S_EXPLODE2,S_EXPLODE3,S_EXPLODE4,
								S_EXPLODE5,S_EXPLODE6,S_EXPLODE7,S_EXPLODE8,
								S_EXPLODE9,S_EXPLODE10,S_EXPLODE11,S_EXPLODE12,
								S_EXPLODE13,S_EXPLODE14,S_EXPLODE15,S_EXPLODE16,S_EXPLODE15,S_EXPLODE16,S_EXPLODE15,S_EXPLODE16,S_EXPLODE15,S_EXPLODE16,S_EXPLODE15,S_EXPLODE16,	FXSPRKILL } ;




char	score100atab[] = {
							FXSPRCOL,128,64,64,		S_100,			FXSPRCOL,128,128,64,	S_100,
							FXSPRCOL,128,64,64,		S_100,			FXSPRCOL,128,128,64,	S_100,
							FXSPRCOL,128,64,64,		S_100,			FXSPRCOL,128,128,64,	S_100,
							FXSPRCOL,128,64,64,		S_100,			FXSPRCOL,128,128,64,	S_100,
							FXSPRCOL,128,64,64,		S_100,			FXSPRCOL,128,128,64,	S_100,
							FXSPRCOL,128,64,64,		S_100,			FXSPRCOL,128,128,64,	S_100,
							FXSPRCOL,128,64,64,		S_100,			FXSPRCOL,128,128,64,	S_100,
							FXSPRCOL,128,64,64,		S_100,			FXSPRCOL,128,128,64,	S_100,
							FXSPRCOL,128,64,64,		S_100,			FXSPRCOL,128,128,64,	S_100,
							FXSPRCOL,128,64,64,		S_100,			FXSPRCOL,128,128,64,	S_100,
							FXSPRCOL,128,64,64,		S_100,			FXSPRCOL,128,128,64,	S_100,
							FXSPRCOL,128,64,64,		S_100,			FXSPRCOL,128,128,64,	S_100,		FXSPRKILL } ;

char	score250atab[] = {
							FXSPRCOL,128,64,64,		S_250,			FXSPRCOL,128,128,64,	S_250,
							FXSPRCOL,128,64,64,		S_250,			FXSPRCOL,128,128,64,	S_250,
							FXSPRCOL,128,64,64,		S_250,			FXSPRCOL,128,128,64,	S_250,
							FXSPRCOL,128,64,64,		S_250,			FXSPRCOL,128,128,64,	S_250,
							FXSPRCOL,128,64,64,		S_250,			FXSPRCOL,128,128,64,	S_250,
							FXSPRCOL,128,64,64,		S_250,			FXSPRCOL,128,128,64,	S_250,
							FXSPRCOL,128,64,64,		S_250,			FXSPRCOL,128,128,64,	S_250,
							FXSPRCOL,128,64,64,		S_250,			FXSPRCOL,128,128,64,	S_250,
							FXSPRCOL,128,64,64,		S_250,			FXSPRCOL,128,128,64,	S_250,
							FXSPRCOL,128,64,64,		S_250,			FXSPRCOL,128,128,64,	S_250,
							FXSPRCOL,128,64,64,		S_250,			FXSPRCOL,128,128,64,	S_250,
							FXSPRCOL,128,64,64,		S_250,			FXSPRCOL,128,128,64,	S_250,		FXSPRKILL } ;


char	score500atab[] = {
							FXSPRCOL,128,64,64,		S_500,			FXSPRCOL,128,128,64,	S_500,
							FXSPRCOL,128,64,64,		S_500,			FXSPRCOL,128,128,64,	S_500,
							FXSPRCOL,128,64,64,		S_500,			FXSPRCOL,128,128,64,	S_500,
							FXSPRCOL,128,64,64,		S_500,			FXSPRCOL,128,128,64,	S_500,
							FXSPRCOL,128,64,64,		S_500,			FXSPRCOL,128,128,64,	S_500,
							FXSPRCOL,128,64,64,		S_500,			FXSPRCOL,128,128,64,	S_500,
							FXSPRCOL,128,64,64,		S_500,			FXSPRCOL,128,128,64,	S_500,
							FXSPRCOL,128,64,64,		S_500,			FXSPRCOL,128,128,64,	S_500,
							FXSPRCOL,128,64,64,		S_500,			FXSPRCOL,128,128,64,	S_500,
							FXSPRCOL,128,64,64,		S_500,			FXSPRCOL,128,128,64,	S_500,
							FXSPRCOL,128,64,64,		S_500,			FXSPRCOL,128,128,64,	S_500,
							FXSPRCOL,128,64,64,		S_500,			FXSPRCOL,128,128,64,	S_500,		FXSPRKILL };


char	score1000atab[] = {
							FXSPRCOL,128,64,64,		S_1000,			FXSPRCOL,128,128,64,	S_1000,
							FXSPRCOL,128,64,64,		S_1000,			FXSPRCOL,128,128,64,	S_1000,
							FXSPRCOL,128,64,64,		S_1000,			FXSPRCOL,128,128,64,	S_1000,
							FXSPRCOL,128,64,64,		S_1000,			FXSPRCOL,128,128,64,	S_1000,
							FXSPRCOL,128,64,64,		S_1000,			FXSPRCOL,128,128,64,	S_1000,
							FXSPRCOL,128,64,64,		S_1000,			FXSPRCOL,128,128,64,	S_1000,
							FXSPRCOL,128,64,64,		S_1000,			FXSPRCOL,128,128,64,	S_1000,
							FXSPRCOL,128,64,64,		S_1000,			FXSPRCOL,128,128,64,	S_1000,
							FXSPRCOL,128,64,64,		S_1000,			FXSPRCOL,128,128,64,	S_1000,
							FXSPRCOL,128,64,64,		S_1000,			FXSPRCOL,128,128,64,	S_1000,
							FXSPRCOL,128,64,64,		S_1000,			FXSPRCOL,128,128,64,	S_1000,
							FXSPRCOL,128,64,64,		S_1000,			FXSPRCOL,128,128,64,	S_1000,		FXSPRKILL };

char	score2500atab[] = {
							FXSPRCOL,128,64,64,		S_2500,			FXSPRCOL,128,128,64,	S_2500,
							FXSPRCOL,128,64,64,		S_2500,			FXSPRCOL,128,128,64,	S_2500,
							FXSPRCOL,128,64,64,		S_2500,			FXSPRCOL,128,128,64,	S_2500,
							FXSPRCOL,128,64,64,		S_2500,			FXSPRCOL,128,128,64,	S_2500,
							FXSPRCOL,128,64,64,		S_2500,			FXSPRCOL,128,128,64,	S_2500,
							FXSPRCOL,128,64,64,		S_2500,			FXSPRCOL,128,128,64,	S_2500,
							FXSPRCOL,128,64,64,		S_2500,			FXSPRCOL,128,128,64,	S_2500,
							FXSPRCOL,128,64,64,		S_2500,			FXSPRCOL,128,128,64,	S_2500,
							FXSPRCOL,128,64,64,		S_2500,			FXSPRCOL,128,128,64,	S_2500,
							FXSPRCOL,128,64,64,		S_2500,			FXSPRCOL,128,128,64,	S_2500,
							FXSPRCOL,128,64,64,		S_2500,			FXSPRCOL,128,128,64,	S_2500,
							FXSPRCOL,128,64,64,		S_2500,			FXSPRCOL,128,128,64,	S_2500,		FXSPRKILL };

char	score5000atab[] = {
							FXSPRCOL,128,64,64,		S_5000,			FXSPRCOL,128,128,64,	S_5000,
							FXSPRCOL,128,64,64,		S_5000,			FXSPRCOL,128,128,64,	S_5000,
							FXSPRCOL,128,64,64,		S_5000,			FXSPRCOL,128,128,64,	S_5000,
							FXSPRCOL,128,64,64,		S_5000,			FXSPRCOL,128,128,64,	S_5000,
							FXSPRCOL,128,64,64,		S_5000,			FXSPRCOL,128,128,64,	S_5000,
							FXSPRCOL,128,64,64,		S_5000,			FXSPRCOL,128,128,64,	S_5000,
							FXSPRCOL,128,64,64,		S_5000,			FXSPRCOL,128,128,64,	S_5000,
							FXSPRCOL,128,64,64,		S_5000,			FXSPRCOL,128,128,64,	S_5000,
							FXSPRCOL,128,64,64,		S_5000,			FXSPRCOL,128,128,64,	S_5000,
							FXSPRCOL,128,64,64,		S_5000,			FXSPRCOL,128,128,64,	S_5000,
							FXSPRCOL,128,64,64,		S_5000,			FXSPRCOL,128,128,64,	S_5000,
							FXSPRCOL,128,64,64,		S_5000,			FXSPRCOL,128,128,64,	S_5000,		FXSPRKILL };

char	score10000atab[] = {
							FXSPRCOL,128,64,64,		S_10000,		FXSPRCOL,128,128,64,	S_10000,
							FXSPRCOL,128,64,64,		S_10000,		FXSPRCOL,128,128,64,	S_10000,
							FXSPRCOL,128,64,64,		S_10000,		FXSPRCOL,128,128,64,	S_10000,
							FXSPRCOL,128,64,64,		S_10000,		FXSPRCOL,128,128,64,	S_10000,
							FXSPRCOL,128,64,64,		S_10000,		FXSPRCOL,128,128,64,	S_10000,
							FXSPRCOL,128,64,64,		S_10000,		FXSPRCOL,128,128,64,	S_10000,
							FXSPRCOL,128,64,64,		S_10000,		FXSPRCOL,128,128,64,	S_10000,
							FXSPRCOL,128,64,64,		S_10000,		FXSPRCOL,128,128,64,	S_10000,
							FXSPRCOL,128,64,64,		S_10000,		FXSPRCOL,128,128,64,	S_10000,
							FXSPRCOL,128,64,64,		S_10000,		FXSPRCOL,128,128,64,	S_10000,
							FXSPRCOL,128,64,64,		S_10000,		FXSPRCOL,128,128,64,	S_10000,
							FXSPRCOL,128,64,64,		S_10000,		FXSPRCOL,128,128,64,	S_10000,	FXSPRKILL };


char	oneupatab[] = {
							FXSPRCOL,128,64,64,		S_1UP,			FXSPRCOL,64,128,64,		S_1UP,
							FXSPRCOL,64,64,128,		S_1UP,			FXSPRCOL,128,128,128,	S_1UP,
							FXSPRCOL,128,64,64,		S_1UP,			FXSPRCOL,64,128,64,		S_1UP,
							FXSPRCOL,64,64,128,		S_1UP,			FXSPRCOL,128,128,128,	S_1UP,
							FXSPRCOL,128,64,64,		S_1UP,			FXSPRCOL,64,128,64,		S_1UP,
							FXSPRCOL,64,64,128,		S_1UP,			FXSPRCOL,128,128,128,	S_1UP,
							FXSPRCOL,128,64,64,		S_1UP,			FXSPRCOL,64,128,64,		S_1UP,
							FXSPRCOL,64,64,128,		S_1UP,			FXSPRCOL,128,128,128,	S_1UP,
							FXSPRCOL,128,64,64,		S_1UP,			FXSPRCOL,64,128,64,		S_1UP,
							FXSPRCOL,64,64,128,		S_1UP,			FXSPRCOL,128,128,128,	S_1UP,
							FXSPRCOL,128,64,64,		S_1UP,			FXSPRCOL,64,128,64,		S_1UP,
							FXSPRCOL,64,64,128,		S_1UP,			FXSPRCOL,128,128,128,	S_1UP,
							FXSPRCOL,128,64,64,		S_1UP,			FXSPRCOL,64,128,64,		S_1UP,
							FXSPRCOL,64,64,128,		S_1UP,			FXSPRCOL,128,128,128,	S_1UP,		FXSPRKILL };

char	burnatab[] = 	{ S_BURN,FXSPRKILL } ;


char	knifespratab[] = {
							FXSPRCOL,32,64,128,		S_LIGHT,
							FXSPRCOL,24,48,96,		S_LIGHT,
							FXSPRCOL,16,32,64,		S_LIGHT,
							FXSPRCOL,8,16,32,		S_LIGHT,
							FXSPRCOL,0,8,16,		S_LIGHT,		FXSPRKILL };

char	lanternatab[] = { 	S_LIGHT,	FXSPRKILL } ;

char	lightatab[] = {		S_LIGHT,FXSPRKILL } ;
char	flareatab[] = {		S_FLARE,FXSPRKILL } ;


char	swordflareatab[] = {
							FXSPRCOL,64,128,255,	FXSPRROTADD,8,	S_FLARE,
							FXSPRCOL,48,96,192,		FXSPRROTADD,8,	S_FLARE,
							FXSPRCOL,32,64,128,		FXSPRROTADD,8,	S_FLARE,
							FXSPRCOL,32,64,128,		FXSPRROTADD,8,	S_FLARE,
							FXSPRCOL,16,32,64,		FXSPRROTADD,8,	S_FLARE,
							FXSPRCOL,8,16,32,		FXSPRROTADD,8,	S_FLARE,
							FXSPRCOL,4,8,16,		FXSPRROTADD,8,	S_FLARE,
							FXSPRCOL,2,4,8,			FXSPRROTADD,8,	S_FLARE,
							FXSPRKILL };

char	swordflare2atab[] = {
							FXSPRCOL,255,128,64,	S_LIGHT,
							FXSPRCOL,192,96,48,		S_LIGHT,
							FXSPRCOL,128,64,32,		S_LIGHT,
							FXSPRCOL,128,64,32,		S_LIGHT,
							FXSPRCOL,64,32,16,		S_LIGHT,
							FXSPRCOL,32,16,8,		S_LIGHT,
							FXSPRCOL,16,8,4,		S_LIGHT,
							FXSPRCOL,8,4,2,			S_LIGHT,		FXSPRKILL };


char	kickflareatab[] = {
							FXSPRCOL,255,255,255,	S_LIGHT,
							FXSPRCOL,255,255,128,	S_LIGHT,
							FXSPRCOL,128,128,64,	S_LIGHT,
							FXSPRCOL,128,64,0,		S_LIGHT,
							FXSPRCOL,64,32,0,		S_LIGHT,
							FXSPRCOL,32,0,0,		S_LIGHT,
							FXSPRCOL,16,0,0,		S_LIGHT,		FXSPRKILL };

char	kickflare2atab[] = {
							FXSPRCOL,255,255,0,		FXSPRROTADD,8,	S_FLARE,
							FXSPRCOL,255,64,0,		FXSPRROTADD,8,	S_FLARE,
							FXSPRCOL,128,32,0	,	FXSPRROTADD,8,	S_FLARE,
							FXSPRCOL,64,16,0,		FXSPRROTADD,8,	S_FLARE,
							FXSPRCOL,32,8,0,		FXSPRROTADD,8,	S_FLARE,
							FXSPRCOL,16,4,0,		FXSPRROTADD,8,	S_FLARE,
							FXSPRCOL,8,0,0,			FXSPRROTADD,8,	S_FLARE,		FXSPRKILL };

char	enemyflareatab[] = {
							FXSPRCOL,255,255,0,		S_LIGHT,
							FXSPRCOL,255,64,0,		S_LIGHT,
							FXSPRCOL,128,32,0,		S_LIGHT,
							FXSPRCOL,64,16,0,		S_LIGHT,
							FXSPRCOL,32,8,0,		S_LIGHT,
							FXSPRCOL,16,4,0,		S_LIGHT,
							FXSPRCOL,8,0,0,			S_LIGHT,		FXSPRKILL };

char	enemyflare2atab[] = {
							FXSPRCOL,255,255,255,	FXSPRROTADD,8,	S_FLARE,
							FXSPRCOL,255,128,255,	FXSPRROTADD,8,	S_FLARE,
							FXSPRCOL,128,64,128,	FXSPRROTADD,8,	S_FLARE,
							FXSPRCOL,64,32,128,		FXSPRROTADD,8,	S_FLARE,
							FXSPRCOL,32,16,64,		FXSPRROTADD,8,	S_FLARE,
							FXSPRCOL,16,8,32,		FXSPRROTADD,8,	S_FLARE,
							FXSPRCOL,8,0,16,		FXSPRROTADD,8,	S_FLARE,		FXSPRKILL };

char	knifeflareatab[] = {
							FXSPRCOL,255,255,255,	S_LIGHT,
							FXSPRCOL,255,255,128,	S_LIGHT,
							FXSPRCOL,128,128,64,	S_LIGHT,
							FXSPRCOL,128,64,0,		S_LIGHT,
							FXSPRCOL,64,32,0,		S_LIGHT,
							FXSPRCOL,32,0,0,		S_LIGHT,
							FXSPRCOL,16,0,0,		S_LIGHT,		FXSPRKILL };

char	chestflareatab[] = {
							FXSPRCOL,255,127,127,	FXSPRROTADD,8,	S_FLARE,
							FXSPRCOL,224,96,96,		FXSPRROTADD,8,	S_FLARE,
							FXSPRCOL,192,64,64,		FXSPRROTADD,8,	S_FLARE,
							FXSPRCOL,176,48,48,		FXSPRROTADD,8,	S_FLARE,
							FXSPRCOL,160,32,32,		FXSPRROTADD,8,	S_FLARE,
							FXSPRCOL,144,24,24,		FXSPRROTADD,8,	S_FLARE,
							FXSPRCOL,128,16,16,		FXSPRROTADD,8,	S_FLARE,
							FXSPRCOL,120,0,16,		FXSPRROTADD,8,	S_FLARE,
							FXSPRCOL,112,0,16,		FXSPRROTADD,8,	S_FLARE,
							FXSPRCOL,104,0,16,		FXSPRROTADD,8,	S_FLARE,
							FXSPRCOL,96,0,8,		FXSPRROTADD,8,	S_FLARE,
							FXSPRCOL,88,0,8,		FXSPRROTADD,8,	S_FLARE,
							FXSPRCOL,80,0,8,		FXSPRROTADD,8,	S_FLARE,
							FXSPRCOL,72,0,8,		FXSPRROTADD,8,	S_FLARE,
							FXSPRCOL,64,0,8,		FXSPRROTADD,8,	S_FLARE,
							FXSPRCOL,56,0,8,		FXSPRROTADD,8,	S_FLARE,
							FXSPRCOL,48,0,8,		FXSPRROTADD,8,	S_FLARE,
							FXSPRCOL,40,0,8,		FXSPRROTADD,8,	S_FLARE,
							FXSPRCOL,32,0,8,		FXSPRROTADD,8,	S_FLARE,
							FXSPRCOL,24,0,8,		FXSPRROTADD,8,	S_FLARE,
							FXSPRCOL,16,0,8,		FXSPRROTADD,8,	S_FLARE,
							FXSPRCOL,8,0,8,			FXSPRROTADD,8,	S_FLARE,
							FXSPRKILL };

char	restartatab[] = { S_FLARE,FXSPRKILL } ;

char	blockflareatab[] = {
							FXSPRCOL,255,255,255,	S_LIGHT,
							FXSPRCOL,64,255,64,	S_LIGHT,
							FXSPRCOL,32,128,32,		S_LIGHT,
							FXSPRCOL,16,64,16,		S_LIGHT,
							FXSPRCOL,8,32,8,		S_LIGHT,
							FXSPRCOL,0,16,0,		S_LIGHT,
							FXSPRCOL,0,8,0,			S_LIGHT,		FXSPRKILL };


static	long	RGB_Fade_Count ;
static	long	RGB_Fade_Rate ;
static	long	RGB_Fade_Accel ;
static	long	Flash_Fade_Count ;
static	long	Flash_Fade_Rate ;
static	long	Flash_Fade_Accel ;

static	uchar	GlobalFadeR ;
static	uchar	GlobalFadeG ;
static	uchar	GlobalFadeB ;
static	uchar	LastR ;
static	uchar	LastG ;
static	uchar	LastB ;
static	uchar	FlashR ;
static	uchar	FlashG ;
static	uchar	FlashB ;
static	uchar	FlashFadeR ;
static	uchar	FlashFadeG ;
static	uchar	FlashFadeB ;

uchar	GlobStoreR ;
uchar	GlobStoreG ;
uchar	GlobStoreB ;
uchar	GlobalR ;
uchar	GlobalG ;
uchar	GlobalB ;
long 	GlobalRGB ;

void		init_global_colours(uchar dR,uchar dG,uchar dB)
{
	GlobalR = dR ;
	GlobalG = dG ;
	GlobalB = dB ;
	GlobalRGB = (GlobalR<<0)+(GlobalG<<8)+(GlobalB<<16) ;
	RGB_Fade_Count = -1 ;
}

void		set_fade_global_colours(uchar dR,uchar dG,uchar dB,long	faderate,long accel)
{
	GlobalFadeR = dR ;
	GlobalFadeG = dG ;
	GlobalFadeB = dB ;
	LastR = GlobalR ;
	LastG = GlobalG ;
	LastB = GlobalB ;
	RGB_Fade_Count = 0 ;
	RGB_Fade_Rate = faderate ;
	RGB_Fade_Accel = accel ;
}


void		fade_global_colours(void)
{
long	r,g,b ;

	if ( RGB_Fade_Count == -1 )				// No Fading??   Then Return ......
		return ;

	r = (GlobalFadeR-LastR) ;
	g = (GlobalFadeG-LastG) ;
	b =	(GlobalFadeB-LastB) ;

	GlobalR = LastR+((r*RGB_Fade_Count)>>16)  ;
	GlobalG = LastG+((g*RGB_Fade_Count)>>16)  ;
	GlobalB = LastB+((b*RGB_Fade_Count)>>16)  ;
	GlobalRGB = (GlobalR<<0)+(GlobalG<<8)+(GlobalB<<16) ;

	RGB_Fade_Count += RGB_Fade_Rate ;
	RGB_Fade_Rate += RGB_Fade_Accel ;

	if ( RGB_Fade_Count >= 0x10000 )
	{
		GlobalR = GlobalFadeR ;
		GlobalG = GlobalFadeG ;
		GlobalB = GlobalFadeB ;
		GlobalRGB = (GlobalR<<0)+(GlobalG<<8)+(GlobalB<<16) ;
		RGB_Fade_Count = -1 ;
	}

// frig me
//	GlobalRGB=0x0000ff;
//	GlobalR=0xff;
//	GlobalG=0;
//	GlobalB=0;



}


void		init_flash_colours(uchar dR,uchar dG,uchar dB)
{
	FlashR = dR ;
	FlashG = dG ;
	FlashB = dB ;
	Flash_Fade_Count = -1 ;
}

void		set_flash_colours(uchar dR,uchar dG,uchar dB,long	faderate,long accel)
{
	FlashFadeR = dR ;
	FlashFadeG = dG ;
	FlashFadeB = dB ;
	Flash_Fade_Count = 0 ;
	Flash_Fade_Rate = faderate ;
	Flash_Fade_Accel = accel ;
}

void		fade_flash_colours(void)
{
long	invflash ;

	if ( Flash_Fade_Count == -1 )
		return ;

	invflash = (65536-Flash_Fade_Count)  ;

	FlashR = (FlashFadeR*invflash)>>16  ;
	FlashG = (FlashFadeG*invflash)>>16  ;
	FlashB = (FlashFadeB*invflash)>>16  ;

	Flash_Fade_Count += Flash_Fade_Rate ;
	Flash_Fade_Rate += Flash_Fade_Accel ;

	ps_drawtpage = (DR_TPAGE *)primlistptr;
	setDrawTPage(ps_drawtpage,0,GAME_DITHER_FLAG,(1<<5));		//(tpages[COLOURADD]) ;
	primlistptr += sizeof(DR_TPAGE);

	ps_tile = (TILE *)primlistptr;
	primlistptr += sizeof(TILE);

	setTile(ps_tile);
	ps_tile->x0 = 0;
	ps_tile->y0 = 0;
	ps_tile->w = 320;
	ps_tile->h = 240;
	setRGB0(ps_tile,FlashR,FlashG,FlashB);
	setSemiTrans(ps_tile,1) ;


// lets margeprim the cunts! (added by Del 17/04/97)
	margePrim(ps_drawtpage,ps_tile);
	addPrim( (u_long *)curr_ot ,(u_long *)ps_drawtpage );

	if ( Flash_Fade_Count >= 0x10000 )
	{
		FlashR = 0 ;
		FlashG = 0 ;
		FlashB = 0 ;
		Flash_Fade_Count = -1 ;
	}
}

/*-----------------17/04/97 10:22-------------------
 this is the spark stuff...
--------------------------------------------------*/
static	long	next_spark ;

SPARK	spark_table[MAXSPARKS] ;

void		init_sparks(void)
{
long	lp ;

	next_spark = 0 ;
	for ( lp=0 ; lp<MAXSPARKS ; lp++ )
		spark_table[lp].sparkon = 0 ;
}



// 30 params!!!! jesus H!

//*														startsize,   	  Endsize,          Start RGB                           End RGB           COLORMODE     gravity    num points  Z adjust  dist origin rand


void		insert_spark(long life,long x,long y,long z,long wh,long srgb,long drgb,uchar colmode,short grav,uchar nodes,long zadd,long ox1,long ox2,long oy1,long oy2,long oz1,long oz2,long xv,long yv,long zv,long xvr,long yvr,long zvr)
{
long	lp ;
SPARK	*sptr ;
SPARKPT	*pptr ;

	sptr = &spark_table[next_spark] ;

	sptr->sparkon = 1 ;
	sptr->sparklife = 1<<life ;
	sptr->sparkshift = life ;
	sptr->sparkx = x ;
	sptr->sparky = y ;
	sptr->sparkz = z ;
	sptr->sparksw = wh ;
	sptr->sparksh = wh>>8 ;
	sptr->sparkdw = wh>>16 ;
	sptr->sparkdh = wh>>24 ;

	sptr->sparksr = srgb ;
	sptr->sparksg = srgb>>8 ;
	sptr->sparksb = srgb>>16 ;
	sptr->sparkdr = drgb ;
	sptr->sparkdg = drgb>>8 ;
	sptr->sparkdb = drgb>>16 ;

	sptr->sparkcolmode = colmode ;
	sptr->sparkgrav = grav ;
	sptr->sparknodes = nodes ;
	sptr->sparkzadd = zadd ;

	pptr = sptr->sparks ;
	for (lp = 0 ; lp<sptr->sparknodes ; lp++ )
	{
		pptr->sparkptx = (drand()&ox1)+ox2 ;
		pptr->sparkpty = (drand()&oy1)+oy2 ;
		pptr->sparkptz = (drand()&oz1)+oz2 ;

		pptr->sparkptxv = xv + (drand()&xvr) - (xvr>>1)  ;
		pptr->sparkptyv = yv + (drand()&yvr) - (yvr>>1)  ;
		pptr->sparkptzv = zv + (drand()&zvr) - (zvr>>1)  ;
		pptr++ ;
	}
	next_spark++ ;
	next_spark %= MAXSPARKS ;
}


#ifndef	USE_DELS_ASM


void		process_sparks(void)
{
long	slp,lp ;
uchar	r,g,b ;
long	rgb ;
long 	*sxy ;
long	*sz ;
long	wh,w,h ;
long	grav ;
short	xv,yv,zv ;
SPARK	*sptr ;
SPARKPT	*pptr ;
SVECTOR	*sv ;
TILE	*spark_tile ;

	sptr = &spark_table[0] ;

	sv = (SVECTOR *)((char *)DCACHE_BASE+0) ;
	sz = (long *)((char *)DCACHE_BASE+8) ;
	sxy = (long *)((char *)DCACHE_BASE+16) ;

	for ( slp=0 ; slp<MAXSPARKS ; slp++ )
	{
		if ( sptr->sparkon == 1 )
		{
			slPushMatrix();
			slTranslate(sptr->sparkx,sptr->sparky,sptr->sparkz);

			sv->vx = 0 ;
			sv->vy = 0 ;
			sv->vz = 0 ;
	   		gte_ldv0(sv);
 	   		gte_rtps();
			gte_stszotz(sz);

			if ( *sz >= 0 )
			{
				*sz = (*sz>>2)+sptr->sparkzadd ;
				if ( *sz > 2047 )
					*sz = 2047 ;
				if ( *sz < 0 )
					*sz = 0 ;

				r = sptr->sparkdr+(((sptr->sparksr-sptr->sparkdr)*sptr->sparklife)>>sptr->sparkshift);
				g = sptr->sparkdg+(((sptr->sparksg-sptr->sparkdg)*sptr->sparklife)>>sptr->sparkshift);
				b = sptr->sparkdb+(((sptr->sparksb-sptr->sparkdb)*sptr->sparklife)>>sptr->sparkshift);

				rgb = r+(g<<8)+(b<<16)+((0x60+0x02)<<24) ;

				w = sptr->sparkdw+(((sptr->sparksw-sptr->sparkdw)*sptr->sparklife)>>sptr->sparkshift);
				h = sptr->sparkdh+(((sptr->sparksh-sptr->sparkdh)*sptr->sparklife)>>sptr->sparkshift);

				wh = w+(h<<16) ;
				w >>= 1 ;
				h >>= 1 ;
				w = w+(h<<16) ;

				grav = sptr->sparkgrav ;

				lp = sptr->sparknodes ;

				spark_tile = (TILE *)primlistptr;
				primlistptr += sizeof(TILE)*lp;
				pptr = sptr->sparks ;

				while ( lp>0 )
				{
	   				gte_ldv0( (SVECTOR *)pptr );
 	   				gte_rtps();

					*(long *)(&spark_tile->r0) = rgb;
					*(long *)(&spark_tile->w) = wh;
					setlen(spark_tile, 3) ;
					lp-- ;

					xv = pptr->sparkptxv ;
					yv = pptr->sparkptyv ;
					zv = pptr->sparkptzv ;
				   	pptr->sparkptx += xv ;
					pptr->sparkpty += yv ;
					pptr->sparkptz += zv ;
					pptr->sparkptzv = zv+grav ;

					gte_stsxy(sxy);
					*(long *)(&spark_tile->x0) = (*sxy)-w ;
					addPrim( (u_long *)curr_ot+(*sz) ,(u_long *)spark_tile );
					spark_tile++ ;
					pptr++ ;
				}

				ps_drawtpage = (DR_TPAGE *)primlistptr;
				primlistptr += sizeof(DR_TPAGE);
				setDrawTPage(ps_drawtpage,0,GAME_DITHER_FLAG,tpages[sptr->sparkcolmode]) ;
				addPrim( (u_long *)curr_ot+(*sz) ,(u_long *)ps_drawtpage );
			}

			sptr->sparklife-- ;
			if ( sptr->sparklife == 0 )
				sptr->sparkon = 0 ;

			slPopMatrix();
		}
		sptr++ ;
	}
}

#endif


/*-----------------17/04/97 10:22-------------------
 this is the rain stuff...
--------------------------------------------------*/
short	weatherfx_table[2048] ;

void	init_rain_fx(void)
{
long	lp ;
short	*rptr ;

	rptr = &weatherfx_table[0] ;
	for ( lp=0 ; lp<512 ; lp++ )
	{
		*rptr++ = random()%SCRXSZ ;
		*rptr++ = random()%SCRYSZ ;
		*rptr++ = (lp>>6)+10+(random()%((lp>>6)+4)) ;
	}


	rainno = 0 ;
	rainflip = 0 ;
	rainmode = -1 ;
	rainsoundon = 0 ;
	rainvolume = 0 ;

}

#ifndef	USE_DELS_ASM
void	do_rain_fx(long	raintype)
{
long	lp ;
short	*rptr ;
short	x,y,v ;
long	xy ;
LINE_G2	*rainline1 ;
TILE	*raintile ;


	rptr = &weatherfx_table[0] ;
	for ( lp=0 ; lp<raintype ; lp++ )
	{
		x = *(rptr) ;
		y = *(rptr+1) ;
		v = *(rptr+2) ;

		x -= v>>1 ;
		y += v ;

		y &= 255 ;
		if ( x<0 )
			x+=SCRXSZ ;

		*(rptr+0) = x ;
		*(rptr+1) = y ;

		rainline1 = (LINE_G2 *)primlistptr;
		primlistptr += sizeof(LINE_G2);
		*(long *)(&rainline1->r0) = 8+(32<<8)+(64<<16)+((0x50+0x02)<<24) ;
		*(long *)(&rainline1->r1) = 0+(8<<8)+(16<<16) ;
		setlen(rainline1,4) ;
		rainline1->x0 = x ;
		rainline1->y0 = y ;
		rainline1->x1 = x+(v>>1) ;
		rainline1->y1 = y-v ;
		addPrim( (u_long *)curr_ot+1 ,(u_long *)rainline1 );
		rptr+=3 ;

	}
	ps_drawtpage = (DR_TPAGE *)primlistptr;
   	primlistptr += sizeof(DR_TPAGE);
	setDrawTPage(ps_drawtpage,0,GAME_DITHER_FLAG,scoretpages[COLOURADD]) ;
	addPrim((u_long *)curr_ot+1 ,(u_long *)ps_drawtpage );

}
#endif


void	init_snow_fx(void)
{
long	lp ;
short	*rptr ;

	rptr = &weatherfx_table[0] ;
	for ( lp=0 ; lp<512 ; lp++ )
	{
		*rptr++ = random()%SCRXSZ ;
		*rptr++ = random()%SCRYSZ ;
		*rptr++ = (lp>>7)+1 ;
		*rptr++ = (random()&255)<<8 ;
	}
}


void	do_snow_fx(long	amount)
{
long	lp ;
short	*rptr ;
short	x,y,v,xo ;
long	xy ;
TILE_1	*snowtile1 ;
TILE	*snowtile ;
SPRINFO	*iptr ;
SPRT	*snowsprite ;
DR_TPAGE	*snowdrawtpage ;


	rptr = &weatherfx_table[0] ;
	for ( lp=0 ; lp<amount ; lp++ )
	{
		x = *(rptr) ;
		y = *(rptr+1) ;
		v = *(rptr+2) ;
		xo = slSin( *(rptr+3) ) >> 12 ;

		*(rptr+3) += v<<9 ;
		*(rptr+3) &= 0xffff ;

		y += v ;
		y &= 255 ;

		*(rptr+1) = y ;

		if ( v == 1 )
		{
			snowtile1 = (TILE_1 *)primlistptr;
			primlistptr += sizeof(TILE_1);
			*(long *)(&snowtile1->r0) = 255+(255<<8)+(255<<16)+((0x68+0x02)<<24) ;
			setlen(snowtile1,2) ;
			snowtile1->x0 = x+xo ;
			snowtile1->y0 = y ;
			addPrim( (u_long *)curr_ot+1 ,(u_long *)snowtile1 );
		}
		else if ( v == 2 )
		{
			snowtile = (TILE *)primlistptr;
			primlistptr += sizeof(TILE);
			*(long *)(&snowtile->r0) = 128+(128<<8)+(128<<16)+((0x60+0x02)<<24) ;
			setlen(snowtile,3) ;
			snowtile->x0 = x+xo ;
			snowtile->y0 = y ;
			*(long *)(&snowtile->w) = 2+(2<<16) ;
			addPrim( (u_long *)curr_ot+1 ,(u_long *)snowtile );
		}
		else
		{
			snowtile = (TILE *)primlistptr;
			primlistptr += sizeof(TILE);
			*(long *)(&snowtile->r0) = 128+(128<<8)+(128<<16)+((0x60+0x02)<<24) ;
			setlen(snowtile,3) ;
			snowtile->x0 = x+xo ;
			snowtile->y0 = y ;
			*(long *)(&snowtile->w) = 3+(3<<16) ;
			addPrim( (u_long *)curr_ot+1 ,(u_long *)snowtile );
		}
		rptr+=4 ;

	}
	ps_drawtpage = (DR_TPAGE *)primlistptr;
   	primlistptr += sizeof(DR_TPAGE);
	setDrawTPage(ps_drawtpage,0,GAME_DITHER_FLAG,scoretpages[COLOURADD]) ;
	addPrim((u_long *)curr_ot+1 ,(u_long *)ps_drawtpage );

}


/*-----------------17/04/97 10:22-------------------
 this is the lightning stuff... its REAL!
--------------------------------------------------*/


LIGHTNING	lightning_table[MAXLIGHTNING] ;


void	process_lightning(void)
{
FIXED	point1[XYZ] ;
FIXED	point2[XYZ] ;
FIXED	time ;
short	x1,y1 ;
short	x2,y2 ;
long	g1,g2 ;
long	r,g,b ;
long	rgb1 ;
long	rgb2 ;
long	lp ;
long	t,ttt ;
LINE_F2	*linef2 ;
Sint32	ans1[XY],ans2[XY] ;
long	z1,z2 ;
LIGHTNING	*lptr ;
long		sz ;
SVECTOR		sv ;
long		sxy1,sxy2 ;
short		x,y ;



	lptr = &lightning_table[0] ;

	for ( lp=0 ; lp<MAXLIGHTNING ; lp++ )
	{
		if ( lptr->lighton == 1 )
		{
			slPushMatrix() ;
			slTranslate(lptr->lightorigin[X],lptr->lightorigin[Y],lptr->lightorigin[Z]);

			point1[X] = 0 ;
			point1[Y] = 0 ;
			point1[Z] = 0 ;

			t = (lptr->lightcount<<4);
			if ( t>255 )
				t = 255;

			r = (t*lptr->lightr1)>>8 ;
			g = (t*lptr->lightg1)>>8 ;
			b = (t*lptr->lightb1)>>8 ;
			rgb1 = r+(g<<8)+(b<<16) ;
			r = (t*lptr->lightr2)>>8 ;
			g = (t*lptr->lightg2)>>8 ;
			b = (t*lptr->lightb2)>>8 ;
			rgb2 = r+(g<<8)+(b<<16) ;
			ttt = (t+(t<<8)+(t<<16)) + ((0x40+0x02)<<24) ;

			for ( time = 1 ; time <= 16 ; time += 1 )
			{
				lightning_bezier(lptr->lighttween1,lptr->lighttween2,lptr->lightstop,time,point2) ;

				if ( time != 16 )
				{
					point2[X] += ((drand()&15)-7)<<15 ;
					point2[Y] += ((drand()&15)-7)<<15 ;
					point2[Z] += ((drand()&15)-7)<<15 ;
				}

				sv.vx = point1[X]>>12 ;
				sv.vy = point1[Y]>>12 ;
				sv.vz = point1[Z]>>12 ;
				gte_ldv0(&sv);
				gte_rtps();
				gte_stsxy(&sxy1);
				gte_stszotz(&z1);
				x1 = ((sxy1&0xffff)) ;
				y1 = (((sxy1>>16)&0xffff)) ;

				sv.vx = point2[X]>>12 ;
				sv.vy = point2[Y]>>12 ;
				sv.vz = point2[Z]>>12 ;
				gte_ldv0(&sv);
				gte_rtps();
				gte_stsxy(&sxy2);
				gte_stszotz(&z2);
				x2 = ((sxy2&0xffff)) ;
				y2 = (((sxy2>>16)&0xffff)) ;

				point1[X] = point2[X] ;
				point1[Y] = point2[Y] ;
				point1[Z] = point2[Z] ;

				if ( z1<ZCLIP || z2<ZCLIP || (x1<0 && x2<0) || (x1>SCRXSZ && x2>SCRXSZ) || (y1<0 && y2<0) || (y1>SCRYSZ && y2>SCRYSZ) )
					continue ;

				if ( z2 > z1 )
					z1 = z2 ;
				z1 >>= 2 ;
				if ( z1>2047 )
					z1 = 2047 ;

				linef2 = (LINE_F2 *)primlistptr;
				primlistptr += sizeof(LINE_F2);
				*(long *)(&linef2->r0) = ttt ;
				setlen(linef2,3);
				*(long *)(&linef2->x0) = sxy1 ;
				*(long *)(&linef2->x1) = sxy2 ;
				addPrim( (u_long *)curr_ot+z1 ,(u_long *)linef2 );

				ps_polyG4 = (POLY_G4 *)primlistptr;
				primlistptr += sizeof(POLY_G4);
				*(long *)(&ps_polyG4->r0) = rgb2+((0x38+0x02)<<24) ;
				*(long *)(&ps_polyG4->r1) = rgb1 ;
				*(long *)(&ps_polyG4->r2) = rgb2 ;
				*(long *)(&ps_polyG4->r3) = rgb1 ;
				setlen(ps_polyG4,8);
				*(long *)(&ps_polyG4->x0) = sxy1-6;
				*(long *)(&ps_polyG4->x1) = sxy1;
				*(long *)(&ps_polyG4->x2) = sxy2-6;
				*(long *)(&ps_polyG4->x3) = sxy2;
				addPrim((u_long *)curr_ot+z1 ,(u_long *)ps_polyG4 );

				ps_polyG4 = (POLY_G4 *)primlistptr;
				primlistptr += sizeof(POLY_G4);
				*(long *)(&ps_polyG4->r0) = rgb2+((0x38+0x02)<<24) ;
				*(long *)(&ps_polyG4->r1) = rgb1 ;
				*(long *)(&ps_polyG4->r2) = rgb2 ;
				*(long *)(&ps_polyG4->r3) = rgb1 ;
				setlen(ps_polyG4,8);
				*(long *)(&ps_polyG4->x0) = sxy1+6;
				*(long *)(&ps_polyG4->x1) = sxy1;
				*(long *)(&ps_polyG4->x2) = sxy2+6;
				*(long *)(&ps_polyG4->x3) = sxy2;
				addPrim((u_long *)curr_ot+z1 ,(u_long *)ps_polyG4 );

				ps_drawtpage = (DR_TPAGE *)primlistptr;
   				primlistptr += sizeof(DR_TPAGE);
				setDrawTPage(ps_drawtpage,0,GAME_DITHER_FLAG,scoretpages[COLOURADD]) ;
				addPrim((u_long *)curr_ot+z1 ,(u_long *)ps_drawtpage );


			}

			lptr->lighttween1[X] += lptr->lighttv1[X] ;
			lptr->lighttween1[Y] += lptr->lighttv1[Y] ;
			lptr->lighttween1[Z] += lptr->lighttv1[Z] ;
			lptr->lighttween2[X] += lptr->lighttv2[X] ;
			lptr->lighttween2[Y] += lptr->lighttv2[Y] ;
			lptr->lighttween2[Z] += lptr->lighttv2[Z] ;

			lptr->lightcount-- ;
			if ( lptr->lightcount == 0 )
				lptr->lighton = 0 ;

			slPopMatrix() ;

		}
		lptr++ ;
	}

}



FIXED	lightning_bez_tab[3][17] ;


static	long	next_lightning ;

void		init_lightning(void)
{
long	lp ;
FIXED	tp1 ;
FIXED	dp1 ;
FIXED	ep1 ;
FIXED	tx3 ;
FIXED	txtxt ;
FIXED	t2 ;
FIXED	t ;

	next_lightning = 0 ;
	for ( lp=0 ; lp<MAXLIGHTNING ; lp++ )
		lightning_table[lp].lighton = 0 ;

	lp = 0 ;
	for ( t = 0 ; t <= toFIXED(1) ; t+=4096 )
	{
		tp1 = toFIXED(1.0)-t  ;		// ( 1 - t )
		dp1 = slMulFX(tp1,tp1) ;	// ( 1 - t ) ^ 2

		t2 = slMulFX(t,t) ;			// t ^ 2

		tx3 = slMulFX(t,toFIXED(3.0)) ;		// ( t*3 )
		ep1 = slMulFX(dp1,tx3) ;			// ( t*3 ) * ( (1-t) ^ 2 )

		tx3 = slMulFX(t2,toFIXED(3.0)) ;	// ( t ^ 2 ) * 3
		tx3 = slMulFX(tx3,tp1) ;    		// (( t*3 ) ^ 2 ) * ( 1 - t )

		txtxt = slMulFX(t,t) ;
		txtxt = slMulFX(txtxt,t) ; 		// t^3

		lightning_bez_tab[0][lp] = ep1 ;
		lightning_bez_tab[1][lp] = tx3 ;
		lightning_bez_tab[2][lp] = txtxt ;

		lp++ ;
	}
}


void	lightning_bezier(FIXED p2[XYZ],FIXED p3[XYZ],FIXED p4[XYZ],uchar t,FIXED ans[XYZ])
{
FIXED	t1,t2,t3 ;

	t1 = lightning_bez_tab[0][t] ;
	t2 = lightning_bez_tab[1][t] ;
	t3 = lightning_bez_tab[2][t] ;

	ans[X] = slMulFX(t1,p2[X]) ;
	ans[Y] = slMulFX(t1,p2[Y]) ;
	ans[Z] = slMulFX(t1,p2[Z]) ;

	ans[X] += slMulFX(t2,p3[X]) ;
	ans[Y] += slMulFX(t2,p3[Y]) ;
	ans[Z] += slMulFX(t2,p3[Z]) ;

	ans[X] += slMulFX(t3,p4[X]) ;
	ans[Y] += slMulFX(t3,p4[Y]) ;
	ans[Z] += slMulFX(t3,p4[Z]) ;

}



void		insert_lightning(FIXED x1,FIXED y1,FIXED z1,FIXED x2,FIXED y2,FIXED z2,long	xyzr,long rgb1,long rgb2,short count)
{
long		lp ;
FIXED		diff[XYZ] ;
LIGHTNING	*lptr ;
uchar		xr,yr,zr ;
long		off ;

	off = -1 ;
	for ( lp=0 ; lp<MAXLIGHTNING ; lp++ )
	{
		if ( lightning_table[lp].lighton == 0 )
		{
			off = lp ;
			break;
		}
	}
	if ( off == -1 )
		return ;
	lptr = &lightning_table[off] ;

	lptr->lighton = 1 ;
	lptr->lightcount = count ;

	lptr->lightorigin[X] = x1 ;
	lptr->lightorigin[Y] = y1 ;
	lptr->lightorigin[Z] = z1 ;

	lptr->lightstart[X] = 0 ;
	lptr->lightstart[Y] = 0 ;
	lptr->lightstart[Z] = 0 ;

	lptr->lightstop[X] = x2-x1 ;
	lptr->lightstop[Y] = y2-y1 ;
	lptr->lightstop[Z] = z2-z1 ;

	diff[X] = (x2-x1)/3 ;
	diff[Y] = (y2-y1)/3 ;
	diff[Z] = (z2-z1)/3 ;

	lptr->lighttween1[X] = diff[X] ;
	lptr->lighttween1[Y] = diff[Y] ;
	lptr->lighttween1[Z] = diff[Z] ;

	lptr->lighttween2[X] = diff[X]<<1 ;
	lptr->lighttween2[Y] = diff[Y]<<1 ;
	lptr->lighttween2[Z] = diff[Z]<<1 ;

	xr = xyzr ;
	yr = xyzr>>8 ;
	zr = xyzr>>16 ;

	lptr->lighttv1[X] = ((drand()&511)-255)<<xr ;
	lptr->lighttv1[Y] = ((drand()&511)-255)<<yr ;
	lptr->lighttv1[Z] = ((drand()&511)-255)<<zr ;

	lptr->lighttv2[X] = ((drand()&511)-255)<<xr ;
	lptr->lighttv2[Y] = ((drand()&511)-255)<<yr ;
	lptr->lighttv2[Z] = ((drand()&511)-255)<<zr ;

	lptr->lightr1 = rgb1 ;
	lptr->lightg1 = rgb1>>8 ;
	lptr->lightb1 = rgb1>>16 ;
	lptr->lightr2 = rgb2 ;
   	lptr->lightg2 = rgb2>>8 ;
	lptr->lightb2 = rgb2>>16 ;

	//next_lightning++ ;
	//next_lightning %= MAXLIGHTNING ;
}




FXSPRITE	fxsprite_table[MAXFXSPRITES] ;

void	init_fxsprites(void)
{
long 	lp ;

	for ( lp = 0 ; lp<MAXFXSPRITES ; lp++ )
		fxsprite_table[lp].fxspron = -1 ;

}


void	insert_fxsprite(FIXED x,FIXED y,FIXED z,FIXED xv,FIXED yv,FIXED zv,FIXED grav,FIXED size,char *anmptr,Uint32 typergb,ANGLE ang)
{
long	lp ;
long	off ;
FXSPRITE	*sptr ;

	off = -1 ;
	sptr = &fxsprite_table[0] ;
	for ( lp = 0 ; lp<MAXFXSPRITES ; lp++ )
	{
		if ( sptr->fxspron == -1 )
		{
			off = lp ;
			break ;
		}
		sptr++ ;
	}

	if ( off == -1 )
		return ;

	sptr = &fxsprite_table[off] ;

	sptr->fxspron = 1 ;
	sptr->fxsprx = x ;
	sptr->fxspry = y ;
	sptr->fxsprz = z ;
	sptr->fxsprxv = xv ;
	sptr->fxspryv = yv ;
	sptr->fxsprzv = zv ;
	sptr->fxsprgrav = grav ;
	sptr->fxsprsz = (size>>4) ;
	sptr->fxspranmptr = anmptr ;
	sptr->fxspranmpos = 0 ;
	sptr->fxsprr = (typergb) ;
	sptr->fxsprg = (typergb)>>8 ;
	sptr->fxsprb = (typergb)>>16 ;
	sptr->fxsprtype = (typergb>>26)&0x3 ;
	sptr->fxsprtrans = (typergb>>30)&0x1 ;
	sptr->fxsprcolmode = (typergb>>28)&0x3 ;
	sptr->fxsprflr = (typergb>>31)&0x1 ;
	sptr->fxsprang = ang ;


}


#ifndef	USE_DELS_ASM
void	draw_fxsprites(void)
{
long   		z ;
FIXED  		scale ;
long   		lp ;
long   		uo ;
char   		frame ;
long   		r,g,b ;
long		x1,y1,x2,y2,x3,y3,x4,y4 ;
short		x,y ;
long		draw ;
FXSPRITE	*sptr ;
SPRINFO		*iptr ;
MATRIX		*unittempm ;
SVECTOR		*sv ;
long		*sxy ;
long		*sz ;
short		uv,wh ;

	sptr = &fxsprite_table[0] ;

	unittempm = (MATRIX *)((uchar *)DCACHE_BASE+256) ;
	sv = (SVECTOR *)((char *)DCACHE_BASE+8) ;		// Yummy... Lets Use The Scratchpad
	sxy = (long *)((char *)DCACHE_BASE+32) ;		// Yummy... Lets Use The Scratchpad
	sz = (long *)((char *)DCACHE_BASE+128) ; 		// Yummy... Lets Use The Scratchpad

	for ( lp = 0 ; lp<MAXFXSPRITES ; lp++ )
	{
		if ( sptr->fxspron != -1 )
		{
			frame = *(sptr->fxspranmptr + sptr->fxspranmpos) ;

			if ( frame == FXSPRKILL )
			{
				sptr->fxspron = -1 ;
				sptr++ ;
				continue;
			}
			else if ( frame == FXSPRLOOP )
			{
				sptr->fxspranmpos = 0 ;
				frame = *sptr->fxspranmptr ;
			}
			else if ( frame == FXSPRCOL )
			{
				sptr->fxsprr = *(sptr->fxspranmptr + sptr->fxspranmpos + 1) ;
				sptr->fxsprg = *(sptr->fxspranmptr + sptr->fxspranmpos + 2) ;
				sptr->fxsprb = *(sptr->fxspranmptr + sptr->fxspranmpos + 3) ;
				sptr->fxspranmpos += 4 ;
				frame = *(sptr->fxspranmptr + sptr->fxspranmpos) ;

				if ( frame == FXSPRROTADD )
				{
					sptr->fxspranmpos++	;
					frame = *(sptr->fxspranmptr + sptr->fxspranmpos) ;
					sptr->fxsprang += frame<<8 ;

					sptr->fxspranmpos++	;
					frame = *(sptr->fxspranmptr + sptr->fxspranmpos) ;
				}
				if ( frame == FXSPRROTSUB )
				{
					sptr->fxspranmpos++	;
					frame = *(sptr->fxspranmptr + sptr->fxspranmpos) ;
					sptr->fxsprang -= frame<<8 ;

					sptr->fxspranmpos++	;
					frame = *(sptr->fxspranmptr + sptr->fxspranmpos) ;
				}
			}


			sptr->fxspranmpos++ ;
			if ( frame == NULLFXSPR )
			{
				sptr++ ;
				continue;
			}

			iptr = spriteinfo+frame ;

			scale = sptr->fxsprsz ;

			slPushMatrix();
			slTranslate(sptr->fxsprx,sptr->fxspry,sptr->fxsprz);

			sptr->fxsprx += sptr->fxsprxv ;
			sptr->fxspry += sptr->fxspryv ;
			sptr->fxsprz += sptr->fxsprzv ;

			sptr->fxsprzv += sptr->fxsprgrav ;
			if ( sptr->fxsprzv > toFIXED(32) )
				sptr->fxsprzv = toFIXED(32) ;

			if ( sptr->fxsprtype == FXSPR_POLY )
			{
				slRotZ(sptr->fxsprang) ;

				x1 = ((iptr->xo)<<4) ;
				y1 = ((iptr->yo)<<4) ;
				x2 = x1 + ((iptr->w)<<4)  ;
				y2 = y1 + ((iptr->h)<<4)  ;

				x1 = (x1*scale)>>12 ;
				x2 = (x2*scale)>>12 ;
				y1 = (y1*scale)>>12 ;
				y2 = (y2*scale)>>12 ;

				sv->vz = 0 ;

				sv->vx = x1 ;
				sv->vy = y1 ;
				gte_ldv0(sv);
				gte_rtps();
    			gte_stsxy(sxy);
				gte_stszotz(sz) ;

				sv->vx = x2 ;
				gte_ldv0(sv);
				gte_rtps();
    			gte_stsxy(sxy+1);
				gte_stszotz(sz+1) ;

				sv->vx = x1 ;
				sv->vy = y2 ;
				gte_ldv0(sv);
				gte_rtps();
    			gte_stsxy(sxy+2);
				gte_stszotz(sz+2) ;

				sv->vx = x2 ;
				gte_ldv0(sv);
				gte_rtps();
    			gte_stsxy(sxy+3);
				gte_stszotz(sz+3) ;

				slPopMatrix();

				if ( *(sz+0)<ZCLIP || *(sz+1)<ZCLIP || *(sz+2)<ZCLIP || *(sz+3)<ZCLIP  )	// Any Less than ZClip Value?
				{
					sptr++ ;
					continue ;
				}
				x1 = *(sxy+0) ;                                 	// Get X's
				x2 = *(sxy+1) ;
				x3 = *(sxy+2) ;
				x4 = *(sxy+3) ;

		 		if (	( (short)x1<0 && (short)x2<0 && (short)x3<0 && (short)x4<0 )	// All off Screen?
			 		 ||	( (short)x1>=SCRXSZ && (short)x2>=SCRXSZ && (short)x3>=SCRXSZ && (short)x4>=SCRXSZ ) )
				{
					sptr++ ;
					continue ;
				}

				y1 = x1>>16 ;                                       // Get Y's
				y2 = x2>>16 ;
				y3 = x3>>16 ;
				y4 = x4>>16 ;

		 		if (	( (short)y1<0 && (short)y2<0 && (short)y3<0 && (short)y4<0 )   // All off Screen?
			 		 ||	( (short)y1>=SCRYSZ && (short)y2>=SCRYSZ && (short)y3>=SCRYSZ && (short)y4>=SCRYSZ )	)
				{
					sptr++ ;
					continue ;
				}

				z = 2047 ;
				if( *(sz+0) < z )
					z = *(sz+0);
				if( *(sz+1) < z )
					z = *(sz+1);
				if( *(sz+2) < z )
					z = *(sz+2);
				if( *(sz+3) < z )
					z = *(sz+3);

			}
			else if ( sptr->fxsprtype == FXSPR_FLAT )
			{
				unittempm->m[0][0] = scale;
				unittempm->m[0][1] = 0;
				unittempm->m[0][2] = 0;
				unittempm->m[1][0] = 0;
				unittempm->m[1][1] = scale;
				unittempm->m[1][2] = 0;
				unittempm->m[2][0] = 0;
				unittempm->m[2][1] = 0;
				unittempm->m[2][2] = scale;
				gte_SetRotMatrix(unittempm);		// Bang a Unit Matrix on GTE

				slRotZ(sptr->fxsprang) ;

				x1 = ((iptr->xo)<<4) ;
				y1 = ((iptr->yo)<<4) ;
				x2 = x1 + ((iptr->w)<<4)  ;
				y2 = y1 + ((iptr->h)<<4)  ;

				sv->vz = 0 ;

				sv->vx = x1 ;
				sv->vy = y1 ;
				gte_ldv0(sv);
				gte_rtps();
    			gte_stsxy(sxy);
				gte_stszotz(sz) ;

				if ( *sz < ZCLIP )
				{
					slPopMatrix() ;
					sptr++ ;
					continue ;
				}

				sv->vx = x2 ;
				gte_ldv0(sv);
				gte_rtps();
    			gte_stsxy(sxy+1);

				sv->vx = x1 ;
				sv->vy = y2 ;
				gte_ldv0(sv);
				gte_rtps();
    			gte_stsxy(sxy+2);

				sv->vx = x2 ;
				gte_ldv0(sv);
				gte_rtps();
    			gte_stsxy(sxy+3);

				slPopMatrix();

				z = *sz ;

				if ( z<ZCLIP )	// Any Less than ZClip Value?
				{
					sptr++ ;
					continue ;
				}
				x1 = *(sxy+0) ;                                 	// Get X's
				x2 = *(sxy+1) ;
				x3 = *(sxy+2) ;
				x4 = *(sxy+3) ;

				if (	( (short)x1<0 && (short)x2<0 && (short)x3<0 && (short)x4<0 )	// All off Screen?
					 ||	( (short)x1>=SCRXSZ && (short)x2>=SCRXSZ && (short)x3>=SCRXSZ && (short)x4>=SCRXSZ ) )
				{
					sptr++ ;
					continue ;
				}

				y1 = x1>>16 ;                                       // Get Y's
				y2 = x2>>16 ;
				y3 = x3>>16 ;
				y4 = x4>>16 ;

				if (	( (short)y1<0 && (short)y2<0 && (short)y3<0 && (short)y4<0 )   // All off Screen?
					 ||	( (short)y1>=SCRYSZ && (short)y2>=SCRYSZ && (short)y3>=SCRYSZ && (short)y4>=SCRYSZ )	)
				{
					sptr++ ;
					continue ;
				}

			}
			else if ( sptr->fxsprtype == FXSPR_NOSCALE )
			{
				unittempm->m[0][0] = GTEONE;
				unittempm->m[0][1] = 0;
				unittempm->m[0][2] = 0;
				unittempm->m[1][0] = 0;
				unittempm->m[1][1] = GTEONE;
				unittempm->m[1][2] = 0;
				unittempm->m[2][0] = 0;
				unittempm->m[2][1] = 0;
				unittempm->m[2][2] = GTEONE;
				gte_SetRotMatrix(unittempm);		// Bang a Unit Matrix on GTE

				sv->vx = 0 ;
				sv->vy = 0 ;
				sv->vz = 0 ;
				gte_ldv0(sv);
				gte_rtps();
    			gte_stsxy(sxy);
				gte_stszotz(sz) ;

				if ( *sz < ZCLIP )
				{
					slPopMatrix() ;
					sptr++ ;
					continue ;
				}

				x = *(sxy+0) ;
				y = *(sxy+0)>>16 ;

				x1 = (iptr->xo) ;
				y1 = (iptr->yo) ;
				x2 = (iptr->w)  ;
				y2 = (iptr->h)  ;

				*(sxy+0) = (x+x1) + ((y+y1)<<16) ;
				*(sxy+1) = (x+x1+x2) + ((y+y1)<<16) ;
				*(sxy+2) = (x+x1) + ((y+y1+y2)<<16) ;
				*(sxy+3) = (x+x1+x2) + ((y+y1+y2)<<16) ;

				slPopMatrix();

				x1 = *(sxy+0) ;                                 	// Get X's
				x2 = *(sxy+3) ;
				y1 = x1>>16 ;                                       // Get Y's
				y2 = x2>>16 ;

				if( (short)x1>SCRXSZ || (short)x2<0 || (short)y1>SCRYSZ || (short)y2<0 )
				{
					sptr++ ;
					continue ;
				}
				z = *sz ;

			}

// ok , lets draw

			if ( sptr->fxsprflr == FXSPR_ONFLR )
				z = 2046 ;
			else
			{
				z >>= 2 ;											// Get into OT Range....
				if ( z>2047 )										// Keep in OT Range...
					z = 2047 ;
				if ( z<0 )										// Keep in OT Range...
					z = 0 ;
			}

			r = (sptr->fxsprr*GlobalR)>>7 ;
			if ( r>255 )
				r = 255;
			g = (sptr->fxsprg*GlobalG)>>7 ;
			if ( g>255 )
				g = 255;
			b = (sptr->fxsprb*GlobalB)>>7 ;
			if ( b>255 )
				b = 255;

			ps_polyFT4 = (POLY_FT4 *)primlistptr;
			primlistptr += sizeof(POLY_FT4);
			setPolyFT4(ps_polyFT4);
			*(long *)(&ps_polyFT4->x0) = *(sxy+0);
			*(long *)(&ps_polyFT4->x1) = *(sxy+1);
			*(long *)(&ps_polyFT4->x2) = *(sxy+2);
			*(long *)(&ps_polyFT4->x3) = *(sxy+3);

			setRGB0(ps_polyFT4,r,g,b);

			ps_polyFT4->tpage = spritetpages[iptr->tpage+sptr->fxsprcolmode] ;

			if ( sptr->fxsprtrans == TRANS )
				setSemiTrans(ps_polyFT4,1) ;

			ps_polyFT4->clut = *(spritecluts+frame) ;

			uv = *(short *)&(iptr->u) ;
			wh = *(short *)&(iptr->w) ;
			*(short *)&(ps_polyFT4->u0) = uv ;
			*(short *)&(ps_polyFT4->u1) = uv+(wh&0x00ff) ;
			*(short *)&(ps_polyFT4->u2) = uv+(wh&0xff00) ;
			*(short *)&(ps_polyFT4->u3) = uv+wh ;

			addPrim((u_long *)curr_ot+z,(u_long *)ps_polyFT4 );
		}
		sptr++ ;
	}
}
#endif


/*-----------------12-10-97 10:22am-----------------
 blast shit, coded by DAN

 modded by del for speed and 3d rings effect.... :)

--------------------------------------------------*/

BLAST	blast_table[MAXBLASTS] ;

void	init_blasts(void)
{
long 	lp ;

	for ( lp = 0 ; lp<MAXBLASTS ; lp++ )
		blast_table[lp].idon = 0 ;
}



#ifndef	USE_DELS_ASM
BLAST	*find_free_blast(void)
{
long	lp ;
BLAST	*blptr ;

	blptr = &blast_table[0];
	for ( lp=0; lp<MAXBLASTS; lp++ )
	{
		if ( blptr->idon == 0 )
			return(blptr);					// here! have a blast struct
		blptr++ ;
	}

	return(0); 								// no joy mate...

}


typedef	struct	blastdraw
{
	int r,g,b; 					// 12 bytes
	FIXED	circbuf[32];		// 128 bytes	(half as big as dans)
	FIXED	sxy[32];			// 128 bytes
	FIXED	sz[32];				// 128 bytes
	SVECTOR	sv;

}BLASTDRAW;


void	draw_blasts(void)				// new cranked version...
{

BLASTDRAW	*spinfo;

long	blp,lp,lp2 ;
long	pre;
long	*tempsxy ;
long	*tempsz ;
long	xy1,xy2,xy3,xy4 ;
long	z1,z2,z3,z4 ;
long	rgb ;
short	uv,wh ;
SPRINFO	*iptr ;
BLAST	*blptr ;
FIXED	*bl ;
long	ir,or ;
POLY_FT4 *polyme;


	spinfo = (BLASTDRAW *)0x1f800080;						// setup a pointer to our scratchpad buffer
	spinfo->sv.vz = 0 ;										// do this only once for speed

// first lets create circle points on scratchpad (32 longs for 16 X/Y's)
	bl = spinfo->circbuf;									// bl = circle buffer
	for ( lp=0 ; lp<16 ; lp++ )
	{
		*(bl++) = slSin(lp<<12)>>12;
		*(bl++) = slCos(lp<<12)>>12;
	}

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

	blptr = blast_table;

// this is the main blast loop (outer loop)
	for ( blp=0 ; blp<MAXBLASTS ; blp++,blptr++ )
	{

		if ( blptr->idon == 0 )
			continue ;

		if ( blptr->time != 0 )
		{
			blptr->time--;
			blptr->orad += blptr->oradadd;
			blptr->irad += blptr->iradadd;
		}

		if ( blptr->time==0 )
		{
			blptr->idon = 0;										// kill the blast... :)
			continue;
		}



		slPushMatrix() ;
		slTranslate(blptr->x,blptr->y,blptr->z) ;

		if ( blptr->idon==2 )										// RING ID?
		{
			slRotX(DEGtoANG(90.0));									// do X rot
   			slRotY(blptr->yrot);									// do Y rot
			blptr->x += blptr->xv;									// add xvelocity
			blptr->y += blptr->yv;									// add yvelocity
		}



		tempsxy =  spinfo->sxy ;  		   			   			// Yummy... Lets Use The Scratchpad
		tempsz = spinfo->sz ;	  		   						// Yummy... Lets Use The Scratchpad

// rot the outter radius points
		or = blptr->orad >> 16 ;
		bl = spinfo->circbuf ;		 							// Mmmmmmm Lurvvvvly!!
		spinfo->sv.vx = ( *(bl++) * or )  ;
		spinfo->sv.vy = ( *(bl++) * or )  ;

		for ( lp=0 ; lp<32 ; lp+=2 )
		{
			gte_ldv0(&spinfo->sv);
			gte_rtps();											// Do Rot Trans Pers

			spinfo->sv.vx = ( *(bl++) * or )  ;
			spinfo->sv.vy = ( *(bl++) * or )  ;

			gte_stsxy(tempsxy++);									// Fetch Screen Coords and Stack 'Em on Cache!
			gte_stszotz(tempsz++);								// Fetch Screen Coords and Stack 'Em on Cache!
		}

// rot the inner radius points
		ir = blptr->irad >> 16 ;
		bl = spinfo->circbuf ;		 							// Mmmmmmm Lurvvvvly!!
		spinfo->sv.vx = ( *(bl++) * ir )  ;
		spinfo->sv.vy = ( *(bl++) * ir )  ;

		for ( lp=0 ; lp<32 ; lp+=2 )
		{
			gte_ldv0(&spinfo->sv);
			gte_rtps();											// Do Rot Trans Pers

			spinfo->sv.vx = ( *(bl++) * ir )  ;
			spinfo->sv.vy = ( *(bl++) * ir )  ;

			gte_stsxy(tempsxy++);									// Fetch Screen Coords and Stack 'Em on Cache!
			gte_stszotz(tempsz++);								// Fetch Screen Coords and Stack 'Em on Cache!
		}

		slPopMatrix() ;

		spinfo->r = blptr->r ;
		spinfo->g = blptr->g ;
		spinfo->b = blptr->b ;

		if ( blptr->time < blptr->fade )
		{
			pre = (blptr->time<<8)/blptr->fade;
			spinfo->r = (spinfo->r*pre)>>8;
			spinfo->g = (spinfo->g*pre)>>8;
			spinfo->b = (spinfo->b*pre)>>8;
		}

		spinfo->r = (spinfo->r*GlobalR)>>7 ;
		if ( spinfo->r>255 )
			spinfo->r = 255;
		spinfo->g = (spinfo->g*GlobalG)>>7 ;
		if ( spinfo->g>255 )
			spinfo->g = 255;
		spinfo->b = (spinfo->b*GlobalB)>>7 ;
		if ( spinfo->b>255 )
			spinfo->b = 255;

		rgb = spinfo->r+(spinfo->g<<8)+(spinfo->b<<16) | ((0x2c+2)<<24) ;		// rgb+code in a long please... :)

		iptr = spriteinfo+blptr->texture ;

		for ( lp=0  ; lp<16 ; lp++ ) 				// Rotate Vertex's Loop
		{
			lp2 = (lp+1)&15 ;

			z1 = spinfo->sz[lp];		   			//*(sz+lp) ; 							// Get Z's
			z2 = spinfo->sz[lp2];  					//*(sz+lp2) ;
			z3 = spinfo->sz[lp+16];					//*(sz+lp+16) ;
			z4 = spinfo->sz[lp2+16];				//*(sz+lp2+16) ;

			if ( z1<ZCLIP || z2<ZCLIP || z3<ZCLIP || z4<ZCLIP )	// Any Less than ZClip Value?
				continue ;										// Do Next Poly.

			xy1 = spinfo->sxy[lp];	 	   			//*(sxy+lp);
			xy2 = spinfo->sxy[lp2];    	   	   		//*(sxy+lp2);
			xy3 = spinfo->sxy[lp+16];  	   	   		//*(sxy+lp+16);
			xy4 = spinfo->sxy[lp2+16]; 		   		//*(sxy+lp2+16);

// yclip (tasteful version)
			if ( (xy1&0xff000000)&&(xy2&0xff000000)&&(xy3&0xff000000)&&(xy4&0xff000000) )
				continue;
// xclip
			if (	( (short)xy1<0 && (short)xy2<0 && (short)xy3<0 && (short)xy4<0 )	// All off Screen?
				 ||	( (short)xy1>=SCRXSZ && (short)xy2>=SCRXSZ && (short)xy3>=SCRXSZ && (short)xy4>=SCRXSZ ) )
				continue;


			if ( blptr->onflr == BLAST_ONFLR )
				z1 = 2046 ;
			else
			{
				if (z2<z1)
   					z1=z2;
   				if (z3<z1)
   					z1=z3;
   				if (z4<z1)
   					z1=z4;
				z1 >>= 2 ;											// Get into OT Range....
				if ( z1>2047 )										// Keep in OT Range...
					z1 = 2047 ;
			}

			polyme = (POLY_FT4 *)primlistptr;
			primlistptr += sizeof(POLY_FT4);
			*(long *)(&polyme->r0) = rgb;

			*(long *)(&polyme->x0) = xy1;
			*(long *)(&polyme->x1) = xy2;
			*(long *)(&polyme->x2) = xy3;
			*(long *)(&polyme->x3) = xy4;

			polyme->tpage = spritetpages[iptr->tpage+COLOURADD] ;
			polyme->clut = *(spritecluts+blptr->texture) ;
			uv = *(short *)&(iptr->u) ;
   			wh = *(short *)&(iptr->w) ;

			*(short *)&(polyme->u0) = uv ;
			*(short *)&(polyme->u1) = uv+(wh&0x00ff) ;
			*(short *)&(polyme->u2) = uv+(wh&0xff00) ;
			*(short *)&(polyme->u3) = uv+wh ;

			setlen(polyme, 9);	  									// setup poly DMA length
			addPrim( (u_long *)curr_ot+z1 ,(u_long *)polyme );
		}

	}																// main blast loop

	return;
}

#endif /*USE_DELS_ASM*/





void	lazer_beam_me(FIXED start[XYZ],FIXED vec[XYZ],long len,long subs,long rgb,uchar fflag,uchar type)
{
FIXED	xyz1[XYZ] ;
FIXED	xyz2[XYZ] ;
int		i,lp,lp2;
FIXED	x1,y1,z1,x2,y2,z2 ;

	x1 = NINJA->transx-TF(10) ;
	x2 = NINJA->transx+TF(10) ;
	y1 = NINJA->transy-TF(10) ;
	y2 = NINJA->transy+TF(10) ;
	z1 = NINJA->transz-TF(70) ;
	z2 = NINJA->transz ;

	xyz1[X] = start[X] ;
	xyz1[Y] = start[Y] ;
	xyz1[Z] = start[Z] ;
	xyz2[X] = start[X]+vec[X] ;
	xyz2[Y] = start[Y]+vec[Y] ;
	xyz2[Z] = start[Z]+vec[Z] ;
	i = 0 ;

	draw_sprite(xyz1[X],xyz1[Y],xyz1[Z],S_FLARE,TF(0.5)+(rand()&32767),((rgb&0xfefefe)>>1)+DRAWSPRTYPE(TRANS,COLOURADD)) ;

	while ( i<len )
	{
		for ( lp = 0 ; lp<subs ; lp++ )
		{
			if ( fflag == LAZERFLOORDET )
			{
				if ( GetHeightOnPos(xyz2[X],xyz2[Y],curhmap) < xyz2[Z] )
				{
					draw_sprite(xyz2[X],xyz2[Y],xyz2[Z],S_FLARE,TF(0.6),((rgb&0xfefefe)>>1)+DRAWSPRTYPE(TRANS,COLOURADD)) ;
					insert_spark( 3 ,xyz2[X],xyz2[Y],xyz2[Z] ,SPARKWH(2,2,1,1), rgb, RGBME(0,0,0) ,COLOURADD ,3 ,16 ,-32  ,31,-16 ,31,-16 ,31,-16 ,0,0,-15,  127,127,127 ) ;
					if ( type == LAZER_BEAM )
						insert_line(xyz1[X],xyz1[Y],xyz1[Z],xyz2[X],xyz2[Y],xyz2[Z],rgb) ;
					i = len ;
					break ;
				}
			}
			if ( xyz2[X] > x1 && xyz2[X] < x2 && xyz2[Y] > y1 && xyz2[Y] < y2 &&  xyz2[Z] > z1 && xyz2[Z] < z2 )
			{
				insert_fxsprite(xyz2[X],xyz2[Y],xyz2[Z],0,0,0,NOGRAV,TF(0.9),flareatab,SPRTYPE(FXSPR_FLAT,TRANS,COLOURADD,0)+rgb,RANDANG) ;
				insert_spark( 3 ,xyz2[X],xyz2[Y],xyz2[Z] ,SPARKWH(5,5,1,1), rgb , RGBME(0,0,0) ,COLOURADD ,3 ,16 ,-32  ,31,-16 ,31,-16 ,31,-16 ,0,0,0,  127,127,127 ) ;
				if ( type == LAZER_BEAM )
					insert_line(xyz1[X],xyz1[Y],xyz1[Z],xyz2[X],xyz2[Y],xyz2[Z],rgb) ;
				HitNinja(-vec[X],-vec[Y],toFIXED(8.0),toFIXED(0.3),HITNINJA_NORM);
				glow_ninja( (rgb&0xf8f8f8)>>3 );

				i = len ;
				break ;
			}

			xyz2[X] += vec[X] ;
			xyz2[Y] += vec[Y] ;
			xyz2[Z] += vec[Z] ;
		}

		if ( type == LAZER_BEAM )
			insert_line(xyz1[X],xyz1[Y],xyz1[Z],xyz2[X],xyz2[Y],xyz2[Z],rgb) ;
		xyz1[X] = xyz2[X] ;
		xyz1[Y] = xyz2[Y] ;
		xyz1[Z] = xyz2[Z] ;
		i++ ;
	}

	if ( type == LAZER_LIGHTNING )
	{
		if ( (rand()&7) == 0 )
			insert_lightning(start[X],start[Y],start[Z],xyz1[X],xyz1[Y],xyz1[Z],	LIGHTCURVE(12,12,12), 		rgb,	(rgb&0xfcfcfc)>>2,  6) ;
		else
			insert_lightning(start[X],start[Y],start[Z],xyz1[X],xyz1[Y],xyz1[Z],	LIGHTCURVE(6,6,6), 		rgb,	(rgb&0xfefefe)>>1,  4) ;
	}
}

void	flare_me(FIXED x,FIXED y,FIXED z,long rgb1,long rgb2,FIXED scale)
{
	insert_fxsprite(x,y,z,0,0,0,0,scale,flareatab,SPRTYPE(FXSPR_FLAT,TRANS,COLOURADD,0)+rgb2,RANDANG);
	insert_fxsprite(x,y,z,0,0,0,0,scale>>1,lightatab,SPRTYPE(FXSPR_FLAT,TRANS,COLOURADD,0)+rgb1,RANDANG);
}


short	splashsparktab[] =	{ 	5,0,8,-96, 		4,8,6,-80	} ;

long	splashspritestab[] =	{
								TF(+16),TF(0),TF(2.0),	(long)splashmediumatab,
								TF(-16),TF(0),TF(2.2),	(long)splashmediumatab,
								TF(0),TF(+16),TF(1.9),	(long)splashmediumatab,
								TF(0),TF(-16),TF(1.7),	(long)splashmediumatab,
								TF(0),TF(0),TF(3),		(long)splashmediumatab
								} ;


void	splash_me(FIXED xyz[XYZ],long ripple)
{
FIXED	x,y,z ;
long	*ptr,lp ;
short	*cptr ;

	x = xyz[X] ;
	y = xyz[Y] ;
	z = xyz[Z] ;

	SPU_PlayDefault_XYZ(SFX_FOREST_SPLASH,xyz) ;

	cptr = splashsparktab ;
	for ( lp=0 ; lp<2 ; lp++ )
	{
		insert_spark( *(cptr+0) ,x,y,z ,SPARKWH(8,6,3,14), RGBME( (24*GlobalR)>>7,(24*GlobalG)>>7,(40*GlobalB)>>7) ,RGBME(0,0,*(cptr+1)) ,COLOURADD ,*(cptr+2) ,32 ,-32 ,511,-255 ,511,-255 ,0,0 ,0,0,*(cptr+3),  15,15,63 ) ;
		cptr+=4 ;
	}
	ptr = splashspritestab ;
	for ( lp=0 ; lp<5 ; lp++ )
	{
		insert_fxsprite(x+(*ptr),y+(*(ptr+1)),z,0,0,0,0,*(ptr+2),(uchar *)*(ptr+3),SPRTYPE(FXSPR_POLY,TRANS,COLOURADD,FXSPR_ONFLR)+RGBME(16,16,32),0) ;
		ptr+=4 ;
	}
	if ( ripple == 1 )
	{
		for ( lp= TF(1.0) ; lp<= TF(1.5) ; lp+= TF(0.5) )
		{
			BLASTME(x,y,z ,TF(4),TF(0), lp,lp, 8,16,32, 32,16,	S_BLAST,	BLAST_ONFLR,NO_DET) ;
		}
	}
}

void	splash_me2(FIXED xyz[XYZ],long ripple)
{
FIXED	x,y,z ;
long	*ptr,lp ;
short	*cptr ;

	x = xyz[X] ;
	y = xyz[Y] ;
	z = xyz[Z] ;

	SPU_PlayDefault_XYZ(SFX_FOREST_FOOTSTEPWATER1+(random()&3),xyz);

	cptr = splashsparktab ;
	for ( lp=0 ; lp<2 ; lp++ )
	{
		insert_spark( *(cptr+0) ,x,y,z ,SPARKWH(8,6,3,14), RGBME( (24*GlobalR)>>7,(24*GlobalG)>>7,(40*GlobalB)>>7) ,RGBME(0,0,*(cptr+1)) ,COLOURADD ,*(cptr+2) ,32 ,-32 ,511,-255 ,511,-255 ,0,0 ,0,0,*(cptr+3),  15,15,63 ) ;
		cptr+=4 ;
	}
	ptr = splashspritestab ;
	for ( lp=0 ; lp<5 ; lp++ )
	{
		insert_fxsprite(x+(*ptr),y+(*(ptr+1)),z,0,0,0,0,*(ptr+2),(uchar *)*(ptr+3),SPRTYPE(FXSPR_POLY,TRANS,COLOURADD,FXSPR_ONFLR)+RGBME(16,16,32),0) ;
		ptr+=4 ;
	}
	if ( ripple == 1 )
	{
		for ( lp= TF(1.0) ; lp<= TF(1.5) ; lp+= TF(0.5) )
		{
			BLASTME(x,y,z ,TF(4),TF(0), lp,lp, 8,16,32, 32,16,	S_BLAST,	BLAST_ONFLR,NO_DET) ;
		}
	}
}

void	explode_me(FIXED xyz[XYZ],long rgb)
{
long	lp ;

	SPU_PlayDefault_XYZ(SFX_GENERALEXPLOSION,xyz);
	draw_sprite(xyz[X],xyz[Y],xyz[Z],S_FLARE,TF(2.5),rgb+DRAWSPRTYPE(TRANS,COLOURADD)) ;
	for ( lp=0 ; lp<2 ; lp++ )
		insert_spark( 4 ,xyz[X],xyz[Y],xyz[Z] ,SPARKWH(3,3,1,1) ,rgb ,RGBME(16,0,16) ,COLOURADD ,2 ,32 ,0 ,127,-64 ,127,-64 ,127,-64 ,0,0,0,  127,127,127 ) ;
	insert_fxsprite(xyz[X],xyz[Y],xyz[Z], 0,0,0, NOGRAV, TF(1.2) ,explode1atab, SPRTYPE(FXSPR_FLAT,TRANS,COLOURADD,0)+rgb ,0);
	for ( lp = 0 ; lp<6 ; lp++ )
	{
		insert_fxsprite(xyz[X],xyz[Y],xyz[Z], ((random()&15)-7)<<14,((random()&15)-7)<<14,((random()&15)-7)<<14, NOGRAV, TF(0.8)+(random()&16383) ,explode1atab, SPRTYPE(FXSPR_FLAT,TRANS,COLOURADD,0)+rgb ,0);
		insert_fxsprite(xyz[X],xyz[Y],xyz[Z], ((random()&15)-7)<<15,((random()&15)-7)<<15,((random()&15)-7)<<15, NOGRAV, TF(0.4)+(random()&16383) ,explode1atab, SPRTYPE(FXSPR_FLAT,TRANS,COLOURADD,0)+rgb ,0);
	}
}




