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

#include	<exec/types.h>
#include	<exec/memory.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"

#define	MAX_LEVEL	8
#define MAX_ALT	256

#define		DEPTH	5
#define	WIDTH	320
#define	HEIGHT	256

extern	char	*pr_buff;

/*UBYTE	far	t[(1<<MAX_LEVEL)+1][(1<<MAX_LEVEL)+1];*/
char	**t;

char	p_ver[]="$VER: Plasma_Cycle v1.0 (06/02/93)";

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

USHORT  depth=2;
int	decalage;
int	offx,offy;
USHORT	width,height;

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

char	*p_text_info="      'Plasma_Cycle'\n\n\nThis effect have been inspired by\n  an old programm that I have,in\noberon I think...Some code have been\ntaken from this!\n";

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

#define    SIZE  8
#define        COUNT 		(1 << SIZE)

UWORD Range[] = {32, 32, 32, 22, 14, 8, 4, 2};

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

UWORD *Cell;

int	pas_min;

struct tom_gadget my_gadg[]={
	{"_Resolution",	SCREEN,	125,14,139,14,0, 0,0,0,0},
/*	{"_Altitude",SLIDER,	125,14,139,9,1, 1,MAX_ALT,0,0},*/
	{0,		END_LISTE,  0,  0,   0, 0, 0,0,0,0,0}
};
WORD	cx,cy;

unsigned	int	seed;
void	rotate();


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

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

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

UWORD	random(int	ampl)
{
	return(my_rand()%ampl);
}


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

void	SetCell(UWORD l,UWORD c,UWORD val)
{
	if((l<height)&&(c<width)){
		*(Cell+(l*width+c))=val;
	}
}

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

UWORD ValCell(UWORD l,UWORD c)
{
	return (*(Cell+(l*width+c)));
}

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

void	set(UWORD l,UWORD c,UWORD size,int height)
{
    UWORD rang;

    rang = Range[size];
    height = height + random(rang) - (rang + 1) / 2;
    if(height<1)height=1;
    SetCell(l,c,height);
    MultiPlot(s,(WORD)(offx+c),(WORD)(offy+l),height);
}

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

/*
 * grow - grow the basic scenery heights.
 */

void	grow()
{
    UWORD l,c,i,step,nextStep,l1;
    UWORD l2,c1,c2;

    SetCell(0,0,0);
    step = COUNT;
    for(i=0;i<SIZE;i++){
	nextStep = step / 2;
	for(l=0;(l<height)&&(tst_end()==FALSE);l+=step){
	    l1 = l + nextStep;
	    l2 = l + step;
	    if( l2 == height){
		l2 = 0;
	    }
	    for(c=0;c<width;c+=step){
		c1 = c + nextStep;
		c2 = c + step;
		if(c2 == width){
		    c2 = 0;
		}
		set(l, c1, i, (ValCell(l,c) + ValCell(l,c2) + 1) / 2);
		set(l1, c, i, (ValCell(l,c) + ValCell(l2,c) + 1) / 2);
		set(l1, c1, i, (ValCell(l,c) + ValCell(l,c2) +
				ValCell(l2,c) + ValCell(l2,c2) + 2) / 4);
	    }
	}
	step = nextStep;
    }
}


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

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	rotate()
{
	static	unsigned	int	compt=0;
	unsigned	int	n,i;

	n=compt;
	for(i=1;i<depth;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++;
}


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

void	dark()
{
  int	i;
  USHORT	n,j;
  ULONG	did;
  struct	tom_gadget	*pg;

  pg=&my_gadg[0];
  /* 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{


	  /******************************************************/
	  /* We find the resolution with the maximum of colors! */
	  /******************************************************/

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

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

	  s = OpenScreen(&Screen);
 }
 if(!s)return;
 FreeSprite (0);
 GfxBase->SpriteReserved|=1;
 rp = &(s->RastPort);
 depth=1<<rp->BitMap->Depth;

 /****************************************************************/
 /* We create a color map, with transitions, in the range of all */
 /* the availables colors					 */
 /****************************************************************/

 if(depth>NB_COL*4){
	max_color=depth;
 }else{
	max_color=depth*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;

/*
  offx=(width-COUNT)/2;
  offy=(height-COUNT)/2;
*/
  offx=0;
  offy=0;

  Cell=(UWORD *)AllocMem(width*height*sizeof(WORD),MEMF_CLEAR);
  if(Cell!=0){
	LoadRGB4(&s->ViewPort,ScreenColors,depth);

	while(tst_end()==FALSE){
		SetRast(rp,0);
/*
		for(i=0;i<MAX_LEVEL;i++){
			for(j=0;j<MAX_LEVEL;j++){
				t[i][j]=0;
			}
		}
		pas_min=1;
		cx=0;
		cy=0;
		calcul(0,0,1<<MAX_LEVEL);
		cx+=1<<MAX_LEVEL;
		calcul(0,0,1<<MAX_LEVEL);
*/
		grow();

		for(i=0;(i<200)&&(tst_end()==FALSE);i++){
			WaitTOF();
			WaitTOF();
			rotate();
		}
	}
	FreeMem(Cell,width*height*sizeof(WORD));
   }
  }
  if(ScreenColors)FreeMem(ScreenColors,sizeof(UWORD)*(max_color));
  CloseScreen(s);
   
}

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

void	proc_end()
{
}

