home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Graphics 16,000
/
graphics-16000.iso
/
msdos
/
fractal
/
fdesi313
/
fdes13s
/
fdesign.c
< prev
next >
Wrap
Text File
|
1990-01-23
|
22KB
|
534 lines
/*
Fractal Designer using IFS (iteration function system) codes.
Using Turbo C 2.0 with Compact model
Author: Doug Nelson
REF: Article in BYTE, January 1988 on the random method of generating
fractals.
1-22-90 added FdesGif module, courtesy Bert Tyler via Compuserve
rev 3.06
1-17-90 changed color scheme rev 3.04
removed 256 color modes
added "alternate display" to top menu
(seems to be a rare problem with reading in .IFS files)
1-16-90 added re-crop to modify menu
added reading of .IFS files from FRACTINT
1-15-90 added zooming to virtual screen
1-14-90 added writing of .IFS files for FRACTINT
added zooming to top menu
12-13-89 added Epson 24 pin support
12-9-89 updated fdesign.doc file and changed rev to v2.00
added genoa/orchid 640x480x256 mode (untested)
12-3-89 added clipping in MCGA and Super VGA modes
added virtual screen build display
12-2-89 added Epson 9 pin printer support & added print menus
11-26-89 changed menus, clipped small plot window, nice filename input v1.18
11-25-89 added small plot of fractal when selecting filename v1.15
11-24-89 added "grat on/off" to modify menu v1.13
11-14-89 added virtual screen support (1200 x 1504) & printing
11-13-89 HP laserjet II and modify screen print work
11-12-89 Began printer support for HP laserjet II
11-9-89 Super VGA colors change with mouse up/down
11-9-89 added k=0 to fix Floating point Domain error in 'plotabunch'
10-8-89 set_palette now does a 256 color plot instead of b&w rev 1.05
10-1-89 set_palette routine for initializing 64 level B&W
9-30-89 started 320x200x256 color display
9-28-89 added command line display of .TRN files v1.02
9-20-89 made rev 1.00 package
9-19-89 added "adjust triangle" and interactive display rev 0.10
9-18-89 fixed up header files so modules are more object-oriented
added another FDESMODI module for the modify menu
added hook for mouse_click to do idle_task
9-15-89 modularized Fdesign into 7 modules, rev 0.03
9-14-89 added BIOS equipment check for co-processor
9-10-89 added directory to "load" command
9-6-89 added command-line display of .TRN file and keyboard escape.
9-5-89 added real IFS probability (not just 1/num_triangles)
9-4-89 added BGI driver and cleaned up user interface
9-3-89 added 'delete triangle' and 'add triangle' to modify menu
9-2-89 re-arranged top level
9-1-89 began modify menu
8-30-89 began mouse menus
8-15-89 made # of triangle transformations variable
8-13-89 added mouse and IFS code calculations
*/
#include <stdio.h> /* standard stuff */
#include <conio.h> /* for gotoxy(x,y) */
#include <float.h> /* floating point */
#include <graphics.h> /* graphics */
#include <string.h> /* string functions */
#include <bios.h>
#include <dos.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
#include <alloc.h>
#include <io.h>
#include "fdesglob.h"
#include "fdestria.h"
#include "fdesequa.h"
#include "fdesfile.h"
#include "fdesmenu.h"
#include "fdesmodi.h"
#include "fdesmous.h"
#include "fdesplot.h"
#include "fdeshres.h"
#include "fdesprin.h"
#include "fdesvirt.h"
#include "fdesifs.h"
#include "fdesgif.h"
#define MAXFUNC 33 /* maximum # of IFS codes in picture */
#define GRAT_X 40
#define GRAT_Y 30
#define MAXCOLORS_ 13
#define MAXCOLOR 12
int colors[MAXCOLORS_] = { 14,13,12,11,10,9,7,6,5,4,3,2,1 };
unsigned char palate[] = {
0, 0, 0, 0, 0,168, 0,168, 0, 0,168,168,
168, 0, 0,168, 0,168,168, 84, 0,168,168,168,
84, 84, 84, 84, 84,252, 84,252, 84, 84,252,252,
252, 84, 84,252, 84,252,252,252, 84,252,252,252
};
int num_triangles;
triangle triangle0; /* reference triangle */
int triangle0_is;
triangle triangles[MAXFUNC]; /* triangle data stores */
int maxcolor;
/*
an array holding the IFS codes generated from the triangle
transformations
*/
float IFS[1+MAXFUNC*7] = { /* example: Sierpinski's triangle */
3,
0.5, 0, 0, 0.5, 0, 0, 0.34,
0.5, 0, 0, 0.5, 1, 0, 0.33,
0.5, 0, 0, 0.5, 0.5, 0.5, 0.33 } ;
/* used only by revs */
char revstring[7];
char *revs(void)
{
int integ,fract;
integ = REV/100;
fract = REV%100;
sprintf(revstring,"v%d.%02d",integ,fract);
return(revstring);
}
popmenu topmenu = {
12 ,
"Normal Plot", "Edit transformations", "Load from disk" ,
"Save to disk", "Quit",
/* " ( MCGA plot )", " ( Super VGA )", */
"Alternate Display",
"Print", "Virtual Screen Print", "IFS codes (FRACTINT)", "Zoom In", "Zoom Reset",
"Save to .GIF",
"stats"
};
popmenu virtmenu = {
4 ,
"Plot 1000000 points", "Plot N points", "Print", "Return"
};
int break_func(void)
{
restorecrtmode();
printf("\nControl Break Abort");
printf("\nFractal Designer %s written by Doug Nelson",revs());
return(0); /* 0 means abort user program */
}
/*
Math error handler
*/
double _matherr(_mexcep why, char *fun, double *arg1p, double *arg2p,
double retval)
{
printf("\nMath exception report:");
printf("\n type = %d",why);
printf("\n function = %s",fun);
printf("\n arg1 = %lf",*arg1p);
printf("\n arg2 = %lf",*arg2p);
printf("\n retval = %lf",retval);
exit(0);
return(0.0);
}
void default_fractal(void)
{
num_triangles = 3;
triangle0.row[0] = 0x11d; triangle0.col[0] = 0x96;
triangle0.row[1] = 0x11d; triangle0.col[1] = 0x10e;
triangle0.row[2] = 0xa5; triangle0.col[2] = 0x10e;
triangle0_is = 1;
triangles[0].row[0] = 0x11d; triangles[0].col[0] = 0x96;
triangles[0].row[1] = 0x11d; triangles[0].col[1] = 0xd2;
triangles[0].row[2] = 0xe1; triangles[0].col[2] = 0xd2;
triangles[1].row[0] = 0x11d; triangles[1].col[0] = 0xd2;
triangles[1].row[1] = 0x11d; triangles[1].col[1] = 0x10e;
triangles[1].row[2] = 0xe1; triangles[1].col[2] = 0x10e;
triangles[2].row[0] = 0xa5; triangles[2].col[0] = 0x10e;
triangles[2].row[1] = 0xa5; triangles[2].col[1] = 0xd2;
triangles[2].row[2] = 0xe1; triangles[2].col[2] = 0xd2;
IFS_changed = 1;
}
/************************************************************************
MAIN PROGRAM
************************************************************************/
void main(int argc, char *argv[]) /* int argc, char *argv[]) */
{
char title[80];
char fname[80];
char *fnptr;
int gr_driver;
int gr_mode;
int done,vdone;
int select;
char ch;
int i;
int virt_scaled; /* flags if virtual screen scaled once before */
char virt_scaled_line[80];
ctrlbrk(break_func);
if ((biosequip() & 0x02) == 0) {
printf("\nBIOS reports no coprocessor. This program runs very slow without one.");
printf("\nDo you wish to continue (Y/N) ?");
scanf("%c",&ch);
if ((ch == 'n') || (ch == 'N')) exit(0);
}
if (registerfarbgidriver(EGAVGA_driver_far) < 0) exit(0);
randomize();
gr_driver = DETECT; /* DETECT, EGA or VGA; */
gr_mode = VGAHI; /* VGAHI or EGA64HI */
initgraph(&gr_driver,&gr_mode,"");
if (gr_driver != VGA) {
gr_driver = EGA;
gr_mode = EGA64HI;
initgraph(&gr_driver,&gr_mode,"");
if (graphresult() != grOk) {
printf("The graphics require VGA or EGA.");
exit(0);
}
}
maxcolor = getmaxcolor();
maxx = getmaxx();
maxy = getmaxy();
/* command line call */
if (argc > 1) {
if (trnfile_load(argv[1]) != 0) {
IFS_changed = 1;
plot_type = 0;
doIFSrand();
restorecrtmode();
}
else {
restorecrtmode();
printf("File not Found");
}
printf("\nFractal Designer %s written by Doug Nelson",revs());
exit(0);
}
stpcpy(last_file,"No file");
file_modified = 0;
if (mouse_reset()==0) {
restorecrtmode();
printf("\nA MS-compatible mouse driver is required.");
exit(0);
}
done = 0;
default_fractal();
sprintf(title,"Fractal Designer %s by Doug Nelson %s",revs(),__DATE__);
putmsg(0,120,title,BLUE,WHITE);
putmsg(0,0,"Press Left Mouse button for menu",RED,WHITE);
plot_type = 0;
doIFSrand();
clrmsg();
clrmsg();
use_grat = 1; /* use graticules when positioning triangles */
do {
putmsg(320,0,last_file,GREEN,WHITE);
if (file_modified) putmsg(320,20,"modified",RED,WHITE);
select = popup(10,10,&topmenu,WHITE,DARKGRAY);
if (file_modified) clrmsg();
clrmsg();
switch (select) {
case 1: /* plot fractal */
cleardevice();
plot_type = 0;
doIFSrand();
break;
case 2: /* modify transformations */
modify_input();
break;
case 3: /* load from disk */
gotoxy(1,1);
if ((fnptr = trn_directory()) != NULL)
if (trnfile_load(fnptr) != 0) {
IFS_changed = 1;
modify_input();
};
break;
case 4: /* save to disk */
do {
if (gscanf(100,100,"Save to File: ",
8,"%s",fname))
{
trn_name_fix(fname);
if (access(fname,0) != 0)
{
trnfile_save(fname);
break;
}
else
{
if (gscanf(80,80,"File Exists, replace (Y/N)? ",
1,"%c",&ch))
{
if ((ch == 'Y') || (ch == 'y'))
{
trnfile_save(fname);
break;
}
}
else break;
}
}
else break;
} while (1);
break;
case 5: /* quit */
done = 1;
break;
case 6: /* plot fractal */
cleardevice();
plot_type = 6;
doIFSrand();
break;
/*
case 6: /* MCGA plot fractal */
if (gr_driver == EGA)
{
putmsg(130,130,
"Requires VGA",
RED, WHITE);
delay(1000);
clrmsg();
break;
}
plot_type = 2; /* MCGA */
putmsg(130,130,
"Move mouse UP or DOWN to change palette",
BLACK, GREEN);
delay(2000);
clrmsg();
init256(0x13);
maxcolor = 256;
maxx = 319;
maxy = 199;
doIFSrand();
setgraphmode(gr_mode);
maxcolor = getmaxcolor();
maxx = getmaxx();
maxy = getmaxy();
mouse_reset();
break;
case 7: /* Super VGA */
if (gr_driver == EGA)
{
putmsg(130,130,
"Requires Super VGA",
RED, WHITE);
delay(1000);
clrmsg();
break;
}
plot_type = 3; /* Super VGA */
if ((select = vcard_type_check()) == 0)
{
break;
}
else
{
putmsg(130,130,
"Move mouse UP or DOWN to change palette",
BLACK, GREEN);
delay(2000);
clrmsg();
init256(select);
}
maxcolor = 256;
maxx = 639;
maxy = 479;
doIFSrand();
setgraphmode(gr_mode);
maxcolor = getmaxcolor();
maxx = getmaxx();
maxy = getmaxy();
mouse_reset();
break;
*/
case 7: /* print */
if (printer_type_check() == 1) break;
if (print_confirm() == 1) break;
pprintf("File: %s\n\r",last_file);
if (file_modified) pprintf(" modified");
putmsg(100,100,"Print Part One",RED,WHITE);
delay(1000);
clrmsg();
printscreen();
modify_scr();
putmsg(100,100,"Print Part Two",RED,WHITE);
delay(1000);
clrmsg();
printscreen();
pprintf("\n\rScreen IFS codes are:\n\r");
for (i=0; i<num_triangles; i++)
{
pprintf("%9.4f %9.4f %9.4f %9.4f %9.4f %9.4f %7.4f\n\r",
IFS[1+i*7+0],IFS[1+i*7+1],
IFS[1+i*7+2],IFS[1+i*7+3],
IFS[1+i*7+4],IFS[1+i*7+5],
IFS[1+i*7+6]);
}
prn_endpage();
cleardevice();
break;
case 8: /* build virtual screen */
if (vscreen_open() == 0) break;
cleardevice();
virt_scaled = 0;
vdone = 0;
do {
virt_target_size = (long)(1000000*area_scaled);
sprintf(virt_scaled_line,"Plot %ldK points",virt_target_size/1000);
virtmenu.item[0] = virt_scaled_line;
select = popup(10,10,&virtmenu,YELLOW,BROWN);
switch (select) {
case 1: /* plot 1000000 points */
cleardevice();
/* clear virtual screen */
putmsg(100,100,"Clearing Virtual Screen",BLUE,WHITE);
vscreen_clear();
clrmsg();
if (virt_scaled == 0)
xscale = VWIDTH/maxx;
yscale = VHEIGHT/maxy;
if (xscale > yscale) xscale = yscale;
else yscale = xscale;
IFS_rescale(xscale,-(maxx/2.0)*xscale+VWIDTH/2.0,
yscale,-(maxy/2.0)*yscale+VHEIGHT/2.0,1);
virt_scaled = 1;
plot_type = 4;
doIFSrand();
break;
case 2: /* plot N points */
if (gscanf(70,70,"Number of points (in thousands):",6,"%ld",&virt_target_size) == 0) break;
/* clear virtual screen */
if (virt_target_size <= 0) break;
virt_target_size *= 1000;
cleardevice();
putmsg(100,100,"Clearing Virtual Screen",BLUE,WHITE);
vscreen_clear();
clrmsg();
if (virt_scaled == 0)
/* &&& fix the aspect ratio */
IFS_rescale(VWIDTH/maxx,-(maxx/2.0)*VWIDTH/maxx+VWIDTH/2.0,
VHEIGHT/maxy,-(maxy/2.0)*VHEIGHT/maxy+VHEIGHT/2.0,1);
virt_scaled = 1;
plot_type = 4;
doIFSrand();
break;
case 3: /* print */
if (printer_type_check() == 1) break;
if (print_confirm() == 1) break;
putmsg(100,100,"Printing Virtual Screen",BLUE,WHITE);
printvscreen();
clrmsg();
prn_endpage();
cleardevice();
break;
case 4: /* return */
vscreen_close();
cleardevice();
vdone = 1;
break;
}
} while (!vdone);
plot_type = 0;
IFS_changed = 1; /* To force re-comp of IFS codes */
break;
case 9: /* IFS codes */
ifs_menu();
break;
case 10: /* zoom in */
zoom_in();
cleardevice();
if (!((plot_type == 0) || (plot_type == 6)))
plot_type = 0;
doIFSrand();
break;
case 11: /* zoom out */
zoom_out();
break;
case 12: /* save to .GIF */
do {
if (gscanf(100,100,"Save .GIF File: ",
8,"%s",fname))
{
gif_name_fix(fname);
if (access(fname,0) != 0)
{
if (create_gif(maxx+1,maxy+1,16,palate,6,fname) == 0)
{
put_image(maxx+1,maxy+1,0,0,0,0,NULL);
close_gif();
}
break;
}
else
{
if (gscanf(80,80,"File Exists, replace (Y/N)? ",
1,"%c",&ch))
{
if ((ch == 'Y') || (ch == 'y'))
{
if (create_gif(maxx+1,maxy+1,16,palate,6,fname) == 0)
{
put_image(maxx+1,maxy+1,0,0,0,0,NULL);
close_gif();
}
break;
}
}
else break;
}
}
else break;
} while (1);
break;
case 13: /* stats */
break;
}
} while (!done);
restorecrtmode();
printf("\nFractal Designer %s written by Doug Nelson",revs());
}