 /* 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/gfxbase.h>
#include <graphics/gfxmacros.h>
#include <graphics/rastport.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_ver[]="$VER: Line2 v1.1 (28/02/93)";

char	*p_text_info="   Effect line\n\nJust show you lines moving\non your screen...\nYou can choose to add\nhorizontal or vertical\nsymetry\nV1.1 By Thomas Landspurg\n";

struct	RastPort	*rp;
struct	Screen	*s;

#define	WIDTH	320
#define	HEIGHT	256
UWORD	width=WIDTH;
UWORD	height=HEIGHT;
UWORD	width2,height2,width3,height3;

#define	MAX_SPEED	20
#define	MAX_NB	100

UWORD  *ScreenColors=0;
#define	NB_COL	10
int	max_color=10;
UWORD	CMap[NB_COL+1]={
    0xf00, 0xff0, 0xff8, 0xe50, 0xf00,
    0x0ff, 0x356, 0xf06, 0x00f, 0x0ff,
    0xfff
};
int	nb_col;

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

struct tom_gadget my_gadg[]={
	{"T_aille",SLIDER,	101,15,135,9,10, 10,MAX_NB-1,0,0},
	{"_Speed",SLIDER,	101,28,135,9,10, 10,MAX_SPEED,0,0},
	{"_Horizontal",	CHECKBOX,272,39,35,9,0, 0,0,0,0},
	{"_Vertical",	CHECKBOX,272,53,35,9,0, 0,0,0,0},
	{"_Resolution",	SCREEN,	  80,45,105,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	x2,y2;
};
struct	pt	tab_pt[MAX_NB];
extern	struct	GfxBase	*GfxBase;

void	Aff_line(rp,n)
struct	RastPort	*rp;
int	n;
{
	Move(rp,width2+tab_pt[n].x,height2+tab_pt[n].y);
	Draw(rp,width2+tab_pt[n].x2,height2+tab_pt[n].y2);

	if(my_gadg[3].value){
		Move(rp,width2-tab_pt[n].x ,height2+tab_pt[n].y);
		Draw(rp,width2-tab_pt[n].x2,height2+tab_pt[n].y2);
		if(my_gadg[2].value){
			Move(rp,width2-tab_pt[n].x ,height2-tab_pt[n].y);
			Draw(rp,width2-tab_pt[n].x2,height2-tab_pt[n].y2);
		}
	}
	if(my_gadg[2].value){
		Move(rp,width2+tab_pt[n].x ,height2-tab_pt[n].y);
		Draw(rp,width2+tab_pt[n].x2,height2-tab_pt[n].y2);
	}
}

/***************************************************************************/
void	rotate()
{
	static	unsigned	int	compt=0;
	unsigned	int	n,i;

    if((compt%4)==0){
	n=compt/4;
	for(i=1;i<nb_col;i++){
		n=n%max_color;
		SetRGB4(	&s->ViewPort,i,
				(ScreenColors[n+1]&0xf00)>>8,
				(ScreenColors[n+1]&0x0f0)>>4,
				(ScreenColors[n+1]&0x00f));
		n++;
	}
     }
     compt++;
}
/***************************************************************************/

UWORD	fade_one_digit(USHORT	n,USHORT	j,UWORD mask)
{
	register	UWORD	s,d;
	s=CMap[n]&mask;
	d=CMap[n+1]&mask;
	return(((s+(d-s)*j*NB_COL/max_color))&mask);
}
/*************************************************************************/

void	dark()
{
  int	d,i,n,j;

  struct	tom_gadget	*pg;

  pg=&my_gadg[4];
  /* 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);
	nb_col=1<<rp->BitMap->Depth;
	width2=width>>1;
	height2=height>>1;
	width3=width2*2/3;
	height3=height2*2/3;
	/****************************************************************/
	/* We create a color map, with transitions, in the range of all */
	/* the availables colors					 */
	/****************************************************************/

	if(nb_col>NB_COL*4){
		max_color=nb_col;
	}else{
		max_color=nb_col*4;
	}
	ScreenColors=(UWORD *)AllocMem(sizeof(UWORD)*(max_color),MEMF_CLEAR);
	if(ScreenColors){
		/* We create a fading ColorMap, with transition....*/
		n=0;
		j=0;
		for(i=1;i<max_color;i++){

			ScreenColors[i]= fade_one_digit(n,j,0xF00)
					|fade_one_digit(n,j,0X0f0)
					|fade_one_digit(n,j,0X00F);

			j++;
			if(j>=(max_color/NB_COL)){
				j=0;
				n++;
			}
		}
	}
	ScreenColors[0]=0;
	LoadRGB4(&s->ViewPort,ScreenColors,nb_col);

	FreeSprite (0);
	GfxBase->SpriteReserved|=1;
	rp = &(s->RastPort);
	d=1<<(s->BitMap.Depth);
	LoadRGB4(&s->ViewPort,ScreenColors,32);
	SetRast(rp,0);

	for(n=0;n<my_gadg[0].value;n++){
		tab_pt[n].x=0;
		tab_pt[n].y=0;
		tab_pt[n].x2=0;
		tab_pt[n].y2=0;
	}
	n=0;
	i=n;

	while(tst_end()==FALSE){
		rotate();
		i=(i+my_gadg[1].value)%6400;
		SetAPen(rp,0);
		Aff_line(rp,n);

		tab_pt[n].x=(int)((width2-1)*sin(2*i*2*PI/6400));
		tab_pt[n].y=(int)((height2-1)*cos(3*i*2*PI/6400));
		tab_pt[n].x2=(int)(width3*sin(5*i*2*PI/6400));
		tab_pt[n].y2=(int)(height3*cos(7*i*2*PI/6400));

		SetAPen(rp,(i/my_gadg[1].value)%31+1);
		Aff_line(rp,n);

		n=(n+1)%my_gadg[0].value;
	
	}
   DCloseScreen(s);
   }
  if(ScreenColors)FreeMem(ScreenColors,sizeof(UWORD)*(max_color));

}

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

