
// =============================================

#include "glover.h"
//#include "bff_load.h"
//#include "water.h"

//void Draw_Sceneries();
void Draw_RawRipple(SVECTOR *vec, LONG radius, ULONG colour,SPRITEX *sprite);


WATERSTR *waterlist = NULL;
AMBIENTSOUNDSTR *amb_soundlist = NULL;

RIPPLE ripples[MAXRIPPLES];
WAKE wakes[MAXWAKES];
DROPLET droplets[MAXDROPLETS];

SPRITEX *SPR_ripbase;
SPRITEX *SPR_wakebase;
SPRITEX *SPR_dropbase;
SPRITEX *SPR_bubbase;


WATERSTR *used_water;


/*-------------------------------*/
void	Draw_Ripples()
{
	RIPPLE *ripple=ripples;
	WAKE *wake=wakes;
	DROPLET *droplet=droplets;

 	while (ripple->next!=ripples)
 	{
		ripple=ripple->next;

		if(ripple->count >= 8)
		{
			Draw_RawRipple(&ripple->sv, ripple->scale>>8, 0x808080,SPR_ripbase);
		}
		else
		{
			int bri;
			bri = ripple->count << 4;	// 0...7 -> 0...0x707070
			Draw_RawRipple(&ripple->sv, ripple->scale>>8, bri | (bri<<8) | (bri<<16),SPR_ripbase);
		}
	}
 	while (wake->next!=wakes)
 	{
		wake=wake->next;

		if(wake->count >= 8)
		{
			Draw_RawRipple(&wake->sv, wake->scale>>8, 0x404040, SPR_wakebase);
		}
		else
		{
			int bri;
			bri = wake->count << 3;	// 0...7 -> 0...0x707070
			Draw_RawRipple(&wake->sv, wake->scale>>8, bri | (bri<<8) | (bri<<16),SPR_wakebase);
		}
	}
 	while (droplet->next!=droplets)
 	{
		VERT minivec;

		droplet=droplet->next;
		minivec.vx = droplet->pos.vx>>12;
		minivec.vy = droplet->pos.vy>>12;
		minivec.vz = droplet->pos.vz>>12;
		switch(droplet->sprno)
		{
		case 1:	// water bubbles
		case 2:
		case 3:
			Print3DSprite(SPR_bubbase+droplet->sprno-1,	&minivec,170, P3DS_ADD | 0x808080);
			break;

		default:	// splashes
			Print3DSprite(SPR_dropbase,	&minivec,170, P3DS_ADD | 0x808080);
			break;
		}
	}
}

// let's assume xz-flat alignment for now...
void Draw_RawRipple(SVECTOR *vec, LONG radius, ULONG colour,SPRITEX *sprite)
{
	LONG spritez[4];
//	LONG spritezn;
	VERT vect[4];
	POLY_FT4 *si;
	GsOTA 	*otptr;
	LONG spritezn;

// if (TOOMANYPOLYS(4*MAXPACKETSIZE,"Draw_RawRipple"))return;
// 0 1
// 2 3

	vect[0].vx = vec->vx - radius;
	vect[0].vz = vec->vz - radius;
	vect[1].vx = vec->vx - radius;
	vect[1].vz = vec->vz + radius;

	vect[2].vx = vec->vx + radius;
	vect[2].vz = vec->vz - radius;
	vect[3].vx = vec->vx + radius;
	vect[3].vz = vec->vz + radius;

	vect[0].vy = vect[1].vy = vect[2].vy = vect[3].vy = vec->vy;

	si = (POLY_FT4 *) GsOUT_PACKET_P;

// 	*(ULONG*)&si->r0=sprctrl.r|(sprctrl.g<<8)|(sprctrl.b<<16)|(GPU_COM_TF4<<24);
 	*(ULONG*)&si->r0=colour|(GPU_COM_TF4<<24);

	*(ULONG*)&si->u0=*(ULONG*)&(sprite)->u0;
	*(ULONG*)&si->u1=*(ULONG*)&(sprite)->u1;
	*(ULONG*)&si->u2=*(ULONG*)&(sprite)->u2;
	*(ULONG*)&si->u3=*(ULONG*)&(sprite)->u3;

	gte_ldv3c(&vect[0].vx);
	gte_rtpt();
	gte_stsxy3_ft4((ULONG*)si);
	gte_stsz3c(&spritez[0]);
	
	gte_ldv0(&vect[3].vx);
	gte_rtps();
	gte_stsxy(&si->x3);
	gte_stsz(&spritez[3]);


// Actually, now we're sorting water artificially backwards, this may well be wrong
/*
	spritezn = spritez[0];
	if(spritez[1]<spritezn) spritezn = spritez[1];
	if(spritez[2]<spritezn) spritezn = spritez[2];
	if(spritez[3]<spritezn) spritezn = spritez[3];
	spritezn >>= 2;
*/
	spritezn = (spritez[0]+spritez[1]+spritez[2]+spritez[3])>>4;

	si->clut = sprite->clut;
 	si->tpage = sprite->tpage|((SEMITRANS_ADD-1)<<5);

 	si->code=GPU_COM_TF4+2;

	if(spritezn > 2000)
		return;
	if(spritezn < 0)
		return;

//	spritezn = spritezn >> 1;	// (PolyList->shift
	if(spritezn > MAXOTZ)
		return;

	otptr=(GsOTA*)(PolyList->org+ spritezn);

	PUTPACKETINTABLE(si,otptr,POLYTF4_LEN);

	INCPOLYSDRAWN;
	si++;							//incr. packet building address by sizeof POLY_FT4
	GsOUT_PACKET_P=(PACKET*)si;		 	//return new packet building address
}



