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

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

char	*p_text_info="   Mistifiy\n\nBased on a Window's effect";

struct	RastPort	*rp;
struct	Screen	*s;
extern	struct	GfxBase	*GfxBase;
#define	WIDTH	320
#define	HEIGHT	256

UWORD	width=WIDTH;
UWORD	height=HEIGHT;

#define	MAX_NB	4

UWORD  ScreenColors[]={
	0x000,
	0x0f0,
	0xf00,
	0x00f};

#define	NB_PT	4
#define NB_OLD	5
#define MAX_SPEED 10

int	speed;

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

struct tom_gadget my_gadg[]={
	{"_Numbers",SLIDER,	101,15,135,9,2, 1,MAX_NB-1,0,0},
	{"_Speed",SLIDER,	101,30,135,9,6, 3,MAX_SPEED,0,0},
	{"_Resolution",	SCREEN,	101,50,135,12,0, 0,0,0,0},
	{0,		END_LISTE,  0,  0,   0, 0, 0,0,0,0,0}
};

typedef	struct	pt{
	int	x,y;
	int	old_x[NB_OLD],old_y[NB_OLD];
	int	vx,vy;
};
struct	pt	tab_pt[MAX_NB*NB_PT];

int	d;

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

void	rotate()
{
    static	unsigned	int	compt=0;
    static	unsigned	int	c=100;
    UWORD	n,i,r,g,b,s2;

    c++;
    if(c==100){
	c=0;
	n=compt;
	for(i=1;i<d;i++){
		n=n%31;
		s2=ScreenColors[n+1];
		r=s2>>8;
		g=(s2>>5)&0x0f;
		b=s2&0x0f;
		SetRGB4(&(s->ViewPort),i,r,g,b);
		n+=5;
	}
	compt++;
   }
}

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

void	dark()
{
  int	i,j,n,color;
  struct	pt *t;
  UWORD		depth;
  struct	tom_gadget	*pg;

  pg=&my_gadg[2];
  /* With WB2.0 or higher, we use facilities of the intuition lib. */
  /* to open screen (overscan...)			           */
  if((GfxBase->LibNode.lib_Version>=37)&&(pg->d3!=0)){
	 s=OpenScreenTags(NULL,
			   SA_Width,(ULONG)pg->d1,
			   SA_Height,(ULONG)pg->d2,
                           SA_Depth,(ULONG)pg->d3,
			   SA_Overscan,(ULONG)pg->value,
                           SA_DisplayID,(ULONG)pg->p_data,
                           SA_Quiet,TRUE,TAG_DONE);
	 width=pg->d1;
	 height=pg->d2;
   }else{
    s = OpenScreen(&Screen);
   }
   if ( s ){

	FreeSprite (0);
	GfxBase->SpriteReserved|=1;
	rp = &(s->RastPort);
	d=1<<(s->BitMap.Depth);

	depth=1<<rp->BitMap->Depth;

	LoadRGB4(&s->ViewPort,ScreenColors,4);
	SetRast(rp,0);

	speed=my_gadg[1].value;

	for(n=0;n<(my_gadg[0].value*NB_PT);n++){
		tab_pt[n].x=rand()%width;
		tab_pt[n].y=rand()%height;
		tab_pt[n].vx=rand()%10-5;
		tab_pt[n].vy=rand()%10-5;
		if((tab_pt[n].vx==0)&&(tab_pt[n].vy==0)){
			tab_pt[n].vx=5;
			tab_pt[n].vy=5;
		}
		for(i=0;i<NB_OLD;i++){
			tab_pt[n].old_x[i]=0;
			tab_pt[n].old_y[i]=0;
		}
	}
	n=0;
	i=n;

	while(tst_end()==FALSE){

		WaitTOF();
		rotate();

		for(n=0;n<(my_gadg[0].value*NB_PT);n++){
			tab_pt[n].x+=tab_pt[n].vx;
			if(tab_pt[n].x>=width){
				tab_pt[n].x=width-1;
				tab_pt[n].vx=-rand()%speed-1;
			}
			if(tab_pt[n].x<0){
				tab_pt[n].x=0;
				tab_pt[n].vx=rand()%speed+1;
			}

			tab_pt[n].y+=tab_pt[n].vy;
			if(tab_pt[n].y>=height){
				tab_pt[n].y=height-1;
				tab_pt[n].vy=-rand()%speed-1;
			}
			if(tab_pt[n].y<0){
				tab_pt[n].y=0;
				tab_pt[n].vy=rand()%speed+1;
			}
		}
		SetDrMd(rp,JAM1);
		color=0;
		for(n=0;n<(my_gadg[0].value);n++){
			SetAPen(rp,0);
			/*************************************/
			/* Affichage du carre le plus ancien */
			/*************************************/

			t=&tab_pt[n*NB_PT];
			Move(rp,t->old_x[0],t->old_y[0]);
			for(i=1;i<NB_PT;i++){
				t++;
				Draw(rp,t->old_x[0],t->old_y[0]);
			}
			t=&tab_pt[n*NB_PT];
			Draw(rp,t->old_x[0],t->old_y[0]);

			/*******************************/
			/* Decalage de coord d'un cran */
			/*******************************/

			t=&tab_pt[n*NB_PT];
			for(i=0;i<NB_PT;i++){
				for(j=0;j<NB_OLD-1;j++){
					t->old_x[j]=t->old_x[j+1];
					t->old_y[j]=t->old_y[j+1];
				}
				t->old_x[NB_OLD-1]=t->x;
				t->old_y[NB_OLD-1]=t->y;
				t++;
			}

			/******************************/
			/* Affichage du nouveau carre */
			/******************************/
			color=n+1;
			if((color%d)==0){
				color=1;
			}
			SetAPen(rp,color);
			
			t=&tab_pt[n*NB_PT];
			Move(rp,t->x,t->y);
			for(i=1;i<NB_PT;i++){
				t++;
				Draw(rp,t->x,t->y);
			}
			t=&tab_pt[n*NB_PT];
			Draw(rp,t->x,t->y);
		}
	}
   DCloseScreen(s);
   }
}

void	proc_init()
{
}
void	proc_save()
{
}
void	proc_end()
{
}

