/* OpalBrot.c  try and do a fractal pattern on OpalVision */


#include <proto/all.h>
#include <opal/opallib.h>
#include <graphics/gfxbase.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>  /* lets give it something to REALLY Render */
#include <m68881.h>

#include "renderer.c"

#define   DISP_W   736
#define   DISP_H   476 /* hi-res screen */ 

__far UBYTE *Button = (UBYTE *)0xbfe001;	/* Nasty */
__far UWORD *RButton= (UWORD *)0xdff016; /* read right button */
        /* bit 10, use dff016 for right */
    

struct GfxBase *GfxBase;

	/* external functions (int Renderer.c) */
/* prototypes go here */

BOOL Open_OpalScreen (ULONG Modes);
void Render_To_Opal (long Y, long Width, long Lines,
			UBYTE *Red, UBYTE *Green, UBYTE *Blue, BOOL Chunky);
void Opal_Render_Finished (void);
void Close_Opal (void);
int  Mandel(double,double,long);

int maxiter=133; /* max # of iterations */

UBYTE RedPlane[1000];
UBYTE GreenPlane[1000];
UBYTE BluePlane[1000];

void main (void)
{
register long x,y;
double mx,my,xmin,xmax,ymin,ymax; /* mandlebrot data */ 
double xstep,ystep;
int it;
char c;
    xmin= -2.1; ymin= -1.3;    
    xmax=  0.8; ymax= 1.3;
	GfxBase = (struct GfxBase *) OpenLibrary ("graphics.library",0);
	if (!Open_OpalScreen (HIRES24|ILACE24|OVERSCAN24))
		{ puts  ("Can't open opalvision screeen\n");
		  exit (0);
	}
        
  /* entry point for multiple renders */ 
  /* init the variables */     
    xstep=(xmax-xmin)/(double) DISP_W; /* increment for each pixel */
    ystep=(ymax-ymin)/(double) DISP_H;
    mx=xmin;
    my=ymin;     
	for (y=0; y<DISP_H && (*Button &0x40); y++){  /*  LINE LOOP STARTS */
         mx=xmin; /* we must reset mx each line */
		 for (x=0; x<DISP_W; x++) /* PIXEL LOOP STARTS */
			{
              it=Mandel( mx,my, maxiter); /* do the brot calcs */  
              if (it==maxiter) {
                    RedPlane[x]=GreenPlane[x]=BluePlane[x]=0; }
              else {      
                RedPlane[x] = it*15 ; /* set pixels */
			    GreenPlane[x] = 255-(it*3);
			    BluePlane[x] = it*7 ; }
              
              mx+=xstep;
			}           /* PIXEL LOOP ENDS */
		  Render_To_Opal (y,DISP_W,1,RedPlane,GreenPlane,BluePlane,FALSE);
	      my += ystep; /* set for next line */
    	}   /* LINE LOOP ENDS, WE RENDER FIRST */
	Opal_Render_Finished ();
    printf("done %d %d \n",x,y);
    while (*Button &0x040)  { 
	    Delay (10L);
        
    } /* wait for button before exit */    
    AmigaPriority();
    printf(" Do you want to save it? (Y or N)");
    c=getch();
    if ( (c=='Y') || (c== 'y')) {
         if ( !OScrn) OScrn=VScrn; /* if virtual */
         SaveJPEG24( OScrn, "brot.jpg", NULL,75); /* save as jpeg */
        }
     printf("\n");    
	Close_Opal ();
}

int Mandel( cx, cy, maxit ) /* calculate mandelbrot iterations */
  double cx, cy;
  long   maxit;
  {
    register long   inum;
    register double x, y, x2, y2,temp;
    x = y = x2 = y2 = 0.0;
    inum = 0L;
    while( (inum < maxit)&& (( x2 + y2 )<  10000.0 ) )      {
        temp = x2 - y2 + cx;
        y *= 2.0 * x;
        y += cy;
        x = temp;
        x2 = x * x;
        y2 = y * y;
        ++inum;
         /* (( x2 + y2 )<  10000.0 ) */
    }
    return( inum );
}
 
