forwarding a radium compilation fix.
[AROS-Contrib.git] / fish / mandel / mand.c
bloba2759d9fcc7255936eda7adf4f3d038d858aaddc
1 /*
2 MAND.C - Command parsing
3 Mandelbrot's Self-Squared Dragon Generator
4 For the Commodore Amiga
5 Version 1.00
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
21 notice is retained.
23 Please see the accompanying documentation for more information.
25 Send ANY problems or suggestions to the address in the <I>nformation
26 section. Thank you!
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
53 or suggestions.
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.
62 Enjoy!
64 Robert French
65 French#Robert%d@LLL-MFE.ARPA
67 ========================================================================
68 ======================================================================== */
70 #include "mand.h"
72 struct Library* MathBase;
73 struct Library* MathTransBase;
75 struct DosLibrary* DOSBase;
77 /*----------------------*/
78 /* Graphics definitions */
80 struct GfxBase *GfxBase;
81 struct IntuitionBase *IntuitionBase;
83 #ifndef LATTICE
84 /*---------------------------*/
85 /* Some Lattice(?) functions */
86 /* Added by hkiel@aros.org */
87 /* Correct them if YOU know */
88 /* what they do... */
89 void loc_abort(char *s);
92 // FIXME: Original used Lattice which has Chk_Abort()
93 int Chk_Abort() /* Disabled by now */
95 return 0;
97 #endif /* LATTICE */
99 /*----------------------------------*/
100 /* Miscellaneous Global Definitions */
102 union kludge {
103 float f;
104 KLUDGE_INT i;
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;
111 long v_offset;
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;
125 /*-------------*/
126 /* Here we go! */
128 int main()
130 FILE *fopen();
131 char *fgets(),*stpblk();
132 #if USE_MATHFFP
133 float cnvf();
134 #else
135 #define cnvf(x) (x)
136 #endif
138 void anal_mand(),wait_close();
140 int temp,y;
141 char *cmd,inp_buf[80],secchar,*argpos;
142 union kludge scale;
143 FILE *fp;
145 max_mem_y = MAXMY;
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);
168 if (GfxBase == NULL)
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);
178 if (DOSBase == NULL)
179 loc_abort("Can't open dos.library");
180 cur_resource |= F_DOS;
182 console = fopen("con:0/0/640/200/Mandelbrot Commands","w+");
183 if (console == NULL)
184 loc_abort("Can't open console window");
185 cur_resource |= F_CONSOLE;
187 fprintf(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);
194 SetPresets(0);
196 for (EVER) {
198 command:
200 fprintf(console,"Command: ");
201 rewind(console);
202 if (redir_fp)
203 if (Chk_Abort()) {
204 fputs("\nRedirected input aborted!\n",console);
205 fclose(redir_fp);
206 redir_fp = NULL;
208 else {
209 cmd = fgets(inp_buf,78,redir_fp);
210 if (cmd == NULL) {
211 fputs("End of file encountered.\n",console);
212 fclose(redir_fp);
213 redir_fp = NULL;
214 cmd = fgets(inp_buf,40,console);
216 else
217 fputs(inp_buf,console);
219 else
220 cmd = fgets(inp_buf,40,console);
221 *(cmd+strlen(cmd)-1) = '\0';
222 secchar = toupper(*(cmd+1));
223 argpos = stpblk(cmd+2);
224 rewind(console);
225 switch (toupper(*cmd)) {
226 case 'I':
227 sscanf(argpos,"%d",&temp);
228 Information(temp);
229 goto command;
230 case 'S':
231 if (secchar == 'R') {
232 sscanf(argpos,"%f",&start_r.f);
233 start_r.i = SPFieee(start_r.i);
234 if (v_fp) {
235 fclose(v_fp);
236 v_fp = NULL;
238 goto command;
240 if (secchar == 'I') {
241 sscanf(argpos,"%f",&start_i.i);
242 start_i.i = SPFieee(start_i.i);
243 if (v_fp) {
244 fclose(v_fp);
245 v_fp = NULL;
247 goto command;
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);
256 goto command;
258 if (secchar == 'A') {
259 fp = fopen(argpos,"w");
260 if (fp == NULL) {
261 fprintf(console,"Cannot open file '%s'\n",argpos);
262 goto command;
264 putc((char) 1,fp);
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);
270 want_read = TRUE;
271 for (y=0;y<max_y;y++) {
272 v_pos_line(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);
276 break;
279 fclose(fp);
280 goto command;
282 ill_cmd();
283 goto command;
284 case 'E':
285 if (secchar == 'R') {
286 sscanf(argpos,"%f",&end_r.i);
287 end_r.i = SPFieee(end_r.i);
288 if (v_fp) {
289 fclose(v_fp);
290 v_fp = NULL;
292 goto command;
294 if (secchar == 'I') {
295 sscanf(argpos,"%f",&end_i.i);
296 end_i.i = SPFieee(end_i.i);
297 if (v_fp) {
298 fclose(v_fp);
299 v_fp = NULL;
301 goto command;
303 ill_cmd();
304 goto command;
305 case 'M':
306 if (secchar == 'X') {
307 sscanf(argpos,"%d",&temp);
308 if (temp < 5 ||
309 (temp > 320 && !(color_mode & 4)) ||
310 (temp > 640 && (color_mode & 4))) {
311 fputs("Illegal parameter!\n",console);
312 goto command;
314 max_x = temp;
315 max_mem = max_mem_y * MAXX;
316 max_mem /= max_x;
317 if (v_fp) {
318 fclose(v_fp);
319 v_fp = NULL;
321 goto command;
323 if (secchar == 'Y') {
324 sscanf(argpos,"%d",&temp);
325 if (temp < 5 ||
326 (temp > 200-STARTY && !(color_mode & 2)) ||
327 (temp > 400-STARTY && (color_mode & 2))) {
328 fputs("Illegal parameter!\n",console);
329 goto command;
331 max_y = temp;
332 if (v_fp) {
333 fclose(v_fp);
334 v_fp = NULL;
336 goto command;
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);
342 goto command;
344 if (temp < 2) {
345 fputs("MaxCount must be greater than 1\n",console);
346 goto command;
348 max_count = temp;
349 goto command;
351 if (secchar == 'M') {
352 sscanf(argpos,"%d",&temp);
353 if (temp < 5) {
354 fputs("Number of lines must be >4!\n",console);
355 goto command;
357 free(v_mand_store);
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!!!");
364 goto command;
366 max_mem_y = temp;
367 if (v_fp) {
368 fclose(v_fp);
369 v_fp = NULL;
371 max_mem = MAXX * max_mem_y;
372 max_mem /= max_x;
373 goto command;
375 ill_cmd();
376 goto command;
377 case 'L':
378 if (v_fp) {
379 fclose(v_fp);
380 v_fp = NULL;
382 v_fp = fopen(stpblk(cmd+1),"r");
383 if (v_fp == NULL) {
384 fprintf(console,"Cannot open file '%s'\n",stpblk(cmd+1));
385 goto command;
387 if (getc(v_fp) != 1) {
388 fputs("File is not in proper format\n",console);
389 fclose(v_fp);
390 v_fp = NULL;
391 goto command;
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);
399 v_offset = 25L;
400 modified = FALSE;
401 v_starty = max_mem+1;
402 want_read = TRUE;
403 v_pos_line(0);
404 goto command;
405 case 'X':
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);
411 if (v_fp) {
412 fclose(v_fp);
413 v_fp = NULL;
415 goto command;
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);
422 if (v_fp) {
423 fclose(v_fp);
424 v_fp = NULL;
426 goto command;
428 ill_cmd();
429 goto command;
430 case 'Z':
431 if (secchar != 'R' && secchar != 'I' && secchar != 'B') {
432 ill_cmd();
433 goto command;
435 if (v_fp) {
436 fclose(v_fp);
437 v_fp = NULL;
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));
449 goto command;
450 case 'C':
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);
455 goto command;
457 if (temp < 1) {
458 fputs("Increment must be greater than 0!\n",console);
459 goto command;
461 color_inc = temp;
462 goto command;
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);
468 goto command;
470 if (temp < 0) {
471 fputs("Negative offset illegal!\n",console);
472 goto command;
474 color_offset = temp;
475 goto command;
477 if (secchar == 'S') {
478 sscanf(argpos,"%d",&temp);
479 if (temp < 0 || temp > 1) {
480 fputs("Illegal color set!\n",console);
481 goto command;
483 color_set = temp;
484 init_colors();
485 goto command;
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);
491 goto command;
493 color_mode = temp;
494 if (!(color_mode & 0x2))
495 if (max_y > 200-STARTY)
496 max_y = 200-STARTY;
497 if (!(color_mode & 0x4))
498 if (max_x > 320)
499 max_x = 320;
500 goto command;
502 if (secchar == 'D') {
503 sscanf(argpos,"%d",&temp);
504 if (temp < 1) {
505 fputs("Divisor must be greater than 0!\n",console);
506 goto command;
508 color_div = temp;
509 goto command;
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);
515 goto command;
517 color_inset = temp;
518 goto command;
520 ill_cmd();
521 goto command;
522 case 'F':
523 sscanf(stpblk(cmd+1),"%d",&temp);
524 if (temp < 0 || temp > 1) {
525 fputs("Function number must be 0 or 1!\n",console);
526 goto command;
528 func_num = temp;
529 goto command;
530 case 'P':
531 sscanf(stpblk(cmd+1),"%d",&temp);
532 SetPresets(temp);
533 goto command;
534 case 'D':
535 if (v_fp == NULL) {
536 fputs("Must <G>enerate or <L>oad first!\n",console);
537 goto command;
539 if (disp_mand() == 0)
540 wait_close();
541 goto command;
542 case 'G':
543 if (gen_mand() == 0)
544 wait_close();
545 goto command;
546 case 'A':
547 if (v_fp == NULL) {
548 fputs("Must <G>enerate or <L>oad first!\n",console);
549 goto command;
551 if (!(color_mode & 1)) {
552 fputs("Cannot be in hold and modify!\n",console);
553 goto command;
555 anal_mand();
556 goto command;
557 case ';':
558 goto command; /* Lattice will complain about this line! */
559 case '<':
560 if (redir_fp) {
561 fclose(redir_fp);
562 redir_fp = NULL;
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));
567 goto command;
568 case 'Q':
569 loc_abort("Bye!");
570 case '?':
571 case 'H':
572 default:
573 AvailableCommands();
574 goto command;
578 return 0;
581 void ill_cmd()
583 fputs("Unknown command!\n",console);
586 #if USE_MATHFFP
587 float cnvf(i)
588 int i;
590 union kludge n;
592 n.i = i;
593 n.i = SPTieee(n.i);
594 return (n.f);
596 #endif
598 /*-----------------------------------------*/
599 /* Non-intelligent virtual memory handling */
601 void v_pos_line(l)
602 int l;
604 if (l < v_starty) {
605 if (modified)
606 v_flush();
607 v_starty = 0;
608 fseek(v_fp,v_offset,0);
609 if (want_read)
610 fread(v_mand_store,max_x*sizeof(UWORD),max_mem,v_fp);
612 if (l-v_starty > max_mem-1) {
613 if (modified)
614 v_flush();
615 v_starty += max_mem;
616 fseek(v_fp,(long)(v_starty*max_x*sizeof(UWORD)+v_offset),0);
617 if (want_read)
618 fread(v_mand_store,max_x*sizeof(UWORD),max_mem,v_fp);
622 void v_flush()
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);
626 modified = FALSE;
629 void loc_abort(s)
630 char *s;
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)
637 fclose(console);
638 if (v_fp)
639 fclose(v_fp);
640 if (redir_fp)
641 fclose(redir_fp);
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)
649 free(v_mand_store);
650 if (cur_resource & F_COLORTAB)
651 free(color_table);
653 CloseDisplay();
655 puts(s);
656 exit(0);
660 void SetPresets(preset)
661 int 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
667 max_x = 320;
668 max_y = 200;
669 max_count = 29;
670 color_inc = 1;
671 color_set = 1;
672 color_mode = 1;
673 color_div = 1;
675 switch (preset)
677 case 0:
678 fputs("Mandelbrot's Set\n", console);
679 start_r.f = -2.85;
680 end_r.f = 2.85;
681 start_i.f = -2.05;
682 end_i.f = 2.05;
683 max_count = 15;
684 color_offset = 91;
685 break;
686 case 1:
687 fputs("Unbounded Rhythms\n", console);
688 start_r.f = 1.703418;
689 end_r.f = 2.016930;
690 start_i.f = -0.169450;
691 end_i.f = 0.169450;
692 color_offset = 31;
693 break;
694 case 2:
695 fputs("RJ's Gangliactic\n", console);
696 start_r.f = 1.937821;
697 end_r.f = 1.945044;
698 start_i.f = -0.00259;
699 end_i.f = 0.00259;
700 color_offset = 31;
701 break;
702 case 3:
703 fputs("Mandelbrot Recursion\n", console);
704 start_r.f = -0.294473;
705 end_r.f = -0.288444;
706 start_i.f = 0.012677;
707 end_i.f = 0.014839;
708 color_offset = 26;
709 max_count = 30;
710 break;
711 case 4:
712 fputs("Crackle\n", console);
713 start_r.f = 0.225;
714 end_r.f = 0.275;
715 start_i.f = 0.8425;
716 end_i.f = 0.8525;
717 color_offset = 61;
718 max_count = 31;
719 break;
720 case 5:
721 fputs("Connections\n", console);
722 start_r.f = 0.115206;
723 end_r.f = 0.168190;
724 start_i.f = -1.036059;
725 end_i.f = -0.985386;
726 color_offset = 76;
727 color_inc = 2;
728 break;
729 default:
730 fputs("SORRY: there's not that many presets!\n",console);
731 break;
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;
743 init_colors();