#include "string.h"
#include "stdlib.h"
#include "stdio.h"
#include "math.h"
#include "exec/types.h"
#include "exec/nodes.h"
#include "exec/lists.h"
#include "exec/memory.h"
#include "intuition/intuition.h"
#include "iff/ifflib.h"
#include "proto/all.h"

#define CMAX 40

extern struct Screen *OpenScreen();

struct GfxBase *GfxBase = NULL;
struct IntuitionBase *IntuitionBase = NULL;
struct Library *IFFBase = NULL;

struct RastPort *rp;
struct ViewPort *vp;
struct Screen *screen;
struct NewScreen ns = {
	0,0,	/* screen XY origin relative to View */
	320,200,	/* screen width and height */
	5,	/* screen depth (number of bitplanes) */
	0,1,	/* detail and block pens */
	NULL,	/* display modes for this screen */
	CUSTOMSCREEN,	/* screen type */
	NULL,	/* pointer to default screen font */
	"Julia",	/* screen title */
	NULL,	/* first in list of custom screen gadgets */
	NULL	/* pointer to custom BitMap structure */
};


UWORD Palette[] = 
  {
  0x0, 0xFFF, 0xD81, 0xC70, 0xB61, 0xA52, 0x943, 0x834,
  0x725, 0x616, 0x507, 0x418, 0x329, 0x23A, 0x14B, 0x5C,
  0x16D, 0x27E, 0x38F, 0x49E, 0x5AD, 0x6BC, 0x7CB, 0x8DA,
  0x9E9, 0xAF8, 0xBE7, 0xCD6, 0xDC5, 0xEB4, 0xFA3, 0xE92,
  };
  
void initview()
{
if (!(GfxBase = (struct GfxBase *) OpenLibrary("graphics.library",0)))
   {
   printf("Can't open graphics library \n");
   exit(0);
   }
if (!(IntuitionBase = (struct IntuitionBase *)
                      OpenLibrary("intuition.library",0)))
   {
   printf("Can't open Intuition library \n");
   exit(0);
   }
if (!(IFFBase = (struct Library *) OpenLibrary("iff.library",0)))
   {
   (void) printf("Copy the iff.library to your LIBS: directory!\n");
   exit(10);
   }

screen = OpenScreen(&ns);
if (screen == NULL)
   {
   printf("Can't open screen \n");
   exit(0);
   }
rp = &screen->RastPort;
vp = &screen->ViewPort;

LoadRGB4(vp,Palette,(short)32);

SetDrMd(rp,JAM1);
}

int inset(x,y,l)
double x,y,l;
{
double e,x1,y1,size;
int c;

c = 0; size = 0;
do
  {
  e = exp(y);
  x1 = l*cos(x)*(e+1/e)/2;
  y1 = -l*sin(x)*(e-1/e)/2;
  x = x1; y = y1;
  size = x*x + y*y;
  c++;
  }
  while ((c<CMAX) && (size<50));
return(c);
}


/***** main program *****/

void main()
{
int i,j,p,fn,num;
double xmax,xmin,ymin,cr,ci,cro,dx,dy,l,dl;
char  filename[80];
UBYTE flags = 1;

/** start **/
xmax = 1.2;
xmin = -1.2;
printf("Exploding julia set generator - by Mike Danielsen 10/23/90\n");
printf(" Starting lambda - "); scanf("%lf",&l);
printf(" Lambda decrement - "); scanf("%lf",&dl);
printf(" Number of plots - "); scanf("%d",&num);
dx = (xmax - xmin) / 321.;
dy = dx * 8.0/7.0;
ymin = -100 * dy; 

initview();
for (fn=0;fn<num;fn++)
{
cr = xmin;
ci = ymin;
cro = cr;
for (i=0;i<100;i++)
   {
   for (j=0;j<160;j++)
      {
      p = inset(cr,ci,l);
      if (p == CMAX) p = 0; 
        else p = (p % 30) + 2;
      SetAPen(rp,p);
      WritePixel(rp,j,i);
      WritePixel(rp,319-j,i);
      WritePixel(rp,j,199-i);
      WritePixel(rp,319-j,199-i);
      cr += dx;
      }
   cr = cro;
   ci += dy;
   }
sprintf(filename,"lcos.plot.%6.4f",l);
if(!(SaveBitMap(filename,rp->BitMap,(WORD *)Palette,flags)))
  {
  printf(" save failed\n");
  exit(0);
  }
l -= dl;  
}
  
if(screen) CloseScreen(screen);
if(IntuitionBase) CloseLibrary(IntuitionBase);
if(GfxBase) CloseLibrary(GfxBase);
if(IFFBase) CloseLibrary(IFFBase);

exit(TRUE);
}