home *** CD-ROM | disk | FTP | other *** search
- /*
- Biomorph/Mandelbrot Fractal Generator
- C-code Version 2.0 By Fred Dunlap from Bert Tyler program
- */
-
- #include <stdio.h>
- #include <dos.h>
- extern int calcdots_sin(void);
- extern int calcdots_b3(void);
- extern int calcdots_b5(void);
- extern int calcdots_f(void);
-
- struct videoinfo { /* All we need to know about a Video Adapter */
- char name[40]; /* Adapter name (IBM EGA, etc) */
- int videomodeax; /* begin with INT 10H, AX=(this) */
- int videomodebx; /* ...and BX=(this) */
- int videomodecx; /* ...and CX=(this) */
- int videomodedx; /* ...and DX=(this) */
- int dotmode; /* video access method used by asm code */
- /* 1 == BIOS 10H, AH=12,13 (SLOW) */
- /* 2 == access like EGA/VGA */
- /* 3 == access like MCGA */
- int xdots; /* number of dots across the screen */
- int ydots; /* number of dots down the screen */
- int colors; /* number of colors available */
- char comment[40]; /* Comments (UNTESTED, etc) */
- };
-
- struct videoinfo videomode[] = {
- /*
- Feel free to add your favorite video adapter to the following table.
- Just remember that only the first 50 entries get displayed and
- assigned Function keys.
-
- --Adapter/Mode------|---INT 10H---|Dot-|-Resolution-|------Comments-----------
- -----Name-----------|-AX--BX-CX-DX|Mode|X-|-Y-|Color|-------------------------
- */
- "IBM Low-Rez EGA", 0x0d, 0, 0, 0, 2, 320, 200, 16, "Quick, but chunky",
- "IBM 16-Color EGA", 0x10, 0, 0, 0, 2, 640, 350, 16, "Slower, but lots nicer",
- "IBM 256-Color MCGA",0x13, 0, 0, 0, 3, 320, 200,256, "Quick, LOTS of colors",
- "IBM 16-Color VGA", 0x12, 0, 0, 0, 2, 640, 480, 16, "Nice, high resolution",
- "IBM 4-Color CGA", 0x05, 0, 0, 0, 1, 320, 200, 4, "BIOS",
- "IBM Hi-Rez B&W CGA",0x06, 0, 0, 0, 1, 640, 200, 2, "BIOS",
- "IBM B&W EGA", 0x0f, 0, 0, 0, 2, 640, 350, 2, "(Monochrome EGA)",
- "IBM B&W VGA", 0x11, 0, 0, 0, 2, 640, 480, 2, "(Monochrome VGA)",
- "END", 3, 0, 0, 0, 0, 0, 0, 0, "Marks END of the List"
- };
-
- int maxvideomode; /* size of the above list */
- int adapter; /* Video Adapter chosen from above list */
-
- char *fkeys[] = { /* Function Key names for display table */
- "F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10",
- "SF1","SF2","SF3","SF4","SF5","SF6","SF7","SF8","SF9","SF10",
- "CF1","CF2","CF3","CF4","CF5","CF6","CF7","CF8","CF9","CF10",
- "AF1","AF2","AF3","AF4","AF5","AF6","AF7","AF8","AF9","AF10",
- "END"};
- char *accessmethod[] = {" ","B"," "," "}; /* BIOS access indicator */
-
- #define MAXHISTORY 80 /* save this many historical rcds */
-
- double history[MAXHISTORY][4]; /* for historical (HOME Key) purposes */
-
- /*
- the following variables are out here only so
- that the assembler routine can get at them easily
- */
- int dotmode; /* video access method */
- /* 1 == use the BIOS (ugh) */
- /* 2 == access like EGA/VGA */
- /* 3 == access like MCGA */
- int xdots, ydots; /* # of dots on the screen */
- int colors; /* maximum colors available */
- int maxit; /* try this many iterations */
- int ixmin, ixmax, iymin, iymax; /* corners of the zoom box */
-
- double delx, dely; /* screen pixel increments */
- double xmin, xmax, ymin, ymax; /* screen corner values */
- double c_r, c_i;
- double limit;
-
- /********************************************************************/
- /** module level variables **/
- /********************************************************************/
- static int new_argc;
- static int far *it_took = 0l;
- static char *new_argv[20];
- static int time_delay = -1;
-
- static int type = 0; /* Fractal type */
- /* 0 = Mandelbrot */
- /* 1 = cube biomorph */
- /* 2 = ^5 biomorph */
- /* 3 = sin biomorph */
- static struct {
- double xmin; double xmax;
- double ymin; double ymax;
- double c_r;
- double c_i;
- double limit;
- int maxit;
- } defaults[] = {
- /* xmin xmax ymin ymax c_r c_i limit max iterations */
- { -2.0, 1.0, -1.5, 1.5, 0.0, 0.0, 4.0, 150}, /* Mandelbrot c_r and c_i aren't used */
- {-16.0, 16.0, -10.0, 10.0, 0.5, 0.0, 10.0, 150}, /* biom cubed */
- { -8.0, 8.0, -5.0, 5.0, 0.7, 0.3, 5.0, 150}, /* biom ^5 */
- {-14.0, 14.0, -10.0, 10.0, 0.1, 0.1, 10.0, 150}}; /* biom sin+squared */
-
-
- /*.FUNCTION *********************************************************
- * Name: scan_for_switches Fred Dunlap 09/21/89
- * Purpose: Scans through argv looking for switches. If it finds one it
- * removes it from new_argv. The args that are not switches are
- * left in new_argv.
- *
- * Inputs: argc and argv.
- *
- * Outputs: number of errors in the switches found
- * initialized new_argc and new_argv.
- *
- * Called by: main
- ****************************************************************************/
- scan_for_switches(int argc, char *argv[])
- {
- /* supported switches:
- -Fx x is 1-9 for video mode.
- -x x is 1-4 for fractal set.
- -Tssss:oooo ssss:oooo is seg and offset of int variable to write 18.2th seconds into
- -Dxx xx is delay time after draw before exit (unless key hit). */
- int error = 0;
- int i;
- new_argc = 0;
- while (argc) {
- i = strlen(argv[0]);
- if (*argv[0] == '-' && (i == 2 ||
- i == 11 && argv[0][6] == ':' && argv[0][1] == 'T' ||
- i == 4 && toupper(argv[0][1]) == 'D' ||
- i == 3 && toupper(argv[0][1]) == 'F')) {
- if (i == 2) {
- /* type switch */
- i = argv[0][1];
- if (i > '0' && i < '5')
- type = i - '1';
- else
- error += 1;
- } else if (i == 3) {
- i = argv[0][2];
- if (i > '0' && i < '9') {
- adapter = i - '1';
- } else
- error += 1;
- } else if (i == 4) {
- time_delay = atoi(argv[0]+2);
- time_delay *= 18;
- } else if (i == 11) {
- if (sscanf(argv[0]+2,"%p", &it_took) != 3) {
- /* Microsoft C supports the %p but assigns THREE things.
- I would assume other compilers won't do this and this
- will need modifing. */
- error += 1;
- it_took = 0l;
- }
- } else {
- } /* time address */
- } else
- new_argv[new_argc++] = argv[0];
- argc -= 1;
- argv++;
- }
- return error;
- } /* end scan_for_switches */
-
- /*.FUNCTION *********************************************************
- * Name: Fred Dunlap 09/21/89
- * Purpose:
- *
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- * Called by:
- ****************************************************************************/
- get_initial_mode()
- {
- int i, j, kbdchar; /* keyboard key-hit value */
- printf("Biom V2 by Fred Dunlap from a Bert Tyler program.\n");
- printf("This program (BIOM) can be started with options on the command line.\n");
- printf("The options are numbers specifing: limit Cr Ci xmin xmax ymin ymax.\n");
- printf("The useful keys you can hit while this program is running are:\n");
- printf(" PgUp/PgDn Shrink/Expand the Zoom Box\n");
- printf(" Cursor Keys Move the Zoom Box Left, Right, Up, or Down (Panning)\n");
- printf(" Ctrl-Cursor-Keys Pan as above, but quickly (may require an Enhanced KBD)\n");
- printf(" End or Enter Redraw (full screen) the area inside the Zoom Box \n");
- printf(" F1,F2,F3,F4... Select a new Video Mode (-Fx on the command line)\n");
- printf(" Home Redraw Previous screen (you can 'back out' recursively)\n");
- printf(" Tab Display the Screen or Zoom-Box X and Y Coordinates\n");
- printf(" Insert Restart the program (at this screen)\n");
- printf(" Delete or Esc Stop the program and return.\n");
- printf(" 1 Mandelbrot set fractal. (-1 on the command line)\n");
- printf(" 2 Biomorph z^3 + c. (-2 on the command line)\n");
- printf(" 3 Biomorph z^5 + c. (-3 on the command line)\n");
- printf(" 4 Biomorph sin(z) +z^2 + c. (-4 on the command line)\n");
- printf("Hitting any key while the program is drawing will stop the drawing immediately\n");
- printf("to perform the function. This means you can begin Zooming and Panning (or\n");
- printf("anything else) as soon as you see something interesting. If you haven't yet\n");
- printf("hit a key when the screen is finished, the program will beep and wait for you.\n");
- printf("\n");
- printf("Please Select your Video Mode by hitting a Function Key (F1, F2, F3, F4,...) \n");
- printf(" (Or hit the <ENTER> key to see a complete list of supported Video modes) \n");
-
- j = maxvideomode; /* init for video modes scan */
- for (;;) { /* wait for valid Fn Key */
- kbdchar = getakey();
- if (kbdchar >= 1059 && kbdchar < 1069 /* F1 - F10 */
- && kbdchar < 1059 + maxvideomode) {
- adapter = kbdchar - 1059; /* use this adapter initially */
- break;
- }
- if (kbdchar >= 1084 && kbdchar < 1114 /* SF1 - AF10 */
- && kbdchar < 1074 + maxvideomode) {
- adapter = kbdchar - 1074; /* use this adapter initially */
- break;
- }
- if (kbdchar >= 1120 && kbdchar < 1130 /* Alt-1 thru Alt-0 */
- && kbdchar < 1080 + maxvideomode) {
- adapter = kbdchar - 1080; /* use this adapter initially */
- break;
- }
- if (kbdchar == 1000) exit(0); /* Control-C */
- if (kbdchar == 27) exit(0); /* exit to DOS on Escape Key */
- if (kbdchar == 1083) exit(0); /* exit to DOS on Delete Key */
- if (kbdchar == 13) { /* <ENTER> key: display adapter list */
- j += 14; /* display next page */
- if (j >= maxvideomode) j = 0; /* (or 1st page) */
- printf("\n\n\nThe current list of supported Video Adapters and Modes includes:\n\n");
- printf(" %-20s Resolution Colors %-30s\n\n",
- "Video Adapter & Mode", " Comments");
- for (i = j; i < maxvideomode && i < j + 14; i++) {
- printf("%-5s %-20s%6d x%4d%5d %1s %-30s\n",fkeys[i],
- videomode[i].name,
- videomode[i].xdots,
- videomode[i].ydots,
- videomode[i].colors,
- accessmethod[videomode[i].dotmode],
- videomode[i].comment
- );
- }
- for (; i < j+15; i++) printf("\n");
- printf(" (Hit the <ENTER> key to see another page of supported Video modes) \n\n");
- printf("Please Select your Video Mode by hitting a Function Key (F1, F2, F3, F4,...) \n");
- printf(" (Notation: F1, SF1, CF1, AF1 == Normal-, Shift-, Control- or Alt-F1) \n");
- printf(" 'B' after #-of-colors means video access is via the BIOS (s-l-o-w-l-y)\n");
- printf("The program will begin with the full set as a starting point. ");
- }
- }
- }
-
- /*.FUNCTION *********************************************************
- * Name: Fred Dunlap 09/21/89
- * Purpose:
- *
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- * Called by:
- ****************************************************************************/
- set_defaults()
- {
- maxit = defaults[type].maxit; /* max iterations */
- limit = defaults[type].limit;
- c_i = defaults[type].c_i;
- c_r = defaults[type].c_r;
- xmax = defaults[type].xmax;
- xmin = defaults[type].xmin;
- ymax = defaults[type].ymax;
- ymin = defaults[type].ymin;
- }
-
-
- /*.FUNCTION *********************************************************
- * Name: Fred Dunlap 09/21/89
- * Purpose:
- *
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- * Called by:
- ****************************************************************************/
- main(argc,argv)
- int argc;
- char *argv[];
- {
- double atof();
- unsigned int start_time, delta_time;
- int xstep, ystep; /* zoom-box increment values */
- int axmode, bxmode, cxmode, dxmode; /* video mode (BIOS ##) */
- int historyptr; /* pointer into history tbl */
- int zoomoff; /* = 0 when zoom is disabled */
- int kbdchar; /* keyboard key-hit value */
- int more, kbdmore; /* continuation variables */
- int i,j; /* temporary loop counters */
- union REGS regs;
-
- adapter = -1;
-
- scan_for_switches(argc,argv);
- if (kbhit())
- getch();
-
-
- for (maxvideomode = 0; /* get size of adapter list */
- strcmp(videomode[maxvideomode].name,"END") != 0
- && maxvideomode < 50; /* that's all the Fn keys we got! */
- maxvideomode++);
-
-
- restart: /* insert key re-starts here */
- set_defaults();
-
-
- if (new_argc > 1) {
- limit = atof(new_argv[1]);
- if (limit == 0.0)
- limit = 10.0;
- }
-
- if (new_argc > 2)
- c_r = atof(new_argv[2]);
-
- if (new_argc > 3)
- c_i = atof(new_argv[3]);
-
- if (new_argc > 4)
- xmin = atof(new_argv[4]);
-
- if (new_argc > 5)
- xmax = atof(new_argv[5]);
-
- if (xmax <= xmin)
- xmax = xmin + 10.0;
-
- if (new_argc > 6)
- ymin = atof(new_argv[6]);
-
- if (new_argc > 7)
- ymax = atof(new_argv[7]);
-
- if (ymax <= ymin)
- ymax = ymin + 10.0;
-
- setvideomode(3,0,0,0); /* switch to text mode */
-
- if (adapter == -1)
- get_initial_mode();
-
- historyptr = 0; /* initialize history ptr */
- history[0][0] = -1;
- zoomoff = 1; /* zooming is enabled */
-
-
- for (more = 1; more;) { /* eternal loop */
-
- /* collect adapter info */
- axmode = videomode[adapter].videomodeax; /* video mode (BIOS call) */
- bxmode = videomode[adapter].videomodebx; /* video mode (BIOS call) */
- cxmode = videomode[adapter].videomodecx; /* video mode (BIOS call) */
- dxmode = videomode[adapter].videomodecx; /* video mode (BIOS call) */
- dotmode = videomode[adapter].dotmode; /* assembler dot read/write */
- xdots = videomode[adapter].xdots; /* # dots across the screen */
- ydots = videomode[adapter].ydots; /* # dots down the screen */
- colors = videomode[adapter].colors; /* # colors available */
-
- xstep = xdots / 40; /* zoom-box increment: across */
- ystep = ydots / 40; /* zoom-box increment: down */
- if (xdots == 640 && ydots == 350) /* zoom-box adjust: 640x350 */
- { xstep = 16; ystep = 9; }
- if (xdots == 720 && ydots == 512) /* zoom-box adjust: 720x512 */
- { xstep = 20; ystep = 15; }
- if (xdots == 1024 && ydots == 768) /* zoom-box adjust: 1024x768 */
- { xstep = 32; ystep = 24; }
-
- delx = (xmax - xmin) / (xdots - 1); /* calculate the stepsizes */
- dely = (ymax - ymin) / (ydots - 1);
-
- if (delx <= 0.0 || dely <= 0.0) { /* oops. zoomed too far */
- zoomoff = 0;
- dely = .000000001; /* !!! s.b. epslon */
- delx = .000000001;
- }
- #if 0
- if (zoomoff == 0) {
- xmax = xmaxlx0[xdots-1]; /* re-set xmax and ymax */
- ymin = ly0[ydots-1];
- }
- #endif
-
- if (history[0][0] == -1) /* initialize the history file */
- for (i = 0; i < MAXHISTORY; i++) {
- history[i][0] = xmax;
- history[i][1] = xmin;
- history[i][2] = ymax;
- history[i][3] = ymin;
- }
-
- if (history[historyptr][0] != xmax || /* save any (new) zoom data */
- history[historyptr][1] != xmin ||
- history[historyptr][2] != ymax ||
- history[historyptr][3] != ymin) {
- if (++historyptr == MAXHISTORY) historyptr = 0;
- history[historyptr][0] = xmax;
- history[historyptr][1] = xmin;
- history[historyptr][2] = ymax;
- history[historyptr][3] = ymin;
- }
-
- setvideomode( axmode, bxmode, cxmode, dxmode); /* switch video modes */
- regs.x.ax = 0;
- int86( 26, ®s, ®s);
- start_time = regs.x.dx;
- if (regs.h.al == 1)
- regs.x.dx = 0;
-
-
- switch( type) {
- case 0:
- kbdmore = calcdots_f(); /* draw the fractal */
- break;
- case 1:
- kbdmore = calcdots_b3();
- break;
- case 2:
- kbdmore = calcdots_b5();
- break;
- case 3:
- kbdmore = calcdots_sin();
- break;
- }
-
- regs.x.ax = 0;
- int86( 26, ®s, ®s);
- if (regs.h.al == 1 || kbdmore)
- start_time = regs.x.dx;
- delta_time = regs.x.dx - start_time;
- start_time = regs.x.dx; /* for -Dxx timing */
-
- if (!kbdmore)
- printf("\007"); /* finished! wake up! */
-
- if (kbdmore)
- time_delay = 0;
-
- if (time_delay >= 0) { /* auto exit timing */
- while( regs.x.dx - start_time < time_delay && !kbhit()) {
- regs.x.ax = 0;
- int86( 26, ®s, ®s);
- }
- if (kbhit())
- time_delay = -1;
- else {
- if (it_took != 0l);
- *it_took = delta_time;
- setvideomode(3,0,0,0); /* all done. return to text mode. */
- exit(0);
- }
- }
-
- ixmin = 0;
- ixmax = xdots-1; /* initial zoom box */
- iymin = 0;
- iymax = ydots-1;
-
- kbdmore = 1;
- while (kbdmore == 1) { /* loop through cursor keys */
- kbdchar = getakey();
- switch (kbdchar) {
- case 32: /* spacebar */
- kbdmore = 0;
- break;
- case 1071: /* home */
- if (--historyptr < 0)
- historyptr = MAXHISTORY-1;
- xmax = history[historyptr][0];
- xmin = history[historyptr][1];
- ymax = history[historyptr][2];
- ymin = history[historyptr][3];
- zoomoff = 1;
- kbdmore = 0;
- break;
- case 9: /* tab */
- printf(" The Current Boundaries are: \n");
- printf(" Xmin = %16.13f \n",xmin);
- printf(" Xmax = %16.13f \n",xmax);
- printf(" Ymin = %16.13f \n",ymin);
- printf(" Ymax = %16.13f \n",ymax);
- continue;
- break;
-
- case '1':
- case '2':
- case '3':
- case '4':
- type = kbdchar - '1';
- set_defaults();
- kbdmore = 0;
- break;
-
- case 13: /* Enter */
- case 1079: /* end */
- xmax = xmin + delx * ixmax;
- xmin += delx * ixmin;
- ymin = ymax - dely * iymax;
- ymax -= dely * iymin;
- kbdmore = 0;
- break;
- case 1082: /* insert */
- adapter = -1;
- goto restart;
- break;
- case 1000: /* Control-C */
- case 27: /* Escape */
- case 1083: /* delete */
- more = 0; kbdmore = 0;
- break;
- case 1075: /* cursor left */
- if (zoomoff == 1 && ixmin >= 1)
- { ixmin -= 1; ixmax -= 1; }
- break;
- case 1077: /* cursor right */
- if (zoomoff == 1 && ixmax < xdots - 1)
- { ixmin += 1; ixmax += 1; }
- break;
- case 1072: /* cursor up */
- if (zoomoff == 1 && iymin >= 1)
- { iymin -= 1; iymax -= 1; }
- break;
- case 1080: /* cursor down */
- if (zoomoff == 1 && iymax < ydots - 1)
- { iymin += 1; iymax += 1; }
- break;
- case 1115: /* Ctrl-cursor left */
- if (zoomoff == 1 && ixmin >= 5)
- { ixmin -= 5; ixmax -= 5; }
- break;
- case 1116: /* Ctrl-cursor right */
- if (zoomoff == 1 && ixmax < xdots - 5)
- { ixmin += 5; ixmax += 5; }
- break;
- case 1141: /* Ctrl-cursor up */
- if (zoomoff == 1 && iymin >= 5)
- { iymin -= 5; iymax -= 5; }
- break;
- case 1145: /* Ctrl-cursor down */
- if (zoomoff == 1 && iymax < ydots - 5)
- { iymin += 5; iymax += 5; }
- break;
- case 1073: /* page up */
- if (zoomoff == 1
- && ixmax - ixmin > 3 * xstep
- && iymax - iymin > 3 * ystep) {
- /* 640x350 Zoom-In Klooge: Adjust the
- Zoom-Box on the initial Zoom-In */
- if (xdots == 640 && ydots == 350
- && iymin == 0 && iymax == ydots-1) {
- iymin -= 5;
- iymax += 5;
- }
- /* 720x512 Zoom-In Klooge: Adjust the
- Zoom-Box on the initial Zoom-In */
- if (xdots == 720 && ydots == 512
- && iymin == 0 && iymax == ydots-1) {
- iymin -= 14;
- iymax += 14;
- }
- ixmin += xstep; ixmax -= xstep;
- iymin += ystep; iymax -= ystep;
- }
- break;
- case 1081: /* page down */
- if (zoomoff == 1
- && ixmin >= xstep && ixmax < xdots - xstep
- && iymin >= ystep && iymax < ydots - ystep) {
- ixmin -= xstep; ixmax += xstep;
- iymin -= ystep; iymax += ystep;
- }
- break;
- default: /* other (maybe a valid Fn key) */
- if (kbdchar >= 1059 && kbdchar < 1069
- && kbdchar < 1059 + maxvideomode) {
- adapter = kbdchar - 1059;
- kbdmore = 0;
- }
- else if (kbdchar >= 1084 && kbdchar < 1114
- && kbdchar < 1074 + maxvideomode) {
- adapter = kbdchar - 1074;
- kbdmore = 0;
- }
- else if (kbdchar >= 1120 && kbdchar < 1130
- && kbdchar < 1080 + maxvideomode) {
- adapter = kbdchar - 1080;
- kbdmore = 0;
- }
- else
- continue;
- break;
- }
-
- if (zoomoff == 1 && kbdmore == 1) { /* draw a zoom box? */
- drawbox(); /* (yup) */
- }
- }
-
- }
-
- setvideomode(3,0,0,0); /* all done. return to text mode. */
- exit(0);
-
- }
-