[net.micro.amiga] MAND.C Pt. 1 - Mandelbrot Set Repost

french@caip.RUTGERS.EDU (12/27/85)

From: "french robert%d.mfenet"@LLL-MFE.ARPA

These files were originally posted a few weeks ago, but due to a terminal
problem, some of the lines were mysteriously missing.  Hopefully I've got
it right this time!

--------------------------------------------------------------------------

Well guys, you asked for it, and here it is.  There are two parts to the
Mandelbrot Set Generator which must be linked together (instructions are
at the beginning of the file).  I don't have any of the documentation
written yet, so you're on your own for a while.  I'll upload it when I get
it finished.  I can't send files over 16K thru the net, so the first
section is sent as two files...just JOIN them together.  Right now, the
program seems to work without any problems, except for an occasional
mysterious crash and the problem with closing a window in the middle of
picture generation (see comments in MAND1.C).  Please send me any comments
or suggestions.

By the way, on a historical note, the "Mandelbrot Set" as related in
Scientific American is a little different from the u-Map implemented
here (as discussed in Mandelbrot's "The Fractal Geometry of Nature").
The main difference is the use of Z -> Z 2+C in Scientific American vs.
Z -> Z 2-u in the book and this program.  The primary effect is the reversal
of the picture across the Y axis.

Enjoy!

                 Robert French
                 French#Robert%d@LLL-MFE.ARPA

----------------- cut, cut, cut!  Take two.... ------------------
/*
                    MAND.C - Command parsing
            Mandelbrot's Self-Squared Dragon Generator
                    For the Commodore Amiga
                         Version 1.00

         Inspired by Scientific American, August/1985

           Corrections and improvements suggested by
                  The Fractal Geometry of Nature
     By Benoit Mandelbrot, W.H. Freeman and Company, 1983
          (Used to be Z=Z^2+C, now is Z=Z^2-u, etc.)

             Copyright (c) 1985, Robert S. French
                  Placed in the Public Domain

This program may be distributed free of charge as long as the above
notice is retained.

Please see the accompanying documentation for more information.

Send ANY problems or suggestions to the address in the <I>nformation
section.  Thank you!

Programs should be compiled with:

1> lc -i:include/ -i:include/lattice/ mand.c
1> lc -i:include/ -i:include/lattice/ mand1.c
1> alink :lib/Lstartup.obj+mand.o+mand1.o to mand lib :lib/lc.lib+:lib/amiga.lib

*/


/*------------------------*/
/* Lots of include files! */

#include <exec/types.h>
#include <exec/tasks.h>
#include <exec/libraries.h>
#include <exec/devices.h>
#include <devices/keymap.h>
#include <graphics/copper.h>
#include <graphics/display.h>
#include <graphics/gfxbase.h>
#include <graphics/text.h>
#include <graphics/view.h>
#include <graphics/gels.h>
#include <graphics/regions.h>
#include <hardware/blit.h>
#include <intuition/intuition.h>
#include <intuition/intuitionbase.h>
#include <stdio.h>


/*-------------------*/
/* Misc. definitions */

#define VERSION "1.00"
#define EVER ;;
#define MAXX 640         /* Maximum X resolution */
#define MAXY 400         /* Maximum Y resolution */
#define MAXMY 100        /* Maximum number of lines at MAXX resolution
                            before going virtual */
#define STARTY 10        /* Starting Y coordinate */

#define F_INTUITION 0x000001
#define F_GRAPHICS  0x000002
#define F_MATH      0x000004
#define F_MATHTRANS 0x000008
#define F_CONSOLE   0x000010
#define F_COLORTAB  0x000020
#define F_SETSTORE  0x000040


/*---------------------------------*/
/* Fast-Floating-Point Definitions */

extern   int     SPFix();
extern   int     SPFlt();
extern   int     SPCmp();
extern   int     SPTst();
extern   int     SPAbs();
extern   int     SPNeg();
extern   int     SPAdd();
extern   int     SPSub();
extern   int     SPMul();
extern   int     SPDiv();
 
extern   int     SPAtan();
extern   int     SPSin();
extern   int     SPCos();
extern   int     SPTan();
extern   int     SPSincos();
extern   int     SPSinh();
extern   int     SPCosh();
extern   int     SPTanh();
extern   int     SPExp();
extern   int     SPLog();
extern   int     SPPow();
extern   int     SPSqrt();
extern   int     SPTieee();
extern   int     SPFieee();

int MathBase,MathTransBase;


/*----------------------*/
/* Graphics definitions */

struct   GfxBase       *GfxBase;
struct   IntuitionBase *IntuitionBase;


/*----------------------------------*/
/* Miscellaneous Global Definitions */

union kludge {
   float f;
   int i;
} start_r,end_r,start_i,end_i;
int max_x,max_y,max_mem_y;
int max_count,color_inc,color_offset,color_set,color_mode,color_div;
int color_inset,func_num;

int v_starty,max_mem;
long v_offset;
UWORD *color_table,*v_mand_store;

int modified,want_read;

FILE *console,*v_fp = NULL,*redir_fp = NULL;

int cur_resource = NULL;


/*-------------*/
/* Here we go! */

main()
{
   FILE *fopen();
   char *fgets(),*stpblk();
   float cnvf();
   void anal_mand(),wait_close();

   int temp,y;
   char *cmd,inp_buf[80],secchar,*argpos;
   union kludge center,distance,scale;
   FILE *fp;

   max_mem_y = MAXMY;

   color_table = (UWORD *)malloc(4096*sizeof(UWORD));
   if (color_table == NULL)
      abort("Can't allocate memory for color table");
   cur_resource |= F_COLORTAB;

   v_mand_store = (UWORD *)malloc(MAXX*max_mem_y*sizeof(UWORD));
   if (v_mand_store == NULL)
      abort("Can't allocate memory for set storage");
   cur_resource |= F_SETSTORE;

   MathBase = OpenLibrary("mathffp.library",0);
   if (MathBase < 1)
      abort("Can't open mathffp.library");
   cur_resource |= F_MATH;

   MathTransBase = OpenLibrary("mathtrans.library",0);
   if (MathTransBase < 1)
      abort("Can't open mathtrans.library");
   cur_resource |= F_MATHTRANS;

   GfxBase = (struct GfxBase *)OpenLibrary("graphics.library",0);
   if (GfxBase == NULL)
      abort("Can't open graphics.library");
   cur_resource |= F_GRAPHICS;
 
   IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library",0);
   if (IntuitionBase == NULL)
      abort("Can't open intuition.library");
   cur_resource |= F_INTUITION;

   console = fopen("con:0/10/640/190/Mandelbrot Commands","w+");
   if (console == NULL)
      abort("Can't open console window");
   cur_resource |= F_CONSOLE;

   fprintf(console,"Mandelbrot Self-Squared Dragon Generator - Version %s\n",VERSION);
   fputs("Copyright (c) 1985, Robert S. French\n",console);
   fputs("Placed in the public domain.\n",console);
   fputs("Type '?' for help\n\n",console);

   max_x = 320;
   max_y = 200-STARTY;
   max_mem = max_mem_y * MAXX / max_x;
   max_count = 60;
   color_inc = 2;
   color_offset = 0;
   color_set = 0;
   color_mode = 0;
   color_div = 1;

   init_colors();

   for (EVER) {

command:

      fprintf(console,"Command: ");
      rewind(console);
      if (redir_fp)
         if (Chk_Abort()) {
            fputs("\nRedirected input aborted!\n",console);
            fclose(redir_fp);
            redir_fp = NULL;
         }
         else {
            cmd = fgets(inp_buf,78,redir_fp);
            if (cmd == NULL) {
               fputs("End of file encountered.\n",console);
               fclose(redir_fp);
               redir_fp = NULL;
               cmd = fgets(inp_buf,40,console);
            }
            else
               fputs(inp_buf,console);
         }
      else
         cmd = fgets(inp_buf,40,console);
      *(cmd+strlen(cmd)-1) = '\0';
      secchar = toupper(*(cmd+1));
      argpos = stpblk(cmd+2);
      rewind(console);
      switch (toupper(*cmd)) {
         case '?':
            fputs("Available commands are:\n\n",console);
            fputs("SH - Show current settings            Q  - Quit\n",console);
            fputs("SR n / SI n / ER n / EI n - Starting and ending coords\n",console);
            fputs("MX n / MY n / MC n - Maximum x and y resolution and count\n",console);
            fprintf(console,"MM n - Maximum number of %d pixel lines in memory\n",MAXX);
            fputs("XR n / XI n - Displace coord\n",console);
            fputs("ZR n / ZI n / ZB n - Zoom around center point\n\n",console);
            fputs("CM n - Graphics mode                  F n - Change Dragon function\n",console);
            fputs("CI n - Color increment                CD - Color divisor\n",console);
            fputs("CO n - Color offset                   CS - Color set\n\n",console);
            fputs("CT n - Color for points in set\n",console);
            fputs("D  - Display picture                  G  - Generate new picture\n",console);
            fputs("A  - Display and analyze              I  - Information about author\n\n",console);
            fputs("SA filename - Save picture            L filename - Load picture\n",console);
            fputs("< filename - Redirect input           ; string - Comment\n\n",console);
            goto command;
         case 'I':
            fprintf(console,"Mandelbrot Self-Squared Dragon Generator version %s by Robert S. French\n",VERSION);
            fputs("Copyright (c) 1985 - Placed in the public domain\n\n",console);
            fputs("The author may be contacted at:\n\n",console);
            fputs("USPS:   2740 Frankfort Avenue\n",console);
            fputs("        Louisville, Ky  40206\n",console);
            fputs("Phone: (502) 897-5096\n",console);
            fputs("ARPA: French#Robert%d@LLL-MFE\n\n",console);
            goto command;
         case 'S':
            if (secchar == 'R') {
               sscanf(argpos,"%f",&start_r.f);
               start_r.i = SPFieee(start_r.i);
               if (v_fp) {
                  fclose(v_fp);
                  v_fp = NULL;
               }
               goto command;
            }
            if (secchar == 'I') {
               sscanf(argpos,"%f",&start_i.i);
               start_i.i = SPFieee(start_i.i);
               if (v_fp) {
                  fclose(v_fp);
                  v_fp = NULL;
               }
               goto command;
            }
            if (secchar == 'H') {
               fputs("Current settings:\n",console);
               fprintf(console,"MaxX=%d, MaxY=%d, SR=%f, ER=%f, SI=%f, EI=%f, F=%d\n",
                  max_x,max_y,cnvf(start_r.i),cnvf(end_r.i),cnvf(start_i.i),
                  cnvf(end_i.i),func_num);
               fprintf(console,"MaxC=%d, CI=%d, CO=%d, CS=%d, CM=%d, CD=%d, CT=%d\n",
                  max_count,color_inc,color_offset,color_set,color_mode,color_div,color_inset);
               goto command;
            }
            if (secchar == 'A') {
               fp = fopen(argpos,"w");
               if (fp == NULL) {
                  fprintf(console,"Cannot open file '%s'\n",argpos);
                  goto command;
               }
               putc((char) 1,fp);
               fwrite(&start_r,sizeof(start_r),1,fp);
               fwrite(&end_r,sizeof(end_r),1,fp);
               fwrite(&start_i,sizeof(start_i),1,fp);
               fwrite(&end_i,sizeof(end_i),1,fp);
               fwrite(&max_x,sizeof(max_x),1,fp);
               fwrite(&max_y,sizeof(max_y),1,fp);
               want_read = TRUE;
               for (y=0;y<max_y;y++) {
                  v_pos_line(y);
                  if(fwrite(v_mand_store+(y-v_starty)*max_x,
                            max_x*sizeof(UWORD),1,fp) != 1) {
                     fputs("Error while writing to file\n",console);
                     break;
                  }
               }
               fclose(fp);
               goto command;
            }
            ill_cmd();
            goto command;
         case 'E':
            if (secchar == 'R') {
               sscanf(argpos,"%f",&end_r.i);
               end_r.i = SPFieee(end_r.i);
               if (v_fp) {
                  fclose(v_fp);
                  v_fp = NULL;
               }
               goto command;
            }
            if (secchar == 'I') {
               sscanf(argpos,"%f",&end_i.i);
               end_i.i = SPFieee(end_i.i);
               if (v_fp) {
                  fclose(v_fp);
                  v_fp = NULL;
               }
               goto command;
            }
            ill_cmd();
            goto command;