home *** CD-ROM | disk | FTP | other *** search
/ Graphics 16,000 / graphics-16000.iso / msdos / fractal / fdesi313 / fdes13s / fdesign.c < prev    next >
Text File  |  1990-01-23  |  22KB  |  534 lines

  1. /*
  2.         Fractal Designer using IFS (iteration function system) codes.
  3.     Using Turbo C 2.0 with Compact model
  4.  
  5.     Author: Doug Nelson
  6.  
  7.     REF: Article in BYTE, January 1988 on the random method of generating
  8.     fractals.
  9.  
  10.     1-22-90 added FdesGif module, courtesy Bert Tyler via Compuserve
  11.         rev 3.06
  12.     1-17-90 changed color scheme            rev 3.04
  13.         removed 256 color modes
  14.                 added "alternate display" to top menu
  15.         (seems to be a rare problem with reading in .IFS files)
  16.         1-16-90 added re-crop to modify menu
  17.                 added reading of .IFS files from FRACTINT
  18.     1-15-90 added zooming to virtual screen
  19.     1-14-90 added writing of .IFS files for FRACTINT
  20.         added zooming to top menu
  21.         12-13-89 added Epson 24 pin support
  22.         12-9-89 updated fdesign.doc file and changed rev to v2.00
  23.                 added genoa/orchid 640x480x256 mode (untested)
  24.     12-3-89 added clipping in MCGA and Super VGA modes
  25.         added virtual screen build display
  26.         12-2-89 added Epson 9 pin printer support & added print menus
  27.         11-26-89 changed menus, clipped small plot window, nice filename input v1.18
  28.         11-25-89 added small plot of fractal when selecting filename v1.15
  29.         11-24-89 added "grat on/off" to modify menu v1.13
  30.         11-14-89 added virtual screen support (1200 x 1504) & printing
  31.     11-13-89 HP laserjet II and modify screen print work
  32.         11-12-89 Began printer support for HP laserjet II
  33.     11-9-89 Super VGA colors change with mouse up/down
  34.     11-9-89 added k=0 to fix Floating point Domain error in 'plotabunch'
  35.     10-8-89 set_palette now does a 256 color plot instead of b&w rev 1.05
  36.     10-1-89 set_palette routine for initializing 64 level B&W
  37.     9-30-89 started 320x200x256 color display
  38.         9-28-89 added command line display of .TRN files v1.02
  39.     9-20-89 made rev 1.00 package
  40.     9-19-89 added "adjust triangle" and interactive display rev 0.10
  41.     9-18-89 fixed up header files so modules are more object-oriented
  42.         added another FDESMODI module for the modify menu
  43.         added hook for mouse_click to do idle_task
  44.         9-15-89 modularized Fdesign into 7 modules, rev 0.03
  45.     9-14-89 added BIOS equipment check for co-processor
  46.     9-10-89 added directory to "load" command
  47.     9-6-89 added command-line display of .TRN file and keyboard escape.
  48.     9-5-89 added real IFS probability (not just 1/num_triangles)
  49.     9-4-89 added BGI driver and cleaned up user interface
  50.     9-3-89 added 'delete triangle' and 'add triangle' to modify menu
  51.     9-2-89 re-arranged top level
  52.     9-1-89 began modify menu
  53.     8-30-89 began mouse menus
  54.     8-15-89 made # of triangle transformations variable
  55.     8-13-89    added mouse and IFS code calculations
  56. */
  57. #include <stdio.h>                      /* standard stuff */
  58. #include <conio.h>                      /* for gotoxy(x,y) */
  59. #include <float.h>                      /* floating point */
  60. #include <graphics.h>                   /* graphics */
  61. #include <string.h>                     /* string functions */
  62. #include <bios.h>
  63. #include <dos.h>
  64. #include <stdlib.h>
  65. #include <time.h>
  66. #include <math.h>
  67. #include <alloc.h>
  68. #include <io.h>
  69. #include "fdesglob.h"
  70. #include "fdestria.h"
  71. #include "fdesequa.h"
  72. #include "fdesfile.h"
  73. #include "fdesmenu.h"
  74. #include "fdesmodi.h"
  75. #include "fdesmous.h"
  76. #include "fdesplot.h"
  77. #include "fdeshres.h"
  78. #include "fdesprin.h"
  79. #include "fdesvirt.h"
  80. #include "fdesifs.h"
  81. #include "fdesgif.h"
  82.  
  83. #define MAXFUNC 33                      /* maximum # of IFS codes in picture */
  84. #define GRAT_X 40
  85. #define GRAT_Y 30
  86. #define MAXCOLORS_ 13
  87. #define MAXCOLOR 12
  88.  
  89. int colors[MAXCOLORS_] = { 14,13,12,11,10,9,7,6,5,4,3,2,1 };
  90.  
  91.  
  92. unsigned char palate[] = {
  93.       0,  0,  0,  0,  0,168,  0,168,  0,  0,168,168,
  94.     168,  0,  0,168,  0,168,168, 84,  0,168,168,168,
  95.      84, 84, 84, 84, 84,252, 84,252, 84, 84,252,252,
  96.     252, 84, 84,252, 84,252,252,252, 84,252,252,252
  97.     };
  98.  
  99. int num_triangles;
  100. triangle triangle0;        /* reference triangle */
  101. int triangle0_is;
  102. triangle triangles[MAXFUNC];         /* triangle data stores */
  103. int maxcolor;
  104. /*
  105.         an array holding the IFS codes generated from the triangle
  106.         transformations
  107. */
  108. float IFS[1+MAXFUNC*7] = {      /* example: Sierpinski's triangle */
  109.     3,
  110.     0.5,    0,    0,    0.5,    0,    0,    0.34,
  111.     0.5,    0,    0,    0.5,    1,    0,    0.33,
  112.     0.5,    0,    0,    0.5,    0.5,    0.5,    0.33 } ;
  113.  
  114. /* used only by revs */
  115. char revstring[7];
  116. char *revs(void)
  117. {
  118. int integ,fract;
  119.     integ = REV/100;
  120.     fract = REV%100;
  121.     sprintf(revstring,"v%d.%02d",integ,fract);
  122.     return(revstring);
  123. }
  124.  
  125.  
  126. popmenu topmenu = {
  127.     12 ,
  128.         "Normal Plot", "Edit transformations", "Load from disk" ,
  129.         "Save to disk", "Quit",
  130.         /* " ( MCGA plot )", " ( Super VGA )", */
  131.         "Alternate Display",
  132.         "Print", "Virtual Screen Print", "IFS codes (FRACTINT)", "Zoom In", "Zoom Reset",
  133.         "Save to .GIF",
  134.         "stats"
  135.     };
  136.  
  137. popmenu virtmenu = {
  138.         4 ,
  139.         "Plot 1000000 points", "Plot N points", "Print", "Return"
  140.         };
  141.  
  142. int break_func(void)
  143. {
  144.     restorecrtmode();
  145.         printf("\nControl Break Abort");
  146.     printf("\nFractal Designer %s written by Doug Nelson",revs());
  147.         return(0);              /* 0 means abort user program */
  148. }
  149. /*
  150.         Math error handler
  151. */
  152. double _matherr(_mexcep why, char *fun, double *arg1p, double *arg2p,
  153.         double retval)
  154. {
  155.         printf("\nMath exception report:");
  156.     printf("\n   type = %d",why);
  157.     printf("\n   function = %s",fun);
  158.     printf("\n   arg1 = %lf",*arg1p);
  159.     printf("\n   arg2 = %lf",*arg2p);
  160.     printf("\n   retval = %lf",retval);
  161.     exit(0);
  162.     return(0.0);
  163. }
  164. void default_fractal(void)
  165. {
  166.         num_triangles = 3;
  167.         triangle0.row[0] = 0x11d; triangle0.col[0] = 0x96;
  168.         triangle0.row[1] = 0x11d; triangle0.col[1] = 0x10e;
  169.         triangle0.row[2] = 0xa5; triangle0.col[2] = 0x10e;
  170.     triangle0_is = 1;
  171.         triangles[0].row[0] = 0x11d; triangles[0].col[0] = 0x96;
  172.         triangles[0].row[1] = 0x11d; triangles[0].col[1] = 0xd2;
  173.         triangles[0].row[2] = 0xe1; triangles[0].col[2] = 0xd2;
  174.         triangles[1].row[0] = 0x11d; triangles[1].col[0] = 0xd2;
  175.         triangles[1].row[1] = 0x11d; triangles[1].col[1] = 0x10e;
  176.         triangles[1].row[2] = 0xe1; triangles[1].col[2] = 0x10e;
  177.         triangles[2].row[0] = 0xa5; triangles[2].col[0] = 0x10e;
  178.         triangles[2].row[1] = 0xa5; triangles[2].col[1] = 0xd2;
  179.     triangles[2].row[2] = 0xe1; triangles[2].col[2] = 0xd2;
  180.         IFS_changed = 1;
  181. }
  182.  
  183. /************************************************************************
  184.         MAIN PROGRAM
  185. ************************************************************************/
  186. void main(int argc, char *argv[])     /* int argc, char *argv[]) */
  187. {
  188. char title[80];
  189. char fname[80];
  190. char *fnptr;
  191. int gr_driver;
  192. int gr_mode;
  193. int done,vdone;
  194. int select;
  195. char ch;
  196. int i;
  197. int virt_scaled;                /* flags if virtual screen scaled once before */
  198. char virt_scaled_line[80];
  199.  
  200.         ctrlbrk(break_func);
  201.         if ((biosequip() & 0x02) == 0) {
  202.                 printf("\nBIOS reports no coprocessor.  This program runs very slow without one.");
  203.                 printf("\nDo you wish to continue (Y/N) ?");
  204.         scanf("%c",&ch);
  205.         if ((ch == 'n') || (ch == 'N')) exit(0);
  206.     }
  207.         if (registerfarbgidriver(EGAVGA_driver_far) < 0) exit(0);
  208.     randomize();
  209.         gr_driver = DETECT; /* DETECT, EGA or VGA; */
  210.         gr_mode = VGAHI; /* VGAHI or EGA64HI */
  211.     initgraph(&gr_driver,&gr_mode,"");
  212.     if (gr_driver != VGA) {
  213.         gr_driver = EGA;
  214.         gr_mode = EGA64HI;
  215.         initgraph(&gr_driver,&gr_mode,"");
  216.         if (graphresult() != grOk) {
  217.             printf("The graphics require VGA or EGA.");
  218.             exit(0);
  219.         }
  220.     }
  221.     maxcolor = getmaxcolor();
  222.     maxx = getmaxx();
  223.     maxy = getmaxy();
  224.  
  225.         /* command line call */
  226.         if (argc > 1) {
  227.            if (trnfile_load(argv[1]) != 0) {
  228.                         IFS_changed = 1;
  229.                         plot_type = 0;
  230.                         doIFSrand();
  231.                         restorecrtmode();
  232.                 }
  233.                 else {
  234.                         restorecrtmode();
  235.                         printf("File not Found");
  236.                 }
  237.                 printf("\nFractal Designer %s written by Doug Nelson",revs());
  238.                 exit(0);
  239.         }
  240.     stpcpy(last_file,"No file");
  241.         file_modified = 0;
  242.         if (mouse_reset()==0) {
  243.         restorecrtmode();
  244.         printf("\nA MS-compatible mouse driver is required.");
  245.                 exit(0);
  246.         }
  247.     done = 0;
  248.  
  249.         default_fractal();
  250.  
  251.     sprintf(title,"Fractal Designer %s by Doug Nelson %s",revs(),__DATE__);
  252.     putmsg(0,120,title,BLUE,WHITE);
  253.         putmsg(0,0,"Press Left Mouse button for menu",RED,WHITE);
  254.         plot_type = 0;
  255.         doIFSrand();
  256.     clrmsg();
  257.     clrmsg();
  258.         use_grat = 1;                   /* use graticules when positioning triangles */
  259.         do {
  260.                 putmsg(320,0,last_file,GREEN,WHITE);
  261.                 if (file_modified) putmsg(320,20,"modified",RED,WHITE);
  262.                 select = popup(10,10,&topmenu,WHITE,DARKGRAY);
  263.                 if (file_modified) clrmsg();
  264.         clrmsg();
  265.         switch (select) {
  266.             case 1: /* plot fractal */
  267.                 cleardevice();
  268.                                 plot_type = 0;
  269.                                 doIFSrand();
  270.                 break;
  271.             case 2: /* modify transformations */
  272.                                 modify_input();
  273.                 break;
  274.             case 3: /* load from disk */
  275.                 gotoxy(1,1);
  276.                 if ((fnptr = trn_directory()) != NULL)
  277.                     if (trnfile_load(fnptr) != 0) {
  278.                                                 IFS_changed = 1;
  279.                                                 modify_input();
  280.                                         };
  281.                 break;
  282.             case 4: /* save to disk */
  283.                                 do {
  284.                                         if (gscanf(100,100,"Save to File: ",
  285.                                                 8,"%s",fname))
  286.                                         {
  287.                                                 trn_name_fix(fname);
  288.                         if (access(fname,0) != 0)
  289.                         {
  290.                             trnfile_save(fname);
  291.                             break;
  292.                         }
  293.                                                 else
  294.                                                 {
  295.                                                         if (gscanf(80,80,"File Exists, replace (Y/N)? ",
  296.                                                                1,"%c",&ch))
  297.                                                         {
  298.                                 if ((ch == 'Y') || (ch == 'y'))
  299.                                 {
  300.                                     trnfile_save(fname);
  301.                                     break;
  302.                                 }
  303.                                                         }
  304.                                                         else break;
  305.                                                 }
  306.                                         }
  307.                                         else break;
  308.                                 } while (1);
  309.                 break;
  310.             case 5: /* quit */
  311.                 done = 1;
  312.                                 break;
  313.             case 6: /* plot fractal */
  314.                 cleardevice();
  315.                                 plot_type = 6;
  316.                                 doIFSrand();
  317.                 break;
  318. /*
  319.                         case 6: /* MCGA plot fractal */
  320.                                 if (gr_driver == EGA)
  321.                                 {
  322.                                         putmsg(130,130,
  323.                                                 "Requires VGA",
  324.                                                 RED, WHITE);
  325.                                         delay(1000);
  326.                                         clrmsg();
  327.                                         break;
  328.                                 }
  329.                 plot_type = 2;        /* MCGA */
  330.                                 putmsg(130,130,
  331.                                         "Move mouse UP or DOWN to change palette",
  332.                                         BLACK, GREEN);
  333.                                 delay(2000);
  334.                                 clrmsg();
  335.                                 init256(0x13);
  336.                                 maxcolor = 256;
  337.                                 maxx = 319;
  338.                                 maxy = 199;
  339.  
  340.                 doIFSrand();
  341.  
  342.                 setgraphmode(gr_mode);
  343.                 maxcolor = getmaxcolor();
  344.                 maxx = getmaxx();
  345.                 maxy = getmaxy();
  346.                 mouse_reset();
  347.  
  348.                                 break;
  349.                         case 7: /* Super VGA */
  350.                                 if (gr_driver == EGA)
  351.                                 {
  352.                                         putmsg(130,130,
  353.                                                 "Requires Super VGA",
  354.                                                 RED, WHITE);
  355.                                         delay(1000);
  356.                                         clrmsg();
  357.                                         break;
  358.                                 }
  359.                                 plot_type = 3;        /* Super VGA */
  360.                                 if ((select = vcard_type_check()) == 0)
  361.                                 {
  362.                                         break;
  363.                                 }
  364.                                 else
  365.                                 {
  366.                     putmsg(130,130,
  367.                                                 "Move mouse UP or DOWN to change palette",
  368.                                                 BLACK, GREEN);
  369.                                         delay(2000);
  370.                                         clrmsg();
  371.                                         init256(select);
  372.                                 }
  373.                                 maxcolor = 256;
  374.                                 maxx = 639;
  375.                                 maxy = 479;
  376.  
  377.                 doIFSrand();
  378.  
  379.                 setgraphmode(gr_mode);
  380.                 maxcolor = getmaxcolor();
  381.                 maxx = getmaxx();
  382.                 maxy = getmaxy();
  383.                 mouse_reset();
  384.  
  385.                                 break;
  386. */
  387.                         case 7: /* print */
  388.                                 if (printer_type_check() == 1) break;
  389.                                 if (print_confirm() == 1) break;
  390.                                 pprintf("File: %s\n\r",last_file);
  391.                                 if (file_modified) pprintf(" modified");
  392.                                 putmsg(100,100,"Print Part One",RED,WHITE);
  393.                                 delay(1000);
  394.                                 clrmsg();
  395.                                 printscreen();
  396.                                 modify_scr();
  397.                                 putmsg(100,100,"Print Part Two",RED,WHITE);
  398.                                 delay(1000);
  399.                                 clrmsg();
  400.                                 printscreen();
  401.                                 pprintf("\n\rScreen IFS codes are:\n\r");
  402.                                 for (i=0; i<num_triangles; i++)
  403.                                 {
  404.                                         pprintf("%9.4f %9.4f %9.4f %9.4f %9.4f %9.4f %7.4f\n\r",
  405.                                                 IFS[1+i*7+0],IFS[1+i*7+1],
  406.                                                 IFS[1+i*7+2],IFS[1+i*7+3],
  407.                                                 IFS[1+i*7+4],IFS[1+i*7+5],
  408.                                                 IFS[1+i*7+6]);
  409.                                 }
  410.                                 prn_endpage();
  411.                                 cleardevice();
  412.                                 break;
  413.                         case 8: /* build virtual screen */
  414.                                 if (vscreen_open() == 0) break;
  415.                                 cleardevice();
  416.                                 virt_scaled = 0;
  417.                                 vdone = 0;
  418.                                 do {
  419.                                 virt_target_size = (long)(1000000*area_scaled);
  420.                                 sprintf(virt_scaled_line,"Plot %ldK points",virt_target_size/1000);
  421.                                 virtmenu.item[0] = virt_scaled_line;
  422.                                 select = popup(10,10,&virtmenu,YELLOW,BROWN);
  423.                                 switch (select) {
  424.                                         case 1: /* plot 1000000 points */
  425.                                                 cleardevice();
  426.                                                 /* clear virtual screen */
  427.                                                 putmsg(100,100,"Clearing Virtual Screen",BLUE,WHITE);
  428.                                                 vscreen_clear();
  429.                                                 clrmsg();
  430.                                                 if (virt_scaled == 0)
  431.                                                 xscale = VWIDTH/maxx;
  432.                                                 yscale = VHEIGHT/maxy;
  433.                                                 if (xscale > yscale) xscale = yscale;
  434.                                                 else yscale = xscale;
  435.                                                 IFS_rescale(xscale,-(maxx/2.0)*xscale+VWIDTH/2.0,
  436.                                                             yscale,-(maxy/2.0)*yscale+VHEIGHT/2.0,1);
  437.                                                 virt_scaled = 1;
  438.                                                 plot_type = 4;
  439.                                                 doIFSrand();
  440.                                                 break;
  441.                                         case 2: /* plot N points */
  442.                                                 if (gscanf(70,70,"Number of points (in thousands):",6,"%ld",&virt_target_size) == 0) break;
  443.                                                 /* clear virtual screen */
  444.                                                 if (virt_target_size <= 0) break;
  445.                                                 virt_target_size *= 1000;
  446.                                                 cleardevice();
  447.                                                 putmsg(100,100,"Clearing Virtual Screen",BLUE,WHITE);
  448.                                                 vscreen_clear();
  449.                                                 clrmsg();
  450.                                                 if (virt_scaled == 0)
  451.                                                 /* &&& fix the aspect ratio */
  452.                                                 IFS_rescale(VWIDTH/maxx,-(maxx/2.0)*VWIDTH/maxx+VWIDTH/2.0,
  453.                                                             VHEIGHT/maxy,-(maxy/2.0)*VHEIGHT/maxy+VHEIGHT/2.0,1);
  454.                                                 virt_scaled = 1;
  455.                                                 plot_type = 4;
  456.                                                 doIFSrand();
  457.                                                 break;
  458.                                         case 3: /* print */
  459.                         if (printer_type_check() == 1) break;
  460.                                                 if (print_confirm() == 1) break;
  461.                                                 putmsg(100,100,"Printing Virtual Screen",BLUE,WHITE);
  462.                                                 printvscreen();
  463.                                                 clrmsg();
  464.                                                 prn_endpage();
  465.                                                 cleardevice();
  466.                                                 break;
  467.                                         case 4: /* return */
  468.                                                 vscreen_close();
  469.                                                 cleardevice();
  470.                                                 vdone = 1;
  471.                                                 break;
  472.                                         }
  473.                                 } while (!vdone);
  474.                                 plot_type = 0;
  475.                                 IFS_changed = 1; /* To force re-comp of IFS codes */
  476.                 break;
  477.                         case 9: /* IFS codes */
  478.                                 ifs_menu();
  479.                                 break;
  480.                         case 10: /* zoom in */
  481.                                 zoom_in();
  482.                                 cleardevice();
  483.                 if (!((plot_type == 0) || (plot_type == 6)))
  484.                     plot_type = 0;
  485.                 doIFSrand();
  486.                                 break;
  487.                         case 11: /* zoom out */
  488.                                 zoom_out();
  489.                                 break;
  490.                         case 12: /* save to .GIF */
  491.                                 do {
  492.                                         if (gscanf(100,100,"Save .GIF File: ",
  493.                                                 8,"%s",fname))
  494.                                         {
  495.                                                 gif_name_fix(fname);
  496.                         if (access(fname,0) != 0)
  497.                         {
  498. if (create_gif(maxx+1,maxy+1,16,palate,6,fname) == 0)
  499. {
  500.         put_image(maxx+1,maxy+1,0,0,0,0,NULL);
  501.         close_gif();
  502. }
  503.                             break;
  504.                         }
  505.                                                 else
  506.                                                 {
  507.                                                         if (gscanf(80,80,"File Exists, replace (Y/N)? ",
  508.                                                                1,"%c",&ch))
  509.                                                         {
  510.                                 if ((ch == 'Y') || (ch == 'y'))
  511.                                 {
  512. if (create_gif(maxx+1,maxy+1,16,palate,6,fname) == 0)
  513. {
  514.         put_image(maxx+1,maxy+1,0,0,0,0,NULL);
  515.         close_gif();
  516. }
  517.                                     break;
  518.                                 }
  519.                                                         }
  520.                                                         else break;
  521.                                                 }
  522.                                         }
  523.                                         else break;
  524.                                 } while (1);
  525.                 break;
  526.             case 13: /* stats */
  527.                                 break;
  528.                 }
  529.     } while (!done);
  530.     restorecrtmode();
  531.     printf("\nFractal Designer %s written by Doug Nelson",revs());
  532. }
  533.  
  534.