WATERSTR *waterCreate()
{
	WATERSTR *m;
	m = MALLOC(sizeof(WATERSTR),"water");
	memset(m,0,sizeof(WATERSTR));
	m->next = waterlist;
	waterlist = m;
	return m;
}
void waterFlush()	// hmmm
{
	int k;
	WATERSTR *water;
	AMBIENTSOUNDSTR *snd;

	while(waterlist)
	{
		water = waterlist->next;
		FREE(waterlist);
		waterlist = water;
	}

	while(amb_soundlist)
	{
		snd = amb_soundlist->next;
		FREE(amb_soundlist);
		amb_soundlist = snd;
	}

	for (k=0; k<MAXRIPPLES;k++)
		ripples[k].count=0;
	for (k=0; k<MAXWAKES;k++)
		wakes[k].count=0;
	for (k=0; k<MAXDROPLETS;k++)
		droplets[k].count=0;
	LINKLISTINIT(ripples[0]);
	LINKLISTINIT(wakes[0]);
	LINKLISTINIT(droplets[0]);

	SPR_ripbase = textureFindInAllBanks("AI_RIPPLE");	// ai_ripple now works ok
	SPR_wakebase = textureFindInAllBanks("AI_WAKE");
	SPR_dropbase = textureFindInAllBanks("AI_SPL01");
	SPR_bubbase = textureFindFrames("PSXBUB");

}

void waterParseToken(UBYTE *data)
{
	WATERSTR *water;
	int crc;
	VECTOR pos;
	VECTOR size;

	water = waterCreate();


	pos.vx = *(SHORT *)(data);
	pos.vy = *(SHORT *)(data+0x04);
	pos.vz = *(SHORT *)(data+0x08);
	size.vx = *(SHORT *)(data+0x0c);
	size.vy = *(SHORT *)(data+0x10);
	size.vz = *(SHORT *)(data+0x14);
	pos.vx = pos.vx<<12;
	pos.vy = pos.vy<<12;
	pos.vz = pos.vz<<12;
	size.vx = size.vx<<12;
	size.vy = size.vy<<12;
	size.vz = size.vz<<12;

	pos.vy = -(pos.vy + size.vy);
	pos.vz = -(pos.vz + size.vz);


	water->box_pos = pos;
	water->box_high.vx = pos.vx + size.vx;
	water->box_high.vy = pos.vy + size.vy;
	water->box_high.vz = pos.vz + size.vz;

/*
	water->box_pos.vx=*(short *)(*data+0);
	water->box_pos.vy=-(*(short *)(*data+4)+*(short *)(*data +16));
	water->box_pos.vz=-(*(short *)(*data+8)+*(short *)(*data +20));

	water->box_high.vx=water->box_pos.vx + *(short *)(*data+12);
	water->box_high.vy=water->box_pos.vy + *(short *)(*data+16);
	water->box_high.vz=water->box_pos.vz + *(short *)(*data+20);

	water->box_pos.vx = water->box_pos.vx << 12;
	water->box_pos.vy = water->box_pos.vy << 12;
	water->box_pos.vz = water->box_pos.vz << 12;

	water->box_high.vx = water->box_high.vx << 12;
	water->box_high.vy = water->box_high.vy << 12;
	water->box_high.vz = water->box_high.vz << 12;
*/
	water->level = - (*(short *)(data + 24)) <<12;
	water->target = water->level;
	water->vx =  *(short *)(data+28);
	water->vz = -*(short *)(data+32);

	water->tag = *(short *)(data+36);

	crc=*((u_short *)(data+38));
	crc|=(*((u_short *)(data+40)))<<16;

// 42...50 are the filename

	water->obj_pos.vx =  *(short *)(data+50)<<12;
	water->obj_pos.vy = -*(short *)(data+54)<<12;
	water->obj_pos.vz = -*(short *)(data+58)<<12;
//62 = &3e, and that's the correct size!

	water->model = BFF_IsCRCModelLoaded(crc, NULL);	// tbd - we need to auto-parse water tokens in lnd_psa
//	water->model = BFF_IsModelLoaded("WATER01", NULL);	// tbd - we need to auto-parse water tokens in lnd_psa
	water->active = 1;
}

