2 MAND.C - Command parsing
3 Mandelbrot's Self-Squared Dragon Generator
4 For the Commodore Amiga
7 Inspired by Scientific American, August/1985
9 Corrections and improvements suggested by
10 The Fractal Geometry of Nature
11 By Benoit Mandelbrot, W.H. Freeman and Company, 1983
12 (Used to be Z=Z^2+C, now is Z=Z^2-u, etc.)
14 Copyright (C) 1985, Robert S. French
15 Placed in the Public Domain
17 Assorted Goodies and Intuition-stuff by =RJ Mical= 1985
18 Hope you appreciate them. I especially like the zoom.
20 This program may be distributed free of charge as long as the above
23 Please see the accompanying documentation for more information.
25 Send ANY problems or suggestions to the address in the <I>nformation
28 Programs should be compiled with:
30 1> lc -i:include/ -i:include/lattice/ mand.c
31 1> lc -i:include/ -i:include/lattice/ mand1.c
32 1> lc -i:include/ -i:include/lattice/ mand2.c
33 1> lc -i:include/ -i:include/lattice/ mand3.c
34 1> lc -i:include/ -i:include/lattice/ mand4.c
35 1> alink :lib/Lstartup.obj+mand.o+mand1.o+mand2.o+mand3.o+mand4.o to mand lib :lib/lc.lib+:lib/amiga.lib
40 /* ===========================================================================
41 ===========================================================================
42 From: "french robert%d.mfenet"@LLL-MFE.ARPA
44 Well guys, you asked for it, and here it is. There are two parts to the
45 Mandelbrot Set Generator which must be linked together (instructions are
46 at the beginning of the file). I don't have any of the documentation
47 written yet, so you're on your own for a while. I'll upload it when I get
48 it finished. I can't send files over 16K thru the net, so the first
49 section is sent as two files...just JOIN them together. Right now, the
50 program seems to work without any problems, except for an occasional
51 mysterious crash and the problem with closing a window in the middle of
52 picture generation (see comments in MAND1.C). Please send me any comments
55 By the way, on a historical note, the "Mandelbrot Set" as related in
56 Scientific American is a little different from the u-Map implemented
57 here (as discussed in Mandelbrot's "The Fractal Geometry of Nature").
58 The main difference is the use of Z -> Z 2+C in Scientific American vs.
59 Z -> Z 2-u in the book and this program. The primary effect is the reversal
60 of the picture across the Y axis.
65 French#Robert%d@LLL-MFE.ARPA
67 ========================================================================
68 ======================================================================== */
72 struct Library
* MathBase
;
73 struct Library
* MathTransBase
;
75 struct DosLibrary
* DOSBase
;
77 /*----------------------*/
78 /* Graphics definitions */
80 struct GfxBase
*GfxBase
;
81 struct IntuitionBase
*IntuitionBase
;
84 /*---------------------------*/
85 /* Some Lattice(?) functions */
86 /* Added by hkiel@aros.org */
87 /* Correct them if YOU know */
89 void loc_abort(char *s
);
92 // FIXME: Original used Lattice which has Chk_Abort()
93 int Chk_Abort() /* Disabled by now */
99 /*----------------------------------*/
100 /* Miscellaneous Global Definitions */
105 } start_r
,end_r
,start_i
,end_i
;
106 int max_x
,max_y
,max_mem_y
;
107 int max_count
,color_inc
,color_offset
,color_set
,color_mode
,color_div
;
108 int color_inset
,func_num
;
110 int v_starty
,max_mem
;
112 UWORD
*color_table
,*v_mand_store
;
114 int modified
,want_read
;
116 FILE *console
,*v_fp
= NULL
,*redir_fp
= NULL
;
118 SHORT ZoomCenterX
, ZoomCenterY
, ZoomBoxSizeX
, ZoomBoxSizeY
;
119 SHORT ZoomBoxStartX
, ZoomBoxStartY
;
122 int cur_resource
= 0;
131 char *fgets(),*stpblk();
138 void anal_mand(),wait_close();
141 char *cmd
,inp_buf
[80],secchar
,*argpos
;
147 color_table
= (UWORD
*)malloc(4096*sizeof(UWORD
));
148 if (color_table
== NULL
)
149 loc_abort("Can't allocate memory for color table");
150 cur_resource
|= F_COLORTAB
;
152 v_mand_store
= (UWORD
*)malloc(MAXX
*max_mem_y
*sizeof(UWORD
));
153 if (v_mand_store
== NULL
)
154 loc_abort("Can't allocate memory for set storage");
155 cur_resource
|= F_SETSTORE
;
157 MathBase
= OpenLibrary("mathffp.library",0);
158 if (MathBase
== NULL
)
159 loc_abort("Can't open mathffp.library");
160 cur_resource
|= F_MATH
;
162 MathTransBase
= OpenLibrary("mathtrans.library",0);
163 if (MathTransBase
== NULL
)
164 loc_abort("Can't open mathtrans.library");
165 cur_resource
|= F_MATHTRANS
;
167 GfxBase
= (struct GfxBase
*)OpenLibrary("graphics.library",0);
169 loc_abort("Can't open graphics.library");
170 cur_resource
|= F_GRAPHICS
;
172 IntuitionBase
= (struct IntuitionBase
*)OpenLibrary("intuition.library",0);
173 if (IntuitionBase
== NULL
)
174 loc_abort("Can't open intuition.library");
175 cur_resource
|= F_INTUITION
;
177 DOSBase
= (struct DosLibrary
*)OpenLibrary("dos.library", 0);
179 loc_abort("Can't open dos.library");
180 cur_resource
|= F_DOS
;
182 console
= fopen("con:0/0/640/200/Mandelbrot Commands","w+");
184 loc_abort("Can't open console window");
185 cur_resource
|= F_CONSOLE
;
188 "Mandelbrot Self-Squared Dragon Generator - Version %s\n",VERSION
);
189 fputs("Copyright (C) 1985, Robert S. French\n",console
);
190 fputs("Power, Goodies, and Baubles by =RJ Mical= 1985\n",console
);
191 fputs("Placed in the public domain.\n",console
);
192 fputs("Type '?' or 'H' or <RETURN> for help\n\n",console
);
200 fprintf(console
,"Command: ");
204 fputs("\nRedirected input aborted!\n",console
);
209 cmd
= fgets(inp_buf
,78,redir_fp
);
211 fputs("End of file encountered.\n",console
);
214 cmd
= fgets(inp_buf
,40,console
);
217 fputs(inp_buf
,console
);
220 cmd
= fgets(inp_buf
,40,console
);
221 *(cmd
+strlen(cmd
)-1) = '\0';
222 secchar
= toupper(*(cmd
+1));
223 argpos
= stpblk(cmd
+2);
225 switch (toupper(*cmd
)) {
227 sscanf(argpos
,"%d",&temp
);
231 if (secchar
== 'R') {
232 sscanf(argpos
,"%f",&start_r
.f
);
233 start_r
.i
= SPFieee(start_r
.i
);
240 if (secchar
== 'I') {
241 sscanf(argpos
,"%f",&start_i
.i
);
242 start_i
.i
= SPFieee(start_i
.i
);
249 if (secchar
== 'H') {
250 fputs("Current settings:\n",console
);
251 fprintf(console
,"MaxX=%d, MaxY=%d, SR=%f, ER=%f, SI=%f, EI=%f, F=%d\n",
252 max_x
,max_y
,cnvf(start_r
.i
),cnvf(end_r
.i
),cnvf(start_i
.i
),
253 cnvf(end_i
.i
),func_num
);
254 fprintf(console
,"MaxC=%d, CI=%d, CO=%d, CS=%d, CM=%d, CD=%d, CT=%d MM=%d\n",
255 max_count
,color_inc
,color_offset
,color_set
,color_mode
,color_div
,color_inset
, max_mem_y
);
258 if (secchar
== 'A') {
259 fp
= fopen(argpos
,"w");
261 fprintf(console
,"Cannot open file '%s'\n",argpos
);
265 fwrite(&start_r
,sizeof(start_r
),1,fp
);
266 fwrite(&start_i
,sizeof(start_i
),1,fp
);
267 fwrite(&end_i
,sizeof(end_i
),1,fp
);
268 fwrite(&max_x
,sizeof(max_x
),1,fp
);
269 fwrite(&max_y
,sizeof(max_y
),1,fp
);
271 for (y
=0;y
<max_y
;y
++) {
273 if(fwrite(v_mand_store
+(y
-v_starty
)*max_x
,
274 max_x
*sizeof(UWORD
),1,fp
) != 1) {
275 fputs("Error while writing to file\n",console
);
285 if (secchar
== 'R') {
286 sscanf(argpos
,"%f",&end_r
.i
);
287 end_r
.i
= SPFieee(end_r
.i
);
294 if (secchar
== 'I') {
295 sscanf(argpos
,"%f",&end_i
.i
);
296 end_i
.i
= SPFieee(end_i
.i
);
306 if (secchar
== 'X') {
307 sscanf(argpos
,"%d",&temp
);
309 (temp
> 320 && !(color_mode
& 4)) ||
310 (temp
> 640 && (color_mode
& 4))) {
311 fputs("Illegal parameter!\n",console
);
315 max_mem
= max_mem_y
* MAXX
;
323 if (secchar
== 'Y') {
324 sscanf(argpos
,"%d",&temp
);
326 (temp
> 200-STARTY
&& !(color_mode
& 2)) ||
327 (temp
> 400-STARTY
&& (color_mode
& 2))) {
328 fputs("Illegal parameter!\n",console
);
338 if (secchar
== 'C') {
339 sscanf(argpos
,"%d",&temp
);
340 if (temp
* color_inc
+ color_offset
> 4095) {
341 fputs("More than 4096 colors!\n",console
);
345 fputs("MaxCount must be greater than 1\n",console
);
351 if (secchar
== 'M') {
352 sscanf(argpos
,"%d",&temp
);
354 fputs("Number of lines must be >4!\n",console
);
358 v_mand_store
= (UWORD
*)malloc(MAXX
*temp
*sizeof(UWORD
));
359 if (v_mand_store
== NULL
) {
360 fputs("Can't allocate that much memory for set storage",console
);
361 v_mand_store
= (UWORD
*)malloc(MAXX
*max_mem_y
*sizeof(UWORD
));
362 if (v_mand_store
== NULL
)
363 loc_abort("Can't reallocate memory!!!");
371 max_mem
= MAXX
* max_mem_y
;
382 v_fp
= fopen(stpblk(cmd
+1),"r");
384 fprintf(console
,"Cannot open file '%s'\n",stpblk(cmd
+1));
387 if (getc(v_fp
) != 1) {
388 fputs("File is not in proper format\n",console
);
393 fread(&start_r
,sizeof(start_r
),1,v_fp
);
394 fread(&end_r
,sizeof(end_r
),1,v_fp
);
395 fread(&start_i
,sizeof(start_i
),1,v_fp
);
396 fread(&end_i
,sizeof(end_i
),1,v_fp
);
397 fread(&max_x
,sizeof(max_x
),1,v_fp
);
398 fread(&max_y
,sizeof(max_y
),1,v_fp
);
401 v_starty
= max_mem
+1;
406 if (secchar
== 'R') {
407 sscanf(argpos
,"%f",&scale
.f
);
408 scale
.i
= SPFieee(scale
.i
);
409 start_r
.i
= SPAdd(start_r
.i
,scale
.i
);
410 end_r
.i
= SPAdd(end_r
.i
,scale
.i
);
417 if (secchar
== 'I') {
418 sscanf(argpos
,"%f",&scale
.f
);
419 scale
.i
= SPFieee(scale
.i
);
420 start_i
.i
= SPAdd(start_i
.i
,scale
.i
);
421 end_i
.i
= SPAdd(end_i
.i
,scale
.i
);
431 if (secchar
!= 'R' && secchar
!= 'I' && secchar
!= 'B') {
439 if (secchar
!= 'I' ) {
440 /* scale along the real axis */
441 sscanf(argpos
,"%f",&scale
.f
);
442 ZoomAlongDarling(SPFieee(scale
.i
), SPFlt(1));
444 if (secchar
!= 'R') {
445 /* scale along the complex axis */
446 sscanf(argpos
,"%f",&scale
.f
);
447 ZoomAlongDarling(SPFlt(1), SPFieee(scale
.i
));
451 if (secchar
== 'I') {
452 sscanf(argpos
,"%d",&temp
);
453 if (max_count
* temp
+ color_offset
> 4095) {
454 fputs("More than 4096 colors!\n",console
);
458 fputs("Increment must be greater than 0!\n",console
);
464 if (secchar
== 'O') {
465 sscanf(argpos
,"%d",&temp
);
466 if (max_count
* color_inc
+ temp
> 4095) {
467 fputs("More than 4096 colors!\n",console
);
471 fputs("Negative offset illegal!\n",console
);
477 if (secchar
== 'S') {
478 sscanf(argpos
,"%d",&temp
);
479 if (temp
< 0 || temp
> 1) {
480 fputs("Illegal color set!\n",console
);
487 if (secchar
== 'M') {
488 sscanf(argpos
,"%d",&temp
);
489 if (temp
< 0 || temp
> 7 || ((temp
&4) && !(temp
&1))) {
490 fputs("Illegal graphics mode!\n",console
);
494 if (!(color_mode
& 0x2))
495 if (max_y
> 200-STARTY
)
497 if (!(color_mode
& 0x4))
502 if (secchar
== 'D') {
503 sscanf(argpos
,"%d",&temp
);
505 fputs("Divisor must be greater than 0!\n",console
);
511 if (secchar
== 'T') {
512 sscanf(argpos
,"%d",&temp
);
513 if (temp
< 0 || temp
> 4095) {
514 fputs("Color must be between 0 and 4095!\n",console
);
523 sscanf(stpblk(cmd
+1),"%d",&temp
);
524 if (temp
< 0 || temp
> 1) {
525 fputs("Function number must be 0 or 1!\n",console
);
531 sscanf(stpblk(cmd
+1),"%d",&temp
);
536 fputs("Must <G>enerate or <L>oad first!\n",console
);
539 if (disp_mand() == 0)
548 fputs("Must <G>enerate or <L>oad first!\n",console
);
551 if (!(color_mode
& 1)) {
552 fputs("Cannot be in hold and modify!\n",console
);
558 goto command
; /* Lattice will complain about this line! */
564 redir_fp
= fopen(stpblk(cmd
+1),"r");
565 if (redir_fp
== NULL
)
566 fprintf(console
,"Can't open file %s!\n",stpblk(cmd
+1));
583 fputs("Unknown command!\n",console
);
598 /*-----------------------------------------*/
599 /* Non-intelligent virtual memory handling */
608 fseek(v_fp
,v_offset
,0);
610 fread(v_mand_store
,max_x
*sizeof(UWORD
),max_mem
,v_fp
);
612 if (l
-v_starty
> max_mem
-1) {
616 fseek(v_fp
,(long)(v_starty
*max_x
*sizeof(UWORD
)+v_offset
),0);
618 fread(v_mand_store
,max_x
*sizeof(UWORD
),max_mem
,v_fp
);
624 fseek(v_fp
,(long)(v_starty
*max_x
*sizeof(UWORD
)+v_offset
),0);
625 fwrite(v_mand_store
,max_x
*sizeof(UWORD
),max_mem
,v_fp
);
632 if (cur_resource
& F_MATHTRANS
)
633 CloseLibrary((struct Library
*)MathTransBase
);
634 if (cur_resource
& F_MATH
)
635 CloseLibrary((struct Library
*)MathBase
);
636 if (cur_resource
& F_CONSOLE
)
642 if (cur_resource
& F_DOS
)
643 CloseLibrary((struct Library
*)DOSBase
);
644 if (cur_resource
& F_GRAPHICS
)
645 CloseLibrary((struct Library
*)GfxBase
);
646 if (cur_resource
& F_INTUITION
)
647 CloseLibrary((struct Library
*)IntuitionBase
);
648 if (cur_resource
& F_SETSTORE
)
650 if (cur_resource
& F_COLORTAB
)
660 void SetPresets(preset
)
663 /* these are some common defaults, preset here to avoid repetitive
664 * assignments in the case statements below. Feel free to override
665 * any of these defaults with your own in the case statements below
678 fputs("Mandelbrot's Set\n", console
);
687 fputs("Unbounded Rhythms\n", console
);
688 start_r
.f
= 1.703418;
690 start_i
.f
= -0.169450;
695 fputs("RJ's Gangliactic\n", console
);
696 start_r
.f
= 1.937821;
698 start_i
.f
= -0.00259;
703 fputs("Mandelbrot Recursion\n", console
);
704 start_r
.f
= -0.294473;
706 start_i
.f
= 0.012677;
712 fputs("Crackle\n", console
);
721 fputs("Connections\n", console
);
722 start_r
.f
= 0.115206;
724 start_i
.f
= -1.036059;
730 fputs("SORRY: there's not that many presets!\n",console
);
734 ZoomCenterX
= max_x
>> 1;
735 ZoomCenterY
= max_y
>> 1;
736 ZoomBoxSizeX
= max_x
;
737 ZoomBoxSizeY
= max_y
;
738 start_r
.i
= SPFieee(start_r
.i
);
739 end_r
.i
= SPFieee(end_r
.i
);
740 start_i
.i
= SPFieee(start_i
.i
);
741 end_i
.i
= SPFieee(end_i
.i
);
742 max_mem
= max_mem_y
* MAXX
/ max_x
;