home *** CD-ROM | disk | FTP | other *** search
- /*
- FRACTINT - The Ultimate Fractal Generator
- Main Routine
- */
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <time.h>
- #include <signal.h>
- #ifndef XFRACT
- #include <io.h>
- #include <dos.h>
- #include <stdarg.h>
- #else
- #include <varargs.h>
- #endif
- #include <ctype.h>
-
- #include "prototyp.h"
- #include "fractype.h"
- #include "helpdefs.h"
-
- struct videoinfo videoentry;
- int helpmode;
-
- long timer_start,timer_interval; /* timer(...) start & total */
- int adapter; /* Video Adapter chosen from list in ...h */
- char *fract_dir1="", *fract_dir2="";
-
- #ifdef __TURBOC__
-
- /* yes, I *know* it's supposed to be compatible with Microsoft C,
- but some of the routines need to know if the "C" code
- has been compiled with Turbo-C. This flag is a 1 if FRACTINT.C
- (and presumably the other routines as well) has been compiled
- with Turbo-C. */
- int compiled_by_turboc = 1;
-
- /* set size to be used for overlays, a bit bigger than largest (help) */
- unsigned _ovrbuffer = 54 * 64; /* that's 54k for overlays, counted in paragraphs */
-
- #else
-
- int compiled_by_turboc = 0;
-
- #endif
-
- /*
- the following variables are out here only so
- that the calcfract() and assembler routines can get at them easily
- */
- int active_system = 0; /* 0 for DOS, WINFRAC for Windows */
- int dotmode; /* video access method */
- int textsafe2; /* textsafe override from videotable */
- int oktoprint; /* 0 if printf() won't work */
- int sxdots,sydots; /* # of dots on the physical screen */
- int sxoffs,syoffs; /* physical top left of logical screen */
- int xdots, ydots; /* # of dots on the logical screen */
- double dxsize, dysize; /* xdots-1, ydots-1 */
- int colors; /* maximum colors available */
- long maxit; /* try this many iterations */
- int boxcount; /* 0 if no zoom-box yet */
- int zrotate; /* zoombox rotation */
- double zbx,zby; /* topleft of zoombox */
- double zwidth,zdepth,zskew; /* zoombox size & shape */
-
- int fractype; /* if == 0, use Mandelbrot */
- char stdcalcmode; /* '1', '2', 'g', 'b' */
- long creal, cimag; /* real, imag'ry parts of C */
- long delx, dely; /* screen pixel increments */
- long delx2, dely2; /* screen pixel increments */
- LDBL delxx, delyy; /* screen pixel increments */
- LDBL delxx2, delyy2; /* screen pixel increments */
- long delmin; /* for calcfrac/calcmand */
- double ddelmin; /* same as a double */
- double param[MAXPARAMS]; /* parameters */
- double potparam[3]; /* three potential parameters*/
- long fudge; /* 2**fudgefactor */
- long l_at_rad; /* finite attractor radius */
- double f_at_rad; /* finite attractor radius */
- int bitshift; /* fudgefactor */
-
- int badconfig = 0; /* 'fractint.cfg' ok? */
- int diskisactive; /* disk-video drivers flag */
- int diskvideo; /* disk-video access flag */
- int hasinverse = 0;
- /* note that integer grid is set when integerfractal && !invert; */
- /* otherwise the floating point grid is set; never both at once */
- long far *lx0, far *ly0; /* x, y grid */
- long far *lx1, far *ly1; /* adjustment for rotate */
- /* note that lx1 & ly1 values can overflow into sign bit; since */
- /* they're used only to add to lx0/ly0, 2s comp straightens it out */
- double far *dx0, far *dy0; /* floating pt equivs */
- double far *dx1, far *dy1;
- int integerfractal; /* TRUE if fractal uses integer math */
-
- /* usr_xxx is what the user wants, vs what we may be forced to do */
- char usr_stdcalcmode;
- int usr_periodicitycheck;
- int usr_distest;
- char usr_floatflag;
-
- int viewwindow; /* 0 for full screen, 1 for window */
- float viewreduction; /* window auto-sizing */
- int viewcrop; /* nonzero to crop default coords */
- float finalaspectratio; /* for view shape and rotation */
- int viewxdots,viewydots; /* explicit view sizing */
-
- HISTORY far *history = NULL;
- int maxhistory = 10;
-
- /* variables defined by the command line/files processor */
- int comparegif=0; /* compare two gif files flag */
- int timedsave=0; /* when doing a timed save */
- int resave_flag=0; /* tells encoder not to incr filename */
- int started_resaves=0; /* but incr on first resave */
- int save_system; /* from and for save files */
- int tabmode = 1; /* tab display enabled */
-
- /* for historical reasons (before rotation): */
- /* top left corner of screen is (xxmin,yymax) */
- /* bottom left corner of screen is (xx3rd,yy3rd) */
- /* bottom right corner of screen is (xxmax,yymin) */
- double xxmin,xxmax,yymin,yymax,xx3rd,yy3rd; /* selected screen corners */
- long xmin, xmax, ymin, ymax, x3rd, y3rd; /* integer equivs */
- double sxmin,sxmax,symin,symax,sx3rd,sy3rd; /* displayed screen corners */
- double plotmx1,plotmx2,plotmy1,plotmy2; /* real->screen multipliers */
-
- int calc_status; /* -1 no fractal */
- /* 0 parms changed, recalc reqd */
- /* 1 actively calculating */
- /* 2 interrupted, resumable */
- /* 3 interrupted, not resumable */
- /* 4 completed */
- long calctime;
-
- int max_colors; /* maximum palette size */
- int zoomoff; /* = 0 when zoom is disabled */
- int savedac; /* save-the-Video DAC flag */
- int browsing; /* browse mode flag */
- char file_name_stack[16][13]; /* array of file names used while browsing */
- int name_stack_ptr ;
- double toosmall;
- int minbox;
- int no_sub_images;
- int autobrowse,doublecaution;
- char brwscheckparms,brwschecktype;
- char browsemask[13];
-
- #define RESTART 1
- #define IMAGESTART 2
- #define RESTORESTART 3
- #define CONTINUE 4
-
- static void check_samename(void)
- {
- char drive[FILE_MAX_DRIVE];
- char dir[FILE_MAX_DIR];
- char fname[FILE_MAX_FNAME];
- char ext[FILE_MAX_EXT];
- char path[FILE_MAX_PATH];
- splitpath(savename,drive,dir,fname,ext);
- if(strcmp(fname,"fract001"))
- {
- makepath(path,drive,dir,fname,"gif");
- if(access(path,0)==0)
- exit(0);
- }
- }
-
- /* Do nothing if math error */
- static void my_floating_point_err(int sig)
- {
- if(sig != 0)
- overflow = 1;
- }
-
- void main(int argc, char **argv)
- {
- int resumeflag;
- int kbdchar; /* keyboard key-hit value */
- int kbdmore; /* continuation variable */
- char stacked=0; /* flag to indicate screen stacked */
-
- /* this traps non-math library floating point errors */
- signal( SIGFPE, my_floating_point_err );
-
- initasmvars(); /* initialize ASM stuff */
- checkfreemem(0);
- load_videotable(1); /* load fractint.cfg, no message yet if bad */
- #ifdef XFRACT
- UnixInit();
- #endif
- init_help();
-
- restart: /* insert key re-starts here */
- autobrowse = FALSE;
- brwschecktype = TRUE;
- brwscheckparms = TRUE;
- doublecaution = TRUE;
- no_sub_images = FALSE;
- toosmall = 6;
- minbox = 3;
- strcpy(browsemask,"*.GIF");
- strcpy(browsename," ");
- name_stack_ptr= -1; /* init loaded files stack */
- if (fract_dir1==NULL)
- fract_dir1 = ".";
- cmdfiles(argc,argv); /* process the command-line */
- dopause(0); /* pause for error msg if not batch */
- init_msg(0,"",NULL,0); /* this causes getakey if init_msg called on runup */
- checkfreemem(1);
- if(debugflag==450 && initbatch==1) /* abort if savename already exits */
- check_samename();
- #ifdef XFRACT
- initUnixWindow();
- #endif
- memcpy(olddacbox,dacbox,256*3); /* save in case colors= present */
-
- if (debugflag == 8088) cpu = 86; /* for testing purposes */
- if (debugflag == 2870 && fpu >= 287 ) fpu = 287; /* for testing purposes */
- if (debugflag == 870 && fpu >= 87 ) fpu = 87; /* for testing purposes */
- if (debugflag == 70) fpu = 0; /* for testing purposes */
- if (getenv("NO87")) fpu = 0;
- fract_dir1 = getenv("FRACTDIR");
- if (fract_dir1==NULL) {
- fract_dir1 = ".";
- }
- #ifdef SRCDIR
- fract_dir2 = SRCDIR;
- #else
- fract_dir2 = ".";
- #endif
- if (fpu == 0) iit = 0;
- if (fpu >= 287 && debugflag != 72) /* Fast 287 math */
- setup287code();
-
- /* IIT math coprocessor chip logic */
- if(iit == 0 && fpu)
- if(IITCoPro())
- iit = 3; /* detect iit chip */
- if(iit < 0) iit = 0; /* user wants chip turned off */
- if(iit>0)
- {
- if(F4x4Check())
- iit = 2; /* semaphore TSR is installed */
- else if(iit == 3)
- iit = 0; /* we detetct chip but no tsr - don't use */
- /* else user forced iit == 1 */
- }
-
- adapter_detect(); /* check what video is really present */
- if (debugflag >= 9002 && debugflag <= 9100) /* for testing purposes */
- if (video_type > (debugflag-9000)/2) /* adjust the video value */
- video_type = (debugflag-9000)/2;
-
- diskisactive = 0; /* disk-video is inactive */
- diskvideo = 0; /* disk driver is not in use */
- setvideotext(); /* switch to text mode */
- calc_status = -1; /* no active fractal image */
- savedac = 0; /* don't save the VGA DAC */
-
- #ifndef XFRACT
- if (debugflag == 10000) /* check for free memory */
- showfreemem();
-
- if (badconfig < 0) /* fractint.cfg bad, no msg yet */
- bad_fractint_cfg_msg();
- #endif
-
- max_colors = 256; /* the Windows version is lower */
- max_kbdcount=(cpu==386) ? 80 : 30; /* check the keyboard this often */
-
- if (showfile && initmode < 0) {
- intro(); /* display the credits screen */
- if (keypressed() == ESC) {
- getakey();
- goodbye();
- }
- }
-
- browsing = FALSE;
-
- if (!functionpreloaded)
- set_if_old_bif();
- stacked = 0;
- restorestart:
- if (colorpreloaded)
- memcpy(dacbox,olddacbox,256*3); /* restore in case colors= present */
-
- lookatmouse = 0; /* ignore mouse */
-
- while (showfile <= 0) { /* image is to be loaded */
- char *hdg;
- tabmode = 0;
- if (!browsing ) /*RB*/
- {
- if (overlay3d) {
- hdg = "Select File for 3D Overlay";
- helpmode = HELP3DOVLY;
- }
- else if (display3d) {
- hdg = "Select File for 3D Transform";
- helpmode = HELP3D;
- }
- else {
- hdg = "Select File to Restore";
- helpmode = HELPSAVEREST;
- }
- if (showfile < 0 && getafilename(hdg,gifmask,readname) < 0) {
- showfile = 1; /* cancelled */
- initmode = -1;
- break;
- }
-
- name_stack_ptr = 0; /* 'r' reads first filename for browsing */
- strcpy(file_name_stack[name_stack_ptr],browsename);
- }
-
- showfile = 0;
- helpmode = -1;
- tabmode = 1;
- if(stacked)
- {
- discardscreen();
- setvideotext();
- stacked = 0;
- }
- if (read_overlay() == 0) /* read hdr, get video mode */
- break; /* got it, exit */
- showfile = -1; /* retry */
- }
-
- helpmode = HELPMENU; /* now use this help mode */
- tabmode = 1;
- lookatmouse = 0; /* ignore mouse */
-
- if ((overlay3d || stacked) && initmode < 0) { /* overlay command failed */
- unstackscreen(); /* restore the graphics screen */
- stacked = 0;
- overlay3d = 0; /* forget overlays */
- display3d = 0; /* forget 3D */
- if (calc_status > 0 && calc_status !=2)
- calc_status = 0;
- resumeflag = 1;
- goto resumeloop; /* ooh, this is ugly */
- }
-
- savedac = 0; /* don't save the VGA DAC */
- imagestart: /* calc/display a new image */
- if(stacked)
- {
- discardscreen();
- stacked = 0;
- }
- #ifdef XFRACT
- usr_floatflag = 1;
- #endif
- got_status = -1; /* for tab_display */
-
- if (showfile)
- if (calc_status > 0) /* goto imagestart implies re-calc */
- calc_status = 0;
-
- if (initbatch == 0)
- lookatmouse = -PAGE_UP; /* just mouse left button, == pgup */
-
- cyclelimit = initcyclelimit; /* default cycle limit */
-
-
- adapter = initmode; /* set the video adapter up */
- initmode = -1; /* (once) */
-
- while (adapter < 0) { /* cycle through instructions */
- if (initbatch) { /* batch, nothing to do */
- initbatch = 4; /* exit with error condition set */
- goodbye();
- }
- kbdchar = main_menu(0);
- if (kbdchar == INSERT) goto restart; /* restart pgm on Insert Key */
- if (kbdchar == DELETE) /* select video mode list */
- kbdchar = select_video_mode(-1);
- if ((adapter = check_vidmode_key(0,kbdchar)) >= 0)
- break; /* got a video mode now */
- #ifndef XFRACT
- if ('A' <= kbdchar && kbdchar <= 'Z')
- kbdchar = tolower(kbdchar);
- #endif
- if (kbdchar == 'd') { /* shell to DOS */
- setclear();
- printf("\n\nShelling to DOS - type 'exit' to return\n\n");
- shell_to_dos();
- goto imagestart;
- }
-
- #ifndef XFRACT
- if (kbdchar == '@' || kbdchar == '2') { /* execute commands */
- #else
- if (kbdchar == F2 || kbdchar == '@') { /* We mapped @ to F2 */
- #endif
- if ((get_commands() & 4) == 0)
- goto imagestart;
- kbdchar = '3'; /* 3d=y so fall thru '3' code */
- }
- #ifndef XFRACT
- if (kbdchar == 'r' || kbdchar == '3' || kbdchar == '#') {
- #else
- if (kbdchar == 'r' || kbdchar == '3' || kbdchar == F3) {
- #endif
- display3d = 0;
- if (kbdchar == '3' || kbdchar == '#' || kbdchar == F3)
- display3d = 1;
- if(colorpreloaded)
- memcpy(olddacbox,dacbox,256*3); /* save in case colors= present */
- setvideotext(); /* switch to text mode */
- showfile = -1;
- goto restorestart;
- }
- if (kbdchar == 't') { /* set fractal type */
- julibrot = 0;
- get_fracttype();
- goto imagestart;
- }
- if (kbdchar == 'x') { /* generic toggle switch */
- get_toggles();
- goto imagestart;
- }
- if (kbdchar == 'y') { /* generic toggle switch */
- get_toggles2();
- goto imagestart;
- }
- if (kbdchar == 'z') { /* type specific parms */
- get_fract_params(1);
- goto imagestart;
- }
- if (kbdchar == 'v') { /* view parameters */
- get_view_params();
- goto imagestart;
- }
- if (kbdchar == 2) { /* ctrl B = browse parms*/
- get_browse_params();
- goto imagestart;
- }
- if (kbdchar == 'f') { /* floating pt toggle */
- if (usr_floatflag == 0)
- usr_floatflag = 1;
- else
- usr_floatflag = 0;
- goto imagestart;
- }
- if (kbdchar == 'i') { /* set 3d fractal parms */
- get_fract3d_params(); /* get the parameters */
- goto imagestart;
- }
- if (kbdchar == 'g') {
- get_cmd_string(); /* get command string */
- goto imagestart;
- }
- /* buzzer(2); */ /* unrecognized key */
- }
-
- zoomoff = 1; /* zooming is enabled */
- helpmode = HELPMAIN; /* now use this help mode */
- resumeflag = 0; /* allows taking goto inside big_while_loop() */
- resumeloop:
- /* this switch processes gotos that are now inside function */
- switch(big_while_loop(&kbdmore,&stacked,resumeflag))
- {
- case RESTART:
- goto restart;
- case IMAGESTART:
- goto imagestart;
- case RESTORESTART:
- goto restorestart;
- default:
- break;
- }
- }
-
- int check_key()
- {
- int key;
- if((key = keypressed()) != 0) {
- if(key != 'o' && key != 'O') {
- fflush(stdout);
- return(-1);
- }
- getakey();
- if (dotmode != 11)
- show_orbit = 1 - show_orbit;
- }
- return(0);
- }
-
- /* timer function:
- timer(0,(*fractal)()) fractal engine
- timer(1,NULL,int width) decoder
- timer(2) encoder
- */
- #ifndef XFRACT
- int timer(int timertype,int(*subrtn)(),...)
- #else
- int timer(va_alist)
- va_dcl
- #endif
- {
- va_list arg_marker; /* variable arg list */
- char *timestring;
- time_t ltime;
- FILE *fp = NULL;
- int out=0;
- int i;
- int do_bench;
-
- #ifndef XFRACT
- va_start(arg_marker,subrtn);
- #else
- int timertype;
- int (*subrtn)();
- va_start(arg_marker);
- timertype = va_arg(arg_marker, int);
- subrtn = (int (*)())va_arg(arg_marker, int *);
- #endif
-
- do_bench = timerflag; /* record time? */
- if (timertype == 2) /* encoder, record time only if debug=200 */
- do_bench = (debugflag == 200);
- if(do_bench)
- fp=dir_fopen(workdir,"bench","a");
- timer_start = clock_ticks();
- switch(timertype) {
- case 0:
- out = (*(int(*)(void))subrtn)();
- break;
- case 1:
- i = va_arg(arg_marker,int);
- out = (int)decoder((short)i); /* not indirect, safer with overlays */
- break;
- case 2:
- out = encoder(); /* not indirect, safer with overlays */
- break;
- }
- /* next assumes CLK_TCK is 10^n, n>=2 */
- timer_interval = (clock_ticks() - timer_start) / (CLK_TCK/100);
-
- if(do_bench) {
- time(<ime);
- timestring = ctime(<ime);
- timestring[24] = 0; /*clobber newline in time string */
- switch(timertype) {
- case 1:
- fprintf(fp,"decode ");
- break;
- case 2:
- fprintf(fp,"encode ");
- break;
- }
- fprintf(fp,"%s type=%s resolution = %dx%d maxiter=%ld",
- timestring,
- curfractalspecific->name,
- xdots,
- ydots,
- maxit);
- fprintf(fp," time= %ld.%02ld secs\n",timer_interval/100,timer_interval%100);
- if(fp != NULL)
- fclose(fp);
- }
- return(out);
- }