// can cope with multiple waters with same tag
void waterSetDepth(int tag, int depth)
{
	WATERSTR *water;
//	DB("waterSetDepth %d %d\n",tag,depth);

	for(water = waterlist;water;water=water->next)
	{
		if(water->tag==tag)
		{
//			DB("(found)\n");

			water->target = depth;
		}
	}
}

// new for the psx - need to be able to turn off water objects once they're drained
// can call here with a speculative tag - no worries if it doesn't exist
void waterEnable(int tag, int enable)
{
	WATERSTR *water;
	AMBIENTSOUNDSTR *snd;
	for(water = waterlist;water;water=water->next)
	{
		if(water->tag==tag)
		{
			water->active = enable;
		}
	}
	for(snd = amb_soundlist;snd;snd=snd->next)
	{
		if(snd->def.tag==tag)
		{
			snd->enabled = enable;
			snd->time = 0;	// so it triggers straight away
		}
	}
}

void waterUpdate()
{
	WATERSTR *water;
	AMBIENTSOUNDSTR *snd;

	for(water = waterlist;water;water=water->next)
	{
		if(water->level!=water->target)
		{
			int d;
			int e;

			if(!(activeframe & 3))
			{
				VECTOR pos;
				int pitch;
				pos.vx = (water->box_pos.vx + water->box_high.vx) >>1;
				pos.vy = water->level;
				pos.vz = (water->box_pos.vz + water->box_high.vz) >>1;
				pitch=(DEFAULT_PITCH + (RANDOM256() & 127));
				sfxSetSamplePitch(globalFX,SFX_BUBBLES_2,pitch);
				sfxPlay3D(globalFX,SFX_BUBBLES_2,&pos);
			}


//			printf("water %d, targ %d\n",water->level>>12, water->target>>12);

			d = water->target-water->level;
			if(d > 4096 * 4) d = 4096 * 4;
			if(d <-4096*4) d =-4096*4;

			e = d * 7/8;
			if(e == 0)
				e = d;

			water->level += e;
			water->obj_pos.vy += e;

// tbd... adjust the box

		}
	}

//	DB("-----snds------\n");
	for(snd = amb_soundlist;snd;snd=snd->next)
	{
//		DB("snd\n");
		if(snd->enabled)
		{
			if(!snd->time)
			{
				sfxPlayAmbient(snd);
/*
				VECTOR pos;
				pos.vx = ((int)( snd->def.x)) << 12;
				pos.vy = ((int)(-snd->def.y)) << 12;
				pos.vz = ((int)(-snd->def.z)) << 12;

//				DB("ambient sound %d\n",snd->def.num);

				sfxPlayParsed(&pos,snd->def.num,snd->def.pitch,snd->def.volume);
*/
				snd->time = snd->def.delay + random(snd->def.rnddelay);
			}
			else
			{
				snd->time--;
			}
		}
	}
}

