/************************************************************************ * Version 3.00 MANDELBROT - Self-Squared Dragon Generator 29-May-86 * * Commodore Amiga Command Parsing MAND.C * ************************************************************************* * Copyright (c) 1986, Robert S. French and R. J. Mical * * --------------------------------------------------------------------- * * This program has been placed in the public domain. A limited * * license is hereby granted for the unlimited use and distribution of * * this program, provided it is not used for commercial or profit- * * making purposes. Thank you. * ************************************************************************* * Author information: | Name: R. J. Mical * * | USnail: Commodore-Amiga, Inc. * * Name: Robert S. French | 983 University Avenue * * USnail: 2740 Frankfort Avenue | Los Gatos, CA 95030 * * Louisville, KY 40206 \-------------------------------------* * Phone: (502) 897-5096 UUCP: ihnp4!ptsfa!well!french * * ARPA: French#Robert%d@LLL-MFE or RFrench@MIT-MULTICS * ************************************************************************* * Please send any comments, suggestions, or bugs to one of the above * * addresses. * ************************************************************************/ #include "mand.h" #include "globals.h" /*-------------*/ /* Here we go! */ main() { FILE *fopen(),*freopen(); char *fgets(),*stopblnk(); long ftell(); #ifndef DOUBLEPREC float cnvf(); #endif void anal_mand(),wait_close(); double dtemp; int temp,t1,t2,t3,x,y,i,filetype; UWORD data1,data2,repcount; char *cmd,inp_buf[80],secchar,*argpos,*argpos2; FLOATSTRUCT scale,ftemp; FILE *fp; max_mem_y = MAXMY; color_table = (UWORD *)AllocMem(4096*sizeof(UWORD),MEMF_CHIP|MEMF_PUBLIC); if (color_table == NULL) abort("Can't allocate memory for color table"); v_mand_store = (UWORD *)AllocMem(MAXX*max_mem_y*sizeof(UWORD),MEMF_CHIP|MEMF_PUBLIC); if (v_mand_store == NULL) abort("Can't allocate memory for set storage"); #ifndef DOUBLEPREC MathBase = OpenLibrary("mathffp.library",0); if (MathBase == NULL) abort("Can't open mathffp.library"); MathTransBase = OpenLibrary("mathtrans.library",0); if (MathTransBase == NULL) abort("Can't open mathtrans.library"); #endif GfxBase = (struct GfxBase *)OpenLibrary("graphics.library",0); if (GfxBase == NULL) abort("Can't open graphics.library"); IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library",0); if (IntuitionBase == NULL) abort("Can't open intuition.library"); IconBase = (struct IconBase *)OpenLibrary("icon.library",0); if (IconBase == NULL) abort("Can't open icon.library"); /* This is a kludge to allow Manx to run nice and fast without hurting execution under Lattice */ console = freopen("con:0/0/640/200/Mandelbrot Commands","w+",stdout); if (console == NULL) abort("Can't open console window"); printf("Mandelbrot Self-Squared Dragon Generator - Version %s - %s\n",VERSION,MOD_DATE); #ifdef DOUBLEPREC printf("Precision: DOUBLE\n"); #else printf("Precision: SINGLE\n"); #endif printf("Copyright (C) 1986, Robert S. French and Robert J. Mical\n\n"); printf("Placed in the public domain -- Read the source and learn!\n\n"); printf("Type '?' for help\n\n"); InitParams(); UserPalette[0] = 0x000; UserPalette[1] = 0xFFF; UserPalette[2] = 0x22F; for (i = 0; i <= 28; i++) UserPalette[i+3] = ((i & 0xF) << 8) | ((i<16?0:15) << 4) | ((i & 0xF) << 0); for (EVER) { command: if (redir_fp) { printf("Redir: "); if (Chk_Abort()) { printf("\nRedirected input aborted!\n"); fclose(redir_fp); redir_fp = NULL; } else { cmd = fgets(inp_buf,78,redir_fp); if (cmd == NULL) { printf("End of file encountered.\n"); fclose(redir_fp); redir_fp = NULL; goto command; } else printf(inp_buf); } } else { printf("Command: "); rewind(stdout); cmd = fgets(inp_buf,78,stdout); } *(cmd+strlen(cmd)-1) = '\0'; proc_command: cmd = stopblnk(cmd); secchar = toupper(*(cmd+1)); argpos = stopblnk(cmd+1); argpos2 = stopblnk(cmd+2); rewind(stdout); switch (toupper(*cmd)) { case 'H': Help(); goto command; case 'S': if (secchar == 'R') { FP(start_r) = atof(argpos2); MAKEFP(start_r) = FIEEE(MAKEFP(start_r)); if (v_fp) { fclose(v_fp); v_fp = NULL; } goto command; } if (secchar == 'I') { FP(start_i) = atof(argpos2); MAKEFP(start_i) = FIEEE(MAKEFP(start_i)); if (v_fp) { fclose(v_fp); v_fp = NULL; } goto command; } if (secchar == 'P' || secchar == 'C') { fp = fopen(argpos2,"w"); if (fp == NULL) { printf("Cannot open file '%s'\n",argpos2); goto command; } if (secchar == 'P') { fprintf(fp,"SR"); prtflt(CNVFLT(MAKEFP(start_r)),fp); fprintf(fp,"\nER"); prtflt(CNVFLT(MAKEFP(end_r)),fp); fprintf(fp,"\nSI"); prtflt(CNVFLT(MAKEFP(start_i)),fp); fprintf(fp,"\nEI"); prtflt(CNVFLT(MAKEFP(end_i)),fp); fprintf(fp,"\nMX%d\n",max_x); fprintf(fp,"MY%d\n",max_y); fprintf(fp,"MM%d\n",max_mem_y); fprintf(fp,"MC%d\n",max_count); fprintf(fp,"F%d\n",func_num); } fprintf(fp,"CI%d\n",color_inc); fprintf(fp,"CO%d\n",color_offset); fprintf(fp,"CS%d\n",color_set); fprintf(fp,"CM%d\n",color_mode); fprintf(fp,"CD%d\n",color_div); fprintf(fp,"CT%d\n",color_inset); for (i=0;i<32;i++) fprintf(fp,"CR %d %d %d %d\n",i,(UserPalette[i] >> 8) & 0xf, (UserPalette[i] >> 4) &0xf, UserPalette[i] & 0xf); fclose(fp); goto command; } if (secchar == 'H') { CurrentSettings(); goto command; } if (secchar == 'A' || secchar == 'Q') { if (v_fp == NULL) { printf("Must enerate or ad first!\n"); goto command; } fp = fopen(argpos2,"w"); if (fp == NULL) { printf("Cannot open file '%s'\n",argpos2); goto command; } if (secchar == 'A') putc((char) 1,fp); else putc((char) 2,fp); dtemp = (double)CNVFLT(MAKEFP(start_r)); fwrite(&dtemp,sizeof(dtemp),1,fp); dtemp = (double)CNVFLT(MAKEFP(end_r)); fwrite(&dtemp,sizeof(dtemp),1,fp); dtemp = (double)CNVFLT(MAKEFP(start_i)); fwrite(&dtemp,sizeof(dtemp),1,fp); dtemp = (double)CNVFLT(MAKEFP(end_i)); fwrite(&dtemp,sizeof(dtemp),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 320 && !(color_mode & 4)) || (temp > 640 && (color_mode & 4))) { printf("Illegal maximum X value!\n"); goto command; } max_x = temp; max_mem = max_mem_y * MAXX; max_mem /= max_x; if (v_fp) { fclose(v_fp); v_fp = NULL; } goto command; } if (secchar == 'Y') { sscanf(argpos2,"%d",&temp); if (temp < 30 || (temp > 200-STARTY && !(color_mode & 2)) || (temp > 400-STARTY && (color_mode & 2))) { printf("Illegal maximum Y value!\n"); goto command; } max_y = temp; if (v_fp) { fclose(v_fp); v_fp = NULL; } goto command; } if (secchar == 'C') { sscanf(argpos2,"%d",&temp); if (temp * color_inc + color_offset > 4095) { printf("More than 4096 colors!\n"); goto command; } if (temp < 2) { printf("MaxCount must be greater than 1\n"); goto command; } max_count = temp; goto command; } if (secchar == 'M') { sscanf(argpos2,"%d",&temp); if (temp < 10) { printf("Number of virtual lines must be >9!\n"); goto command; } FreeMem(v_mand_store,MAXX*max_mem_y*sizeof(UWORD)); v_mand_store = (UWORD *)AllocMem(MAXX*temp*sizeof(UWORD),MEMF_CHIP|MEMF_PUBLIC); if (v_mand_store == NULL) { printf("Can't allocate that much memory for set storage"); v_mand_store = (UWORD *)AllocMem(MAXX*max_mem_y*sizeof(UWORD),MEMF_CHIP|MEMF_PUBLIC); if (v_mand_store == NULL) abort("Can't reallocate memory!!!"); goto command; } max_mem_y = temp; if (v_fp) { fclose(v_fp); v_fp = NULL; } max_mem = MAXX * max_mem_y; max_mem /= max_x; goto command; } ill_cmd(); goto command; case 'L': if (secchar == 'O') { if (v_fp) { fclose(v_fp); v_fp = NULL; } fp = fopen(argpos2,"r"); if (fp == NULL) { printf("Cannot open file '%s'\n",argpos2); goto command; } filetype = getc(fp); if (filetype != 1 && filetype != 2) { printf("File is not in proper format\n"); fclose(fp); fp = NULL; goto command; } if (fread(&dtemp,sizeof(dtemp),1,fp) != 1) goto bad_load; FP(ftemp) = CNVSNG(dtemp); MAKEFP(start_r) = FIEEE(MAKEFP(ftemp)); if (fread(&dtemp,sizeof(dtemp),1,fp) != 1) goto bad_load; FP(ftemp) = CNVSNG(dtemp); MAKEFP(end_r) = FIEEE(MAKEFP(ftemp)); if (fread(&dtemp,sizeof(dtemp),1,fp) != 1) goto bad_load; FP(ftemp) = CNVSNG(dtemp); MAKEFP(start_i) = FIEEE(MAKEFP(ftemp)); if (fread(&dtemp,sizeof(dtemp),1,fp) != 1) goto bad_load; FP(ftemp) = CNVSNG(dtemp); MAKEFP(end_i) = FIEEE(MAKEFP(ftemp)); if (fread(&max_x,sizeof(max_x),1,fp) != 1) goto bad_load; if (fread(&max_y,sizeof(max_y),1,fp) != 1) goto bad_load; if (max_x > 320) color_mode |= (HIRES_MODE|NOT_HOLDANDMODIFY); if (max_y > 200) color_mode |= INTERLACE_MODE; max_mem = max_mem_y * MAXX; max_mem /= max_x; if (filetype == 1) { v_offset = ftell(fp); v_starty = 1; v_fp = fp; fp = NULL; modified = FALSE; } else { v_fp = fopen(TEMPNAME,"w+"); v_offset = 0L; v_starty = 1; modified = FALSE; want_read = FALSE; if (v_fp == NULL) abort("Can't open temporary file!"); for (y=0;y 31) { printf("Color number out of range!\n"); goto command; } UserPalette[temp] = (t1 << 8) | (t2 << 4) | t3; goto command; } if (secchar == 'I') { sscanf(argpos2,"%d",&temp); if (max_count * temp + color_offset > 4095) { printf("More than 4096 colors!\n"); goto command; } if (temp < 1) { printf("Increment must be greater than 0!\n"); goto command; } color_inc = temp; goto command; } if (secchar == 'O') { sscanf(argpos2,"%d",&temp); if (max_count * color_inc + temp > 4095) { printf("More than 4096 colors!\n"); goto command; } if (temp < 0) { printf("Negative offset illegal!\n"); goto command; } color_offset = temp; goto command; } if (secchar == 'S') { sscanf(argpos2,"%d",&temp); if (temp < 0 || temp > 2) { printf("Illegal color set!\n"); goto command; } color_set = temp; init_colors(); goto command; } if (secchar == 'M') { sscanf(argpos2,"%d",&temp); if (temp < 0 || temp > 7 || ((temp&4) && !(temp&1))) { printf("Illegal graphics mode!\n"); goto command; } color_mode = temp; if (!(color_mode & 0x2)) if (max_y > 200-STARTY) { if (v_fp) { fclose(v_fp); v_fp = NULL; } max_y = 200-STARTY; } if (!(color_mode & 0x4)) if (max_x > 320) { if (v_fp) { fclose(v_fp); v_fp = NULL; } max_x = 320; max_mem = max_mem_y * MAXX; max_mem /= max_x; } goto command; } if (secchar == 'D') { sscanf(argpos2,"%d",&temp); if (temp < 1) { printf("Divisor must be greater than 0!\n"); goto command; } color_div = temp; goto command; } if (secchar == 'T') { sscanf(argpos2,"%d",&temp); if (temp < 0 || temp > 4095) { printf("Color must be between 0 and 4095!\n"); goto command; } color_inset = temp; goto command; } ill_cmd(); goto command; case 'F': sscanf(argpos,"%d",&temp); if (temp < 0 || temp > 1) { printf("Function number must be 0 or 1!\n"); goto command; } func_num = temp; if (v_fp) { fclose(v_fp); v_fp = NULL; } goto command; case 'P': sscanf(argpos,"%d",&temp); sprintf(inp_buf,"< Preset%d",temp); goto proc_command; case 'D': if (v_fp == NULL) { printf("Must enerate or ad first!\n"); goto command; } if (disp_mand() == NULL) wait_close(); goto command; case 'G': if (gen_mand() == NULL) wait_close(); goto command; case ';': goto command; /* Lattice will complain about this line! */ case '<': if (redir_fp) { fclose(redir_fp); redir_fp = NULL; } redir_fp = fopen(argpos,"r"); if (redir_fp == NULL) printf("Cannot open file '%s'\n",argpos); goto command; case 'Q': abort(NULL); case '?': AvailableCommands(); goto command; } } } ill_cmd() { printf("Unknown command!\n"); } #ifndef DOUBLEPREC float cnvf(i) int i; { union kludge n; n.i = i; n.i = SPTieee(n.i); return (n.f); } #endif /*-----------------------------------------*/ /* Non-intelligent virtual memory handling */ v_pos_line(l) int l; { if (l < v_starty) { if (modified) v_flush(); v_starty = 0; fseek(v_fp,v_offset,0); if (want_read) fread(v_mand_store,max_x*sizeof(UWORD),max_mem,v_fp); } if (l-v_starty > max_mem-1) { if (modified) v_flush(); v_starty += max_mem; fseek(v_fp,(long)(v_starty*max_x*sizeof(UWORD)+v_offset),0); if (want_read) fread(v_mand_store,max_x*sizeof(UWORD),max_mem,v_fp); } return (0); } v_flush() { fseek(v_fp,(long)(v_starty*max_x*sizeof(UWORD)+v_offset),0); fwrite(v_mand_store,max_x*sizeof(UWORD),max_mem>max_y?max_y:max_mem,v_fp); modified = FALSE; return (0); } abort(s) char *s; { CloseDisplay(); #ifndef DOUBLEPREC if (MathTransBase) CloseLibrary(MathTransBase); if (MathBase) CloseLibrary(MathBase); #endif if (console) fclose(console); if (v_fp) fclose(v_fp); if (redir_fp) fclose(redir_fp); if (GfxBase) CloseLibrary(GfxBase); if (IntuitionBase) CloseLibrary(IntuitionBase); if (IconBase) CloseLibrary(IconBase); if (v_mand_store) FreeMem(v_mand_store,max_mem_y*MAXX*sizeof(UWORD)); if (color_table) FreeMem(color_table,4096*sizeof(UWORD)); DeleteFile(TEMPNAME); if (s) fprintf(stderr,"%s\n",s); exit(0); } InitParams() { max_x = 320; max_y = 200; max_count = 50; color_inc = 2; color_set = 1; color_mode = 1; color_div = 1; func_num = 0; fl_assign(&FP(start_r),(double)-.5); MAKEFP(start_r) = FIEEE(MAKEFP(start_r)); fl_assign(&FP(end_r),(double)2.0); MAKEFP(end_r) = FIEEE(MAKEFP(end_r)); fl_assign(&FP(start_i),(double)-1.25); MAKEFP(start_i) = FIEEE(MAKEFP(start_i)); fl_assign(&FP(end_i),(double)1.25); MAKEFP(end_i) = FIEEE(MAKEFP(end_i)); ZoomCenterX = max_x >> 1; ZoomCenterY = max_y >> 1; ZoomBoxSizeX = max_x; ZoomBoxSizeY = max_y; max_mem = max_mem_y * MAXX / max_x; init_colors(); } fl_assign(f,v) /* Kludge to fix bug in Lattice 3.02 */ #ifdef DOUBLEPREC double *f; #else float *f; #endif double v; { *f = v; } char *stopblnk(cp) char *cp; { while (isspace(*cp)) cp++; return(cp); } prtflt(f,fp) #ifdef DOUBLEPREC double f; #else float f; #endif FILE *fp; { #ifdef MANX char bfr[25]; #ifdef DOUBLEPREC ftoa((double) f,bfr,17); #else ftoa((double) f,bfr,7); #endif if (fp == stdout) printf("%s",bfr); else fprintf(fp,"%s",bfr); #endif #ifdef LATTICE fprintf(fp,PERCFLT,f); #endif } iabs(v) int v; { if (v < 0) return (-v); else return (v); }