|
|
1.1 root 1: /*** Mandel.c - compute and display Mandelbrot set 1.1.1.2 ! root 2: * ! 3: * Created by Microsoft Corp. 1986 1.1 root 4: */ 5: 6: 7: 8: /** Mandel compute the elements of the Mandelbrot set 9: * 10: * z = z**2 + c 11: * 12: * where z and c are in the complex plane and z = 0 + 0i for the first 13: * iteration. The elements of the set along with the description of the 14: * computation are written to the .cnt file. 15: */ 16: 17: 18: 19: 20: /** Call 21: * 22: * mandel -v {-u a+bi} {-l c+di} {-r num} {-c num} {-i itr} {-a f} {-f name} 23: * {-d display} 24: * 25: * where 26: * 27: * a compute each point with an aspect ratio of f where 28: * f is : 29: * f.ffff floating point number describing the 30: * ratio of width vs height of each pixel 31: * 32: * c number of points across the real coordinate. This 33: * value cannot exceed 2000 and is defaulted to 640. 34: * 35: * d set display to device. The default display is EGA. 36: * CGA Color Graphics Adapter 37: * columns = 350 38: * rows = 200 39: * aspect = 2.4 40: * 41: * EGA Extended Graphics Adapter 42: * columns = 640 43: * rows = 350 44: * aspect = 2.4 45: * 46: * PGA Professional Graphics Adapter 47: * columns = 640 48: * rows = 480 49: * aspect = 1.0 50: * 51: * f name for the .cnt file 52: * If name is not specified, "mandel" is used. 53: * 54: * i iteration limit. This value cannot exceed 1000 and 55: * the default is 256 56: * 57: * l lower right corner as c+di 58: * 59: * 60: * r number of points down the imaginary coordinate. This 61: * value is defaulted to 350. 62: * 63: * u upper left corner as a+bi 64: * 65: * v display information about each scan line as processed 66: * 67: * The .cnt file has the format 68: * int number of points along the real axis 69: * int number of points along the imaginary axis 70: * int maximum iteration point for each point 71: * double real coordinate of upper left 72: * double imaginary coordinate of upper left 73: * double real coordinate of lower right 74: * double imaginary coordinate lower rightft 75: * long (loop + 1) counters for histogram values 76: */ 77: 1.1.1.2 ! root 78: #define INCL_DOSDEVICES 1.1 root 79: 1.1.1.2 ! root 80: #include <os2def.h> 1.1 root 81: #include <stdio.h> 1.1.1.2 ! root 82: #include <bsedos.h> 1.1 root 83: 84: int mandinter (); 85: 86: #define MAXREAL 2000 /* maximum number of points in line */ 87: #define MAXLOOP 1000 /* maximum number of iterations */ 88: 89: #define CGA_DEV 0 /* Color Graphics Adapter */ 90: #define CGA_COL 350 /* number of display columns for CGA */ 91: #define CGA_ROW 200 /* number of display rows for CGA */ 92: #define CGA_ASP 12/5 /* aspect ratio (width/height) for CGA */ 93: 94: #define EGA_DEV 1 /* Extended Graphics Adapter */ 95: #define EGA_COL 640 /* number of display columns for EGA */ 96: #define EGA_ROW 350 /* number of display rows for EGA */ 97: #define EGA_ASP 1.33 /* aspect ratio (width/height) for EGA */ 98: 99: #define PGA_DEV 2 /* Professional Graphics Adapter */ 100: #define PGA_COL 640 /* number of display columns for PGA */ 101: #define PGA_ROW 480 /* number of display rows for PGA */ 102: #define PGA_ASP 1.0 /* aspect ratio (width/height) for PGA */ 103: 104: 105: struct cmplx { 106: double realp; /* real part of number */ 107: double imagp; /* imaginary part of number */ 108: }; 109: 110: 111: 1.1.1.2 ! root 112: char fp287; /* 287 processor status from DosDevConfig */ 1.1 root 113: char pmand[60] = "mandel.cnt"; /* file name for loop counts */ 114: FILE *fmand; 115: 116: double rinc; /* increment in real coordinate */ 117: double iinc; /* increment in imaginary coordinate */ 118: 119: int device = EGA_DEV; /* default device type */ 120: int arg_device = -1; /* device type from arguments */ 121: int mcount[MAXREAL]; /* array holding interation counters */ 122: int rlcount[MAXREAL + 2]; /* run length encoded interation counters */ 123: int nreal = EGA_COL; /* number of points on real coordinate */ 124: int arg_nreal = 0; /* number real coordinate from arguments */ 125: int nimag = EGA_ROW; /* number of points on imaginary coordinate */ 126: int arg_nimag = 0; /* number imaginary coordinate from arguments */ 127: int loop = 256; /* maximum loop count for each point */ 128: int verbose = FALSE; /* display scan line information if true */ 129: double aspect = EGA_ASP; /* default screen aspect ratio */ 130: double arg_aspect = 0.0; /* aspect from arguments */ 131: 132: long hist[MAXLOOP + 1] = {0}; /* histogram counters */ 133: 134: struct cmplx c; /* value of mandelbrot seed */ 135: struct cmplx ul; /* coordinates of upper left corner */ 136: struct cmplx lr; /* coordinates of lower right corner */ 137: 138: 139: main (argc, argv) 140: int argc; 141: char **argv; 142: { 143: int nr; 144: int ni; 145: int i; 146: int temp; 147: int *rl; 148: long position; 149: 1.1.1.2 ! root 150: if (DosDevConfig (&fp287, 3, 0) != 0) { 1.1 root 151: printf ("Unable to get fp processor presence flag\n"); 152: exit (1); 153: } 154: if (fp287 != 1) { 155: printf ("There is not a 287 fp processor present\n"); 156: exit (1); 157: } 158: nextarg (argc, argv); 159: if ((fmand = fopen (pmand, "wb")) == NULL) { 160: printf ("Unable to open count file %s\n", pmand); 161: exit (3); 162: } 163: if (ul.realp == lr.realp && ul.imagp == lr.imagp) { 164: printf ("%15.13lf+%15.13lfi, %15.13lf+%15.13lfi\n",ul.realp,ul.imagp,lr.realp,lr.imagp); 165: printf ("Upper left real = lower right real\n"); 166: exit (3); 167: } 168: 169: /* reset nreal, nimag, aspect from command line device type */ 170: 171: switch (arg_device) { 172: case CGA_DEV: 173: nreal = CGA_COL; 174: nimag = CGA_ROW; 175: aspect = CGA_ASP; 176: break; 177: 178: case EGA_DEV: 179: nreal = EGA_COL; 180: nimag = EGA_ROW; 181: aspect = EGA_ASP; 182: break; 183: 184: case PGA_DEV: 185: nreal = PGA_COL; 186: nimag = PGA_ROW; 187: aspect = PGA_ASP; 188: break; 189: } 190: 191: /* reset individual parameters */ 192: 193: if (arg_nreal != 0) 194: nreal = arg_nreal; 195: if (arg_nimag != 0) 196: nimag = arg_nimag; 197: if (arg_aspect != 0) 198: aspect = arg_aspect; 199: 200: /* compute the step increments for the specifed aspect */ 201: 202: rinc = (lr.realp - ul.realp) / (double)nreal; 203: iinc = rinc * aspect; 204: 205: lr.imagp = ul.imagp - iinc * nimag; 206: 207: fwrite ((char *)&nreal, sizeof (int), 1, fmand); 208: fwrite ((char *)&nimag, sizeof (int), 1, fmand); 209: fwrite ((char *)&loop, sizeof (int), 1, fmand); 210: fwrite ((char *)&ul, sizeof (ul), 1, fmand); 211: fwrite ((char *)&lr, sizeof (lr), 1, fmand); 212: fwrite ((char *)&rinc, sizeof (rinc), 1, fmand); 213: fwrite ((char *)&iinc, sizeof (iinc), 1, fmand); 214: fwrite ((char *)&aspect, sizeof (aspect), 1, fmand); 215: position = ftell (fmand); 216: fwrite ((char *)hist, sizeof (long), loop + 1, fmand); 217: 218: c.imagp = ul.imagp; 219: for (ni = 0; ni < nimag; ni++) { 220: c.realp = ul.realp; 221: if (verbose) 222: printf ("%4d, %15.13lf + %15.13lfi", ni, c.realp, c.imagp); 223: manditer (c.realp, c.imagp, loop, nreal, mcount, rinc); 224: for (nr = 0; nr < nreal; nr++) { 225: i = mcount[nr]; 226: hist[i]++; 227: } 228: 229: /* run length encode counts for this scan line */ 230: 231: temp = *mcount; 232: nr = 1; 233: rl = rlcount + 1; 234: i = -1; 235: for (; nr < nreal; nr++) { 236: i++; 237: if (mcount[nr] != temp) { 238: /* process change in value */ 239: if (i != 0) 240: /* output count of duplicate values */ 241: *rl++ = -(i + 1); 242: /* output value */ 243: *rl++ = temp; 244: /* reset compression values */ 245: temp = mcount[nr]; 246: i = -1; 247: } 248: } 249: if (i != -1) { 250: if (i != 0) 251: /* output count of duplicate values */ 252: *rl++ = -(i + 2); 253: /* output value */ 254: *rl++ = temp; 255: } 256: *rlcount = rl - rlcount -1; 257: if (verbose) 258: printf ("%4d\n", *rlcount); 259: if (fwrite ((char *)rlcount, sizeof (int), *rlcount + 1, fmand) != 260: *rlcount + 1) { 261: printf ("error writing count file %s\n", pmand); 262: exit (4); 263: } 264: c.imagp -= iinc; 265: } 266: fseek (fmand, position, 0); 267: if (fwrite ((char *)hist, sizeof (long), loop + 1, fmand) != loop + 1) { 268: printf ("error writing histogram to file %s\n", pmand); 269: exit (4); 270: } 271: } 272: 273: 274: 275: /** nextarg - process arguments 276: * 277: */ 278: 279: 280: nextarg (argc, argv) 281: int argc; 282: char **argv; 283: { 284: 285: argv++; 286: while ((argc-- > 0) && (**argv == '-')) { 287: switch (*(*argv+1)) { 288: case 'a': 289: /* specify aspect ratio */ 290: argv++; 291: if ((argc < 1) || 292: (sscanf (*argv++, "%lf", &arg_aspect) != 1)) { 293: printf ("Error specifing aspect\n"); 294: exit (1); 295: } 296: argc--; 297: break; 298: 299: case 'c': 300: /* specify number of columns and limit to maximum value */ 301: argv++; 302: if ((argc < 1) || 303: (sscanf (*argv++, " %d", &arg_nreal) != 1)) { 304: printf ("Error specifying number of real points\n"); 305: exit (1); 306: } 307: argc--; 308: if (arg_nreal > MAXREAL) { 309: arg_nreal = MAXREAL; 310: printf ("Number of columns limited to %d\n", MAXREAL); 311: } 312: break; 313: 314: case 'd': 1.1.1.2 ! root 315: /* specify default device parameters */ 1.1 root 316: argv++; 317: if (strcmp (*argv, "CGA") == 0) 318: arg_device = CGA_DEV; 319: else if (strcmp (*argv, "EGA") == 0) 320: arg_device = EGA_DEV; 321: else if (strcmp (*argv, "PGA") == 0) 322: arg_device = PGA_DEV; 323: else { 324: printf ("Error specifing device\n"); 325: exit (1); 326: } 327: argv++; 328: argc--; 329: break; 330: 331: case 'f': 332: /* specify output file name */ 333: argv++; 334: /* set file name */ 335: strcpy (pmand, *argv); 336: strcat (pmand, ".cnt"); 337: break; 338: 339: case 'i': 340: /* specify iteration count and limit to maximum */ 341: argv++; 342: if ((argc < 1) || 343: (sscanf (*argv++, " %d", &loop) != 1)) { 344: printf ("Error specifying iteration limit\n"); 345: exit (1); 346: } 347: argc--; 348: if (loop > MAXLOOP) { 349: loop = MAXREAL; 350: printf ("Iteration count limited to %d\n", MAXLOOP); 351: } 352: break; 353: 354: case 'l': 355: /* specify lower right corner as c+di */ 356: argv++; 357: if ((argc < 1) || (sscanf (*argv++, "%lf%lfi", 358: &lr.realp, &lr.imagp) != 2)) { 359: printf ("Error specifying lower right\n"); 360: exit (1); 361: } 362: argc--; 363: break; 364: 365: 366: case 'r': 367: /* specify number of rows */ 368: argv++; 369: if ((argc < 1) || 370: (sscanf (*argv++, " %d", &arg_nimag) != 1)) { 371: printf ("Error specifying number of imaginary points\n"); 372: exit (1); 373: } 374: argc--; 375: break; 376: 377: case 'u': 378: /* specify upper right corner as a+bi */ 379: argv++; 380: if ((argc < 1) || (sscanf (*argv++, "%lf%lfi", 381: &ul.realp, &ul.imagp) != 2)) { 382: printf ("Error specifying upper left\n"); 383: exit (1); 384: } 385: argc--; 386: break; 387: 388: case 'v': 389: /* specify verbose output */ 390: argv++; 391: verbose = TRUE; 392: break; 393: 394: default: 395: printf ("Unknown argument %s\n", *argv); 396: exit (1); 397: 398: } 399: } 400: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.