void waterDraw()
{
	WATERSTR *water;
	NEWMODEL *m;

	for(water = waterlist;water;water=water->next)
	{
/*
	printf("water %d -> %d, %d -> %d, %d-> %d\n",
		water->box_pos.vx>>12,water->box_high.vx>>12,
		water->box_pos.vy>>12,water->box_high.vy>>12,
		water->box_pos.vz>>12,water->box_high.vz>>12
		);
*/
		if(water->active)
		{
			m = water->model;
			if(m)
			{
				m->position.vx = water->obj_pos.vx>>12;
				m->position.vy = water->obj_pos.vy>>12;
				m->position.vz = water->obj_pos.vz>>12;
				lscapeDrawClipped(m, &GsWSMATRIX, LSCAPE_DRAWMODEL);
			}
		}
	}

}


// note - high-res position
void waterPlaySplash(VECTOR *pos, int vol)
{
	int dist;
	VECTOR bigvec;

	bigvec.vx = pos->vx << 12;
	bigvec.vy = pos->vy << 12;
	bigvec.vz = pos->vz << 12;


	if(world == ATLANTIS)
	{
		int i;
		i = RANDOM256() & 3;
		sfxPlayVol3D(levelFX, SFX_AT_SPLASH_SMALL1+i,&bigvec, vol);
	}
	else if (world == HUB)
	{
		int i;
		i = RANDOM256() & 3;
		sfxPlayVol3D(levelFX, SFX_HU_SPLASH_SMALL1+i,&bigvec, vol);
	}
	else if (world == PIRATES)
	{
		int i;
		i = RANDOM256() & 3;
		if(i == 3) i = 0;	// oops - only 3 splashes on pirates, otherwise we get too mank monkey noises
		sfxPlayVol3D(levelFX, SFX_PI_SPLASH_SMALL1+i,&bigvec, vol);
	}
	else if (world == CARNIVAL)
	{
		int i;
		i = RANDOM256() & 3;
		sfxPlayVol3D(levelFX, SFX_CA_SPLASH_SMALL1+i,&bigvec, vol);
	}
	else if(world == PREHISTORIC)
	{
		int i;
		i = (RANDOM256()-64)<<2;
// default DEFAULT_PITCH
		sfxSetSamplePitch(levelFX, SFX_PR_SPLASH, i+DEFAULT_PITCH);

		sfxPlayVol3D(levelFX, SFX_PR_SPLASH,&bigvec, vol);
	}
}

int waterDoSplashiness(VECTOR *in, int radius, int flags, int *waterheight)
{
	int rval;
	VECTOR small;

	used_water = NULL;

	if(flags & SPLASHY_WATERY)
	{
		rval = WATERYWATER;
		*waterheight = in->vy + (getHeightAt(in->vx <<12, in->vy << 12, in->vz << 12) >> 12) - 10;


	}
	else
	{
		rval = waterGetWaterInfo(in,radius,waterheight);
	}


	if(flags & SPLASHY_JUSTINFO)
	{
		if(rval == BELOWWATER && (flags & SPLASHY_BUBBLES) && RANDOM256() > 220)
		{
			small = *in;
			Start_Droplet(&small,NULL,1);
		}
		return rval;
	}

	if(rval == INWATER || flags & SPLASHY_WATERY)
	{
		small = *in;
		small.vy = *waterheight;

//		if((flags & 127)!= INWATER && (flags & 127)!= WATERYWATER)
		if((flags & 127)!= INWATER && !(flags & SPLASHY_WATERY))
		{
			waterPlaySplash(&small,256);
			Start_Splash(&small);
		}
		else if(!(flags & SPLASHY_MOVING) && RANDOM256() > 250)
		{
			Start_Ripple(&small,3000,15);	// big ripple occasionally when static
		}

		if ((flags & SPLASHY_MOVING))	// && ((frame & 1)==0))
		{
			Start_Wake(&small,4096/2,15);

			if(RANDOM256() > 220)
			{
				Start_Droplet(&small,NULL,0);
			}
		}

	}
	else if(rval == BELOWWATER && (flags & SPLASHY_BUBBLES) && RANDOM256() > 220)
	{
		small = *in;
		Start_Droplet(&small,NULL,1);
	}

	return rval;
}


