 /* Fichier star.dark.c				*/
/* Module appele par le programme principal	*/
/* pour effectuer un effet defini..appele par	*/
/* loadseg					*/

#include	<exec/types.h>
#include	<dos/dos.h>
#include	<intuition/intuition.h>
#include	<intuition/gadgetclass.h>
#include	<graphics/gfx.h>
#include	<graphics/gfxmacros.h>
#include	<graphics/gfxbase.h>
#include	<graphics/rastport.h>
#include	<clib/exec_protos.h>
#include	<clib/intuition_protos.h>
#include	"/includes/struct.h"
#include	"/includes/tom_gadget.h"

struct	RastPort	*rp;
struct	Screen	*s;
extern	struct	appel_proc	*p_data_proc;
extern	struct	GfxBase	*GfxBase;

#define	WIDTH	320
#define	HEIGHT	256
#define	DEPTH	3

SHORT	width=WIDTH;
SHORT	height=HEIGHT;
SHORT	depth=2;
ULONG	did;

char	p_ver[]="$VER: FireWork v1.1 (12/02/93)";

char	*p_text_info=
"      FireWork v1.1\n"
"\n"
"  A pyrotechnic effects\n"
"wihout any need of firemen!!!\n"
"\n"
"  Look nice, especally with fast\n"
"computers....\n"
"\n"
"  @ Thomas Landspurg 93";

#define reg register
extern	void __asm MultiPlot(reg __a0 struct Screen *,reg __d0 WORD, reg __d1 WORD,reg __d2 WORD);

struct NewScreen    Screen = {
    0, 0, WIDTH,  HEIGHT, DEPTH, 0,0, 0, CUSTOMSCREEN, NULL, NULL ,NULL, NULL};

UWORD  ScreenColors[] = {
    0x000,
    0xF00,
    0xFFF,
    0xF0F,
    0x0FF,
    0xF98,
    0x8AF,
    0xFB0,
    0xFC0,
    0xFD0,
    0xFE0,
    0xFF0,
    0xBF0,
    0x8F0,
    0x7D0,
    0x5B0,
    0x000,
    0x490,
    0x360,
    0x340,
    0x444,
    0x555,
    0x666,
    0x777,
    0x888,
    0x999,
    0xAAA,
    0xBBB,
    0xCCC,
    0xDDD,
    0xEEE,
    0xFFF,
    0x000 };

#define	COEF	100
#define	ACC	3
#define	MAX_FIRE 200
#define	MAX_ECLAT 25
#define	MAX_NB	51

int	max_nb;
int	nb_fire;

struct tom_gadget my_gadg[]={
	{"_Number"	,SLIDER,	100,20,139,9,20, 10,MAX_NB-1,0,0},
	{0,		END_LISTE,  0,  0,   0, 0, 0,0,0,0,0}
};


#define	NONE	0
#define	FIRE	1
#define	ECLAT	2
#define	NB_OLD	10

typedef	struct	fire{
	int	type;
	int	time;
	int	x,y;
	int	tx[NB_OLD];
	int	ty[NB_OLD];
	int	sx,sy;
	int	color;
};

struct	fire	tab_fire[MAX_FIRE+1];
unsigned	int	seed;

/********************************************************** my_rand() ***/

unsigned        int     my_rand()
{
        
        seed=25173*seed+138490;
        return(seed);
}

/********************************************************** new_fire() ***/

void	new_fire()
{
	int	i;
	register struct	fire	*f;
	f=tab_fire;
	i=0;
	while((i<MAX_FIRE)&&(f->type!=NONE)){
		i++;
		f++;
	}
	if(i!=MAX_FIRE){
		f->type=FIRE;
		f->x=my_rand()%(width*COEF);
		f->y=0;
		f->color=my_rand()%((1<<DEPTH)-1)+1;
		f->sx=my_rand()%(100)-50;
		f->sy=my_rand()%(200)+200;
		f->time=my_rand()%100+100;
		nb_fire++;

	}
}

/********************************************************** eclat() ***/

void	eclat(struct	fire	*f)
{
	struct	fire	*tf;
	int	n;

	tf=tab_fire;
	for(n=0;(n<MAX_ECLAT)&&(tf!=&tab_fire[MAX_FIRE]);tf++){
		if(tf->type==NONE){	
			tf->type=ECLAT;
			tf->x=f->x;
			tf->y=f->y;
			tf->color=f->color;
			tf->sx=my_rand()%50-25;
			tf->sy=my_rand()%100-50;
			tf->time=my_rand()%10+50;
			n++;
		}
	}
	nb_fire--;
}

/********************************************************** aff_trainee() ***/

void	aff_trainee(struct	fire	*f,int nb)
{
	int	i;
	SetAPen(rp,0);
	MultiPlot(s,(WORD)(f->tx[nb-1]),(WORD)(f->ty[nb-1]),0);
	for(i=nb-1;i>=1;i--){
		f->tx[i]=f->tx[i-1];
		f->ty[i]=f->ty[i-1];
	}
	if(f->time>nb){
		f->tx[0]=f->x/COEF;
		f->ty[0]=height-f->y/COEF;
		MultiPlot(s,(WORD)(f->tx[0]),(WORD)(f->ty[0]),f->color);
	}
}

/********************************************************** main_fire() ***/

void	main_fire()
{
	int	i,n;

	register struct	fire	*f;

	if(nb_fire<max_nb){
		if((my_rand()%100>90)){
			new_fire();
		}
	}
	n=0;
	f=tab_fire;
	for(i=0;i<MAX_FIRE;i++){
		switch(f->type){
		   case NONE:
			break;
		   case FIRE:
			n++;
			if(f->time==0){
				eclat(f);
				f->type=NONE;
			}else{
				f->x+=f->sx;
				f->y+=f->sy;
				f->sy-=ACC;
				f->time--;
				aff_trainee(f,2);
			}
			break;
		   case ECLAT:
			n++;
			if(f->time==0){
				f->type=NONE;
			}else{
				f->x+=f->sx;
				f->y+=f->sy;
				f->sy-=1;
				f->time--;
				aff_trainee(f,NB_OLD-1);
			}
			break;
		}
		f++;
	}
}


/********************************************************** dark ***/

void	dark()
{
	int	d,i;

	depth=2;
	width=0;
	find_res((SHORT)TRUE,&depth,&width,&height,&did);

	Screen.Width=width;
	Screen.Height=height;
	Screen.ViewModes=did;
	if(depth<2)return;

        if ( NOT( s = OpenScreen(&Screen)))
        return;

	FreeSprite (0);
	GfxBase->SpriteReserved|=1;
	rp = &(s->RastPort);
	LoadRGB4(&s->ViewPort,ScreenColors,(1<<DEPTH));

	SetRast(rp,0);
	max_nb=my_gadg[0].value;
	nb_fire=0;

	for(i=0;i<MAX_FIRE;i++){
		tab_fire[i].type=NONE;
	}
	while(tst_end()==FALSE){
		WaitTOF();
		main_fire();
	}
	DCloseScreen(s);
}

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

void	proc_init()
{
        seed=VBeamPos();
}
void	proc_save()
{
}

void	proc_end()
{
}