// ah. in AND out are all littlenumbers
int waterGetWaterInfo(VECTOR *in, int radius, int *waterheight)
{
	WATERSTR *water;
	VECTOR bigin;
	int in_water;

	bigin.vx = in->vx<<12;
	bigin.vy = in->vy<<12;
	bigin.vz = in->vz<<12;

	used_water = NULL;
	in_water = NOWHERENEARWATER;

	for(water = waterlist;water;water=water->next)
	{
		if(
			   bigin.vx > water->box_pos.vx
			&& bigin.vx < water->box_high.vx
			&& bigin.vz > water->box_pos.vz
			&& bigin.vz < water->box_high.vz
			&& bigin.vy > water->box_pos.vy -(radius<<12)
			&& bigin.vy < water->box_high.vy+(radius<<12)
			)
		{
			used_water = water;

			*waterheight = water->level >> 12;
			in_water =INWATER;
		}
	}

	if(in_water != INWATER)
		return NOWHERENEARWATER;

	if(in->vy + radius < *waterheight)
	{
		return ABOVEWATER;
	}
	else if(in->vy - radius > *waterheight)
	{
		return BELOWWATER;
	}
	return INWATER;
}







void	Start_Ripple(VECTOR *vector,ULONG scale,UBYTE count)
{
	ULONG i;
	ULONG lowestval=0xffff;
	RIPPLE *lowest=&ripples[1];
	RIPPLE *ripple=&ripples[1];
//  	printf("ADD RIPPLE\n");

	for (i=1;i<MAXRIPPLES;i++)
	{			
		if (ripple->count==0)
		{
fillripple:	ripple->sv.vx = vector->vx;
			ripple->sv.vy = vector->vy;
			ripple->sv.vz = vector->vz;
		   	ripple->scale=scale;
			ripple->count=count;
		   	LINKLISTADD(ripple,ripples[0]);
			return;
		}
		else
		{
			if (ripple->count<lowestval)
			{
			   lowestval=ripple->count;
			   lowest=ripple;
			}
		}
		ripple++;
	}				  
//	printf("ran out of ripples\n");
	ripple=lowest;
   	LINKLISTSUB(ripple);
	goto fillripple; //go back and use lowest slot
}

// fling a water droplet into the air in a random direction
void Start_Droplet(VECTOR *vector, VECTOR *base_vel, int type)
{
	ULONG i;
	ULONG lowestval=0xffff;
	DROPLET *lowest=&droplets[1];
	DROPLET *droplet=&droplets[1];

	for (i=1;i<MAXDROPLETS;i++)
	{			
		if (droplet->count==0)
		{
filldroplet:
			droplet->pos.vx = vector->vx<<12;
			droplet->pos.vy = vector->vy<<12;
			droplet->pos.vz = vector->vz<<12;

			if(base_vel)
			{
				droplet->vel.vx = base_vel->vx + ((RANDOM256()-128) <<5);
				droplet->vel.vy = base_vel->vy + ((RANDOM256()-128) <<5);
				droplet->vel.vz = base_vel->vz + ((RANDOM256()-128) <<5);
			}
			else
			{
				if(!type)	// watersplash
				{
					droplet->pos.vy -= 5*4096;
					droplet->vel.vx = (RANDOM256()-128) <<6;
					droplet->vel.vy = -4096 * 6 + ((RANDOM256()-128) <<4);
					droplet->vel.vz = (RANDOM256()-128) <<6;
					droplet->sprno = 0;
				}
				else		// waterbubble
				{
					droplet->pos.vy -= 5*4096;
					droplet->vel.vx = ((RANDOM256()-128) <<5);
					droplet->vel.vy = 0;
					droplet->vel.vz = ((RANDOM256()-128) <<5);
				}
			}

			if(!type)
			{
				droplet->sprno = 0;
			}
			else
			{
				droplet->sprno = (RANDOM256() % 3)+1;
			}

			droplet->count=50;
			droplet->type = type;
		   	LINKLISTADD(droplet,droplets[0]);
			return;
		}
		else
		{
			if (droplet->count<lowestval)
			{
			   lowestval=droplet->count;
			   lowest=droplet;
			}
		}
		droplet++;
	}				  
//	printf("ran out of droplets\n");
	droplet=lowest;
   	LINKLISTSUB(droplet);
	goto filldroplet; //go back and use lowest slot
}

void Start_Splash(VECTOR *vector)
{
	Start_Ripple(vector,3000,15);	// big ripple
	Start_Droplet(vector,NULL,0);	// five droplets which will spawn little ripples
	Start_Droplet(vector,NULL,0);
	Start_Droplet(vector,NULL,0);
	Start_Droplet(vector,NULL,0);
	Start_Droplet(vector,NULL,0);
}


void	Start_Wake(VECTOR *vector,ULONG scale,UBYTE count)
{
	ULONG i;
	ULONG lowestval=0xffff;
	WAKE *lowest=&wakes[1];
	WAKE *wake;
//  	printf("ADD wake\n");


	wake=wakes;
 	while (wake->next!=wakes)
	{
		USHORT dx;
		USHORT dz;
		dx = (USHORT)((wake->sv.vx -vector->vx) + 25);
		dz = (USHORT)((wake->sv.vz -vector->vz) + 25);
		if(dx < 50 && dz < 50)	// unsigned, remember, so -ve numbers are extreme +ve ones
			return;
		wake=wake->next;
	}



	wake=&wakes[1];
	for (i=1;i<MAXWAKES;i++)
	{			
		if (wake->count==0)
		{
fillwake:	wake->sv.vx = vector->vx;
			wake->sv.vy = vector->vy;
			wake->sv.vz = vector->vz;
		   	wake->scale=scale;
			wake->count=count;
		   	LINKLISTADD(wake,wakes[0]);
			return;
		}
		else
		{
			if (wake->count<lowestval)
			{
			   lowestval=wake->count;
			   lowest=wake;
			}
		}
		wake++;
	}				  
//	printf("ran out of wakes\n");
	wake=lowest;
   	LINKLISTSUB(wake);
	goto fillwake; //go back and use lowest slot
}

/*-------------------------------*/
void	Update_Ripples()
{
	RIPPLE *ripple=ripples;
	WAKE *wake=wakes;
	DROPLET *droplet = droplets;
	VECTOR minivec;
	int water, wh;

 	while (ripple->next!=ripples)
	{
		ripple=ripple->next;
		ripple->count--;
		ripple->scale+=256;
		if (ripple->count==0)
			LINKLISTSUB(ripple);
	}
 	while (wake->next!=wakes)
	{
		wake=wake->next;
		wake->count--;
		wake->scale+=128;
		if (wake->count==0)
			LINKLISTSUB(wake);
	}
 	while (droplet->next!=droplets)
	{
		droplet=droplet->next;
		ADDVECTOR(&droplet->pos,&droplet->pos,&droplet->vel);
//		printf("droplet vel = %d %d %d\n",droplet->vel.vx,droplet->vel.vy,droplet->vel.vz);



		minivec.vx = droplet->pos.vx>>12;
		minivec.vy = droplet->pos.vy>>12;
		minivec.vz = droplet->pos.vz>>12;
		water = waterGetWaterInfo(&minivec, 4, &wh);

		switch(droplet->type)
		{
			case 1:	// water bubble rises (don't decrease count)
				droplet->vel.vy -= gravity/2;
				droplet->vel.vx = (droplet->vel.vx * 4000) >>12;
				droplet->vel.vz = (droplet->vel.vz * 4000) >>12;
				if(water != BELOWWATER)
				{
					minivec.vy = wh;
//					waterPlaySplash(&minivec,64);

					Start_Ripple(&minivec,1024,12);	// lickle ripple
					droplet->count = 0;
				}
				break;


			case 0:	// droplet falls
			default:
				droplet->count--;
				droplet->vel.vy += gravity;
				if(water == BELOWWATER || water == INWATER)
				{
					minivec.vy = wh;
					waterPlaySplash(&minivec,16);
					Start_Ripple(&minivec,1024,12);	// lickle ripple
					droplet->count = 0;
				}
				break;
		}
		if(!droplet->count)
		{
			LINKLISTSUB(droplet);
		}
	}
}

// It's linked-list-tastic, mate
// (Incidentally, the reason the LND ambients are in here is coz the first use is the AT1 waterfall
// Note, the src is only guaranteed to be *2* aligned, not *4*
void waterParseSound(LNDAMBIENTSOUNDDEFSTR * def)
{
	AMBIENTSOUNDSTR *snd;

	snd = MALLOC(sizeof(AMBIENTSOUNDSTR),"ambsnd");
	memcpy(&snd->def,def,sizeof(LNDAMBIENTSOUNDDEFSTR));
	snd->next = amb_soundlist;
	snd->time = snd->def.delay + random(snd->def.rnddelay);
	snd->enabled = 1;
	amb_soundlist = snd;
}


