home *** CD-ROM | disk | FTP | other *** search
- /*
- encoder.c - GIF Encoder and associated routines
- */
-
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
- #ifndef XFRACT
- #include <io.h>
- #endif
- #include "fractint.h"
- #include "fractype.h"
- #include "prototyp.h"
-
- /* MCP 10-27-91 */
- #ifdef WINFRACT
- extern int OperCancelled;
- void OpenStatusBox(void);
- void UpdateStatusBox(unsigned long Partial, unsigned long Total);
- void CloseStatusBox(void);
- #endif
-
- static int inittable(void);
- static int _fastcall shftwrite(BYTE *color,int numcolors);
- static int _fastcall raster(unsigned int);
- static int _fastcall extend_blk_len(int datalen);
- static int _fastcall put_extend_blk(int block_id,int block_len,char far *block_data);
- static int _fastcall store_item_name(char *);
- static void _fastcall setup_save_info(struct fractal_info far *save_info);
-
- #ifdef XFRACT
- int decode_fractal_info();
- #endif
-
- /*
- Save-To-Disk Routines (GIF)
-
- GIF and 'Graphics Interchange Format' are trademarks (tm) of Compuserve
- Incorporated, an H&R Block Company.
-
-
- The following routines perform the GIF encoding when the 's' key is pressed.
- The routines refer to several variables that are declared elsewhere
- [colors, xdots, ydots, and 'dacbox'], and rely on external routines to
- actually read and write screen pixels [getcolor(x,y) and putcolor(x,y,color)].
- (Writing pixels is just stuffed in here as a sort of visual status report,
- and has nothing to do with any GIF function.) They also rely on the
- existence of an externally-defined 64K dataspace and they use the routines
- 'toextra()' and 'cmpextra()' to deal with that dataspace (in the same manner
- as 'memcpy()' and 'memcmp()' would). Otherwise, they perform a generic
- GIF-encoder function.
-
- Note that these routines use small string- and hash-tables, and "flush"
- the GIF entries whenever the hash-table gets two-thirds full or the string
- table gets full. They also use the GIF encoding technique of limiting the
- encoded string length to a specific size, "adding" a string to the hash table
- at that point even if a matching string exists ("adding" is in quotes, because
- if a matching string exists we can increment the code counter but safely throw
- the duplicate string away, saving both string space and a hash table entry).
-
- This results in relatively good speed and small data space, but at the
- expense of compression efficiency (filesize). These trade-offs could be
- adjusted by modifying the #DEFINEd variables below.
-
- Note that the 'strlocn' and 'teststring' routines are declared
- to be external just so that they can be defined (and the space re-used)
- elsewhere. The actual declarations are in the assembler code.
-
- */
-
- #define MAXTEST 100 /* maximum single string length */
- #define MAXSTRING 64000L /* total space reserved for strings */
- /* maximum number of strings available */
- #define MAXENTRY 5003 /* (a prime number is best for hashing) */
-
- #ifdef XFRACT
- unsigned int strlocn[10240];
- BYTE teststring[MAXTEST];
- BYTE block[266]; /* GIF-encoded blocks go here */
- #endif
-
- static int numsaves = 0; /* For adjusting 'save-to-disk' filenames */
-
- static FILE *out;
- static int last_colorbar;
- static int save16bit;
- static int outcolor1s, outcolor2s;
-
- static int lentest, lastentry, numentries, numrealentries;
- static unsigned int nextentry;
- static int clearcode, endcode;
- static unsigned int hashcode;
-
- static BYTE blockcount;
- static int startbits, codebits, bytecount, bitcount;
-
- static BYTE paletteBW[] = { /* B&W palette */
- 0, 0, 0, 63, 63, 63,
- };
- static BYTE paletteCGA[] = { /* 4-color (CGA) palette */
- 0, 0, 0, 21, 63, 63, 63, 21, 63, 63, 63, 63,
- };
- static BYTE paletteEGA[] = { /* 16-color (EGA/CGA) pal */
- 0, 0, 0, 0, 0, 42, 0, 42, 0, 0, 42, 42,
- 42, 0, 0, 42, 0, 42, 42, 21, 0, 42, 42, 42,
- 21, 21, 21, 21, 21, 63, 21, 63, 21, 21, 63, 63,
- 63, 21, 21, 63, 21, 63, 63, 63, 21, 63, 63, 63,
- };
-
- int savetodisk(char *filename) /* save-to-disk routine */
- {
- char tmpmsg[41]; /* before openfile in case of overrun */
- char openfile[80], openfiletype[10];
- char tmpfile[80];
- char *period;
- int newfile;
- int i, j, outcolor1, outcolor2, interrupted;
- restart:
-
- save16bit = disk16bit;
- if (gif87a_flag) /* not storing non-standard fractal info */
- save16bit = 0;
-
- strcpy(openfile,filename); /* decode and open the filename */
- strcpy(openfiletype,DEFAULTFRACTALTYPE);/* determine the file extension */
- if (save16bit)
- strcpy(openfiletype,".pot");
- #if 0
- /* this logic fails if directory name hhas period */
- for (i = 0; i < (int)strlen(openfile); i++)
- if (openfile[i] == '.') {
- strcpy(openfiletype,&openfile[i]);
- openfile[i] = 0;
- }
- #endif
- if((period = has_ext(openfile)) != NULL)
- {
- strcpy(openfiletype,period);
- *period = 0;
- }
- if (resave_flag != 1)
- updatesavename(filename); /* for next time */
-
- strcat(openfile,openfiletype);
-
- strcpy(tmpfile,openfile);
- if (access(openfile,0) != 0) /* file doesn't exist */
- newfile = 1;
- else { /* file already exists */
- if (overwrite == 0) {
- if (resave_flag == 0)
- goto restart;
- if (started_resaves == 0) { /* first save of a savetime set */
- updatesavename(filename);
- goto restart;
- }
- }
- if (access(openfile,2) != 0) {
- sprintf(tmpmsg,s_cantwrite,openfile);
- stopmsg(0,tmpmsg);
- return -1;
- }
- newfile = 0;
- i = strlen(tmpfile);
- while (--i >= 0 && tmpfile[i] != SLASHC)
- tmpfile[i] = 0;
- strcat(tmpfile,"fractint.tmp");
- }
-
- started_resaves = (resave_flag == 1) ? 1 : 0;
- if (resave_flag == 2) /* final save of savetime set? */
- resave_flag = 0;
-
- if ((out=fopen(tmpfile,"wb")) == NULL) {
- sprintf(tmpmsg,s_cantcreate,tmpfile);
- stopmsg(0,tmpmsg);
- return -1;
- }
-
- if (dotmode == 11) { /* disk-video */
- char buf[60];
- sprintf(buf,"Saving %s",openfile);
- dvid_status(1,buf);
- }
- #ifdef XFRACT
- else {
- putstring(3,0,0,"Saving to:");
- putstring(4,0,0,openfile);
- putstring(5,0,0," ");
- }
- #endif
-
- busy = 1;
-
- if (debugflag != 200)
- interrupted = encoder();
- else
- interrupted = timer(2,NULL); /* invoke encoder() via timer */
-
- busy = 0;
-
- fclose(out);
-
- if (interrupted) {
- char buf[200];
- sprintf(buf,"Save of %s interrupted.\nCancel to ",openfile);
- if (newfile)
- strcat(buf,"delete the file,\ncontinue to keep the partial image.");
- else
- strcat(buf,"retain the original file,\ncontinue to replace original with new partial image.");
- interrupted = 1;
- if (stopmsg(2,buf) < 0) {
- interrupted = -1;
- unlink(tmpfile);
- }
- }
-
- if (newfile == 0 && interrupted >= 0) { /* replace the real file */
- unlink(openfile); /* success assumed since we checked */
- rename(tmpfile,openfile); /* earlier with access */
- }
-
- if (dotmode != 11) { /* supress this on disk-video */
- if (active_system == 0) { /* no bars in Windows version */
- outcolor1 = outcolor1s;
- outcolor2 = outcolor2s;
- for (j = 0; j <= last_colorbar; j++) {
- if ((j & 4) == 0) {
- if (++outcolor1 >= colors) outcolor1 = 0;
- if (++outcolor2 >= colors) outcolor2 = 0;
- }
- for (i = 0; 250*i < xdots; i++) { /* clear vert status bars */
- putcolor(i,j,getcolor(i,j)^outcolor1);
- putcolor(xdots-1-i,j,getcolor(xdots-1-i,j)^outcolor2);
- }
- }
- }
- #ifdef XFRACT
- putstring(5,0,0,"Saving done\n");
- #endif
- }
- else /* disk-video */
- dvid_status(1,"");
-
- if (interrupted) {
- static FCODE msg[] = {" *interrupted* save "};
- texttempmsg(msg);
- if (initbatch >= 1) initbatch = 3; /* if batch mode, set error level */
- return -1;
- }
- if (timedsave == 0) {
- buzzer(0);
- if (initbatch == 0) {
- extract_filename(tmpfile,openfile);
- sprintf(tmpmsg," File saved as %s ",tmpfile);
- texttempmsg(tmpmsg);
- }
- }
- if(initsavetime < 0)
- goodbye();
- return 0;
- }
-
-
- int encoder()
- {
- int i, ydot, xdot, color, outcolor1, outcolor2;
- int width;
- int rownum, rowlimit;
- unsigned int hashentry;
- BYTE bitsperpixel, x;
- int entrynum;
- struct fractal_info save_info;
- unsigned int maxstring;
-
- ydot = 0;
- /* arbitrary math uses top of extraseg - steal from encoder if necessary */
- if(bf_save_len)
- {
- maxstring = (unsigned int)(0x10000l-(bf_save_len+2)*22);
- maxstring = min((unsigned int)MAXSTRING,maxstring);
- }
- else
- maxstring = MAXSTRING;
-
- if(initbatch) /* flush any impending keystrokes */
- while(keypressed())
- getakey();
-
- setup_save_info(&save_info);
-
- #ifndef XFRACT
- bitsperpixel = 0; /* calculate bits / pixel */
- for (i = colors; i >= 2; i /= 2 )
- bitsperpixel++;
-
- startbits = bitsperpixel+1; /* start coding with this many bits */
- if (colors == 2)
- startbits++; /* B&W Klooge */
- #else
- if (colors==2) {
- bitsperpixel = 1;
- startbits = 3;
- } else {
- bitsperpixel = 8;
- startbits = 9;
- }
- #endif
-
- clearcode = 1 << (startbits - 1); /* set clear and end codes */
- endcode = clearcode+1;
-
- outcolor1 = 0; /* use these colors to show progress */
- outcolor2 = 1; /* (this has nothing to do with GIF) */
- if (colors > 2) {
- outcolor1 = 2;
- outcolor2 = 3;
- }
- if (((++numsaves) & 1) == 0) { /* reverse the colors on alt saves */
- i = outcolor1;
- outcolor1 = outcolor2;
- outcolor2 = i;
- }
- outcolor1s = outcolor1;
- outcolor2s = outcolor2;
-
- if (gif87a_flag == 1) {
- if (fwrite("GIF87a",6,1,out) != 1) goto oops; /* old GIF Signature */
- } else {
- if (fwrite("GIF89a",6,1,out) != 1) goto oops; /* new GIF Signature */
- }
-
- width = xdots;
- rowlimit = ydots;
- if (save16bit) {
- /* pot16bit info is stored as:
- file: double width rows, right side of row is low 8 bits
- diskvid: ydots rows of colors followed by ydots rows of low 8 bits
- decoder: returns (row of color info then row of low 8 bits) * ydots
- */
- rowlimit <<= 1;
- width <<= 1;
- }
- if (write2(&width,2,1,out) != 1) goto oops; /* screen descriptor */
- if (write2(&ydots,2,1,out) != 1) goto oops;
- x = (BYTE)(128 + ((6-1)<<4) + (bitsperpixel-1)); /* color resolution == 6 bits worth */
- if (write1(&x,1,1,out) != 1) goto oops;
- if (fputc(0,out) != 0) goto oops; /* background color */
- i = 0;
- /** PB, changed to always store pixel aspect ratio, some utilities
- have been reported to like it **/
- /**
- if ( finalaspectratio < screenaspect-0.01
- || finalaspectratio > screenaspect+0.01) {
- **/
- if (viewwindow /* less than full screen? */
- && (viewxdots == 0 || viewydots == 0)) /* and we picked the dots? */
- i = (int)(((double)sydots / (double)sxdots) * 64.0/screenaspect - 14.5);
- else /* must risk loss of precision if numbers low */
- i = (int)((((double)ydots / (double)xdots) / finalaspectratio) * 64 - 14.5);
- if (i < 1) i = 1;
- if (i > 255) i = 255;
- if (gif87a_flag) i = 0; /* for some decoders which can't handle aspect */
- if (fputc(i,out) != i) goto oops; /* pixel aspect ratio */
-
- #ifndef XFRACT
- if (colors == 256) { /* write out the 256-color palette */
- if (gotrealdac) { /* got a DAC - must be a VGA */
- if (!shftwrite((BYTE *)dacbox,colors)) goto oops;
- #else
- if (colors > 2) {
- if (gotrealdac) { /* got a DAC - must be a VGA */
- if (!shftwrite((BYTE *)dacbox,256)) goto oops;
- #endif
- } else { /* uh oh - better fake it */
- for (i = 0; i < 256; i += 16)
- if (!shftwrite(paletteEGA,16)) goto oops;
- }
- }
- if (colors == 2) { /* write out the B&W palette */
- if (!shftwrite(paletteBW,colors)) goto oops;
- }
- #ifndef XFRACT
- if (colors == 4) { /* write out the CGA palette */
- if (!shftwrite(paletteCGA,colors))goto oops;
- }
- if (colors == 16) { /* Either EGA or VGA */
- if (gotrealdac) {
- if (!shftwrite((BYTE *)dacbox,colors))goto oops;
- }
- else { /* no DAC - must be an EGA */
- if (!shftwrite(paletteEGA,colors))goto oops;
- }
- }
- #endif
-
- if (fwrite(",",1,1,out) != 1) goto oops; /* Image Descriptor */
- i = 0;
- if (write2(&i,2,1,out) != 1) goto oops;
- if (write2(&i,2,1,out) != 1) goto oops;
- if (write2(&width,2,1,out) != 1) goto oops;
- if (write2(&ydots,2,1,out) != 1) goto oops;
- if (write1(&i,1,1,out) != 1) goto oops;
-
- bitsperpixel = (BYTE)(startbits - 1); /* raster data starts here */
- if (write1(&bitsperpixel,1,1,out) != 1) goto oops;
-
- codebits = startbits; /* start encoding */
-
- if (!raster(9999)) goto oops; /* initialize the raster routine */
-
- if (!inittable()) goto oops; /* initialize the LZW tables */
-
- for ( rownum = 0; rownum < ydots; rownum++
- #ifdef WINFRACT
- , UpdateStatusBox(rownum, ydots)
- #endif
- ) { /* scan through the dots */
- for (ydot = rownum; ydot < rowlimit; ydot += ydots) {
- for (xdot = 0; xdot < xdots; xdot++) {
- if (save16bit == 0 || ydot < ydots)
- color = getcolor(xdot,ydot);
- else
- color = readdisk(xdot+sxoffs,ydot+syoffs);
- teststring[0] = (BYTE)++lentest;
- teststring[lentest] = (BYTE)color;
- if (lentest == 1) { /* root entry? */
- lastentry = color;
- continue;
- }
- if (lentest == 2) /* init the hash code */
- hashcode = 301 * (teststring[1]+1);
- hashcode *= (color + lentest); /* update the hash code */
- hashentry = ++hashcode % MAXENTRY;
- for( i = 0; i < MAXENTRY; i++) {
- if (++hashentry >= MAXENTRY) hashentry = 0;
- if (cmpextra(strlocn[hashentry]+sizeof(int),
- (char *)teststring,lentest+1) == 0)
- break;
- if (strlocn[hashentry] == 0) i = MAXENTRY;
- }
- /* found an entry and string length isn't too bad */
- if (strlocn[hashentry] != 0 && lentest < MAXTEST-1-sizeof(int)) {
- fromextra(strlocn[hashentry],(char *)&entrynum,sizeof(int));
- lastentry = entrynum;
- continue;
- }
- if (!raster(lastentry)) goto oops; /* write entry */
- numentries++; /* act like you added one, anyway */
- if (strlocn[hashentry] == 0) { /* add new string, if any */
- entrynum = numentries+endcode;
- strlocn[hashentry] = nextentry;
- toextra(nextentry, (char *)&entrynum,sizeof(int));
- toextra(nextentry+sizeof(int),
- (char *)teststring,lentest+1);
- nextentry += lentest+1+sizeof(int);
- numrealentries++;
- }
- teststring[0] = 1; /* reset current entry */
- teststring[1] = (BYTE)color;
- lentest = 1;
- lastentry = color;
-
- if ((numentries+endcode) == (1<<codebits))
- codebits++; /* use longer encoding */
-
- if ( numentries + endcode > 4093 || /* out of room? */
- numrealentries > (MAXENTRY*2)/3 ||
- nextentry > maxstring-MAXTEST-1-2*sizeof(int)) {
- if (!raster(lastentry)) goto oops; /* flush & restart */
- if (!inittable()) goto oops;
- }
- }
- if (dotmode != 11 /* supress this on disk-video */
- && active_system == 0 /* and in Windows version */
- && ydot == rownum) {
- if ((ydot & 4) == 0) {
- if (++outcolor1 >= colors) outcolor1 = 0;
- if (++outcolor2 >= colors) outcolor2 = 0;
- }
- for (i = 0; 250*i < xdots; i++) { /* display vert status bars */
- /* (this is NOT GIF-related) */
- /* PB Changed following code to xor color, so that
- image can be restored at end and resumed
- putcolor( i,ydot,outcolor1);
- putcolor(xdots-1-i,ydot,outcolor2);
- */
- putcolor(i,ydot,getcolor(i,ydot)^outcolor1);
- putcolor(xdots-1-i,ydot,getcolor(xdots-1-i,ydot)^outcolor2);
- }
- last_colorbar = ydot;
- }
- #ifdef WINFRACT
- keypressed();
- if (OperCancelled)
- #else
- if (keypressed()) /* keyboard hit - bail out */
- #endif
- ydot = rownum = 9999;
- }
- }
-
- if (!raster(lastentry)) goto oops; /* tidy up - dump the last code */
-
- if (!raster(endcode)) goto oops; /* finish the map */
-
- if (fputc(0,out) != 0) goto oops; /* raster data ends here */
-
- if (gif87a_flag == 0) { /* store non-standard fractal info */
- /* loadfile.c has notes about extension block structure */
- if (ydot >= 9999)
- save_info.calc_status = 0; /* partial save is not resumable */
- save_info.tot_extend_len = 0;
- if (resume_info != NULL && save_info.calc_status == 2) {
- /* resume info block, 002 */
- save_info.tot_extend_len += extend_blk_len(resume_len);
- if (!put_extend_blk(2,resume_len,resume_info))goto oops;
- }
- if (save_info.fractal_type == FORMULA || save_info.fractal_type == FFORMULA)
- save_info.tot_extend_len += store_item_name(FormName);
- if (save_info.fractal_type == LSYSTEM)
- save_info.tot_extend_len += store_item_name(LName);
- if (save_info.fractal_type == IFS || save_info.fractal_type == IFS3D)
- save_info.tot_extend_len += store_item_name(IFSName);
- if (display3d <= 0 && rangeslen) {
- /* ranges block, 004 */
- save_info.tot_extend_len += extend_blk_len(rangeslen*2);
- #ifdef XFRACT
- fix_ranges(ranges,rangeslen,0);
- put_extend_blk(4,rangeslen*2,(char far *)ranges);
- fix_ranges(ranges,rangeslen,0);
- #else
- if (!put_extend_blk(4,rangeslen*2,(char far *)ranges))
- goto oops;
- #endif
- }
- /* Extended parameters block 005 */
- if(bf_math)
- {
- save_info.tot_extend_len += extend_blk_len(22*(bflength+2));
- /* note: this assumes variables allocated in order starting with
- bfxmin in init_bf2() in BIGNUM.C */
- if (!put_extend_blk(5,22*(bflength+2),(char far *)bfxmin))
- goto oops;
- }
-
- /* main and last block, 001 */
- save_info.tot_extend_len += extend_blk_len(FRACTAL_INFO_SIZE);
- #ifdef XFRACT
- decode_fractal_info(&save_info,0);
- #endif
- if (!put_extend_blk(1,FRACTAL_INFO_SIZE,(char far *)&save_info)) {
- goto oops;
- }
- }
-
- if (fwrite(";",1,1,out) != 1) goto oops; /* GIF Terminator */
-
- return ((ydot < 9999) ? 0 : 1);
-
- oops:
- {
- fflush(out);
- stopmsg(0,"Error Writing to disk (Disk full?)");
- return 1;
- }
- }
-
- static int _fastcall shftwrite(BYTE *color,int numcolors)
- /* shift IBM colors to GIF */
- {
- BYTE thiscolor;
- int i,j;
- for (i = 0; i < numcolors; i++)
- for (j = 0; j < 3; j++) {
- thiscolor = color[3*i+j];
- thiscolor = (BYTE)(thiscolor << 2);
- thiscolor = (BYTE)(thiscolor + (BYTE)(thiscolor >> 6));
- if (fputc(thiscolor,out) != (int)thiscolor) return(0);
- }
- return(1);
- }
-
- static int inittable() /* routine to init tables */
- {
- int i;
-
- if (!raster(clearcode)) return(0); /* signal that table is initialized */
-
- numentries = 0; /* initialize the table */
- numrealentries = 0;
- nextentry = 1;
- lentest = 0;
- codebits = startbits;
-
- toextra(0,"\0",1); /* clear the hash entries */
- for (i = 0; i < MAXENTRY; i++)
- strlocn[i] = 0;
-
- return(1);
- }
-
- static int _fastcall raster(unsigned int code) /* routine to block and output codes */
- {
- unsigned int icode, i, j;
-
- if (code == 9999) { /* special start-up signal */
- bytecount = 0;
- bitcount = 0;
- for (i = 0; i < 266; i++)
- block[i] = 0;
- return(1);
- }
-
- icode = code << bitcount; /* update the bit string */
- block[bytecount ] |= (icode & 255);
- block[bytecount+1] |= ((icode>>8) & 255);
- icode = (code>>8) << bitcount;
- block[bytecount+2] |= ((icode>>8) & 255);
- bitcount += codebits;
- while (bitcount >= 8) { /* locate next starting point */
- bitcount -= 8;
- bytecount++;
- }
-
- if (bytecount > 250 || code == (unsigned int)endcode) { /* time to write a block */
- if (code == (unsigned int)endcode)
- while (bitcount > 0) { /* if EOF, find the real end */
- bitcount -= 8;
- bytecount++;
- }
- i = bytecount;
- blockcount = (BYTE)i;
- if (write1(&blockcount,1,1,out) != 1) return(0); /* write the block */
- if (fwrite(block,i,1,out) != 1) return(0);
- bytecount = 0; /* now re-start the block */
- for (j = 0; j < 5; j++) /* (may have leftover bits) */
- block[j] = block[j+i];
- for (j = 5; j < 266; j++)
- block[j] = 0;
- }
- return(1);
- }
-
-
- static int _fastcall extend_blk_len(int datalen)
- {
- return(datalen + (datalen+254)/255 + 15);
- /* data + 1.per.block + 14 for id + 1 for null at end */
- }
-
- static int _fastcall put_extend_blk(int block_id,int block_len,char far *block_data)
- {
- int i,j;
- char header[15];
- strcpy(header,"!\377\013fractint");
- sprintf(&header[11],"%03u",block_id);
- if (fwrite(header,14,1,out) != 1) return(0);
- i = (block_len + 254) / 255;
- while (--i >= 0) {
- block_len -= (j = min(block_len,255));
- if (fputc(j,out) != j) return(0);
- while (--j >= 0)
- fputc(*(block_data++),out);
- }
- if (fputc(0,out) != 0) return(0);
- return(1);
- }
-
- static int _fastcall store_item_name(char *nameptr)
- {
- char tmpname[40];
- strcpy(tmpname,nameptr);
- /* formula/lsys/ifs info block, 003 */
- put_extend_blk(3,40,tmpname);
- return(extend_blk_len(40));
- }
-
- static void _fastcall setup_save_info(struct fractal_info far *save_info)
- {
- int i;
- if(fractype != FORMULA && fractype != FFORMULA)
- maxfn = 0;
- /* set save parameters in save structure */
- far_strcpy(save_info->info_id, INFO_ID);
- save_info->version = 10; /* file version, independant of system */
-
- if(maxit <= 32767)
- save_info->iterationsold = (short)maxit;
- else
- save_info->iterationsold = 32767;
-
- save_info->fractal_type = (short)fractype;
- save_info->xmin = xxmin;
- save_info->xmax = xxmax;
- save_info->ymin = yymin;
- save_info->ymax = yymax;
- save_info->creal = param[0];
- save_info->cimag = param[1];
- save_info->videomodeax = (short)videoentry.videomodeax;
- save_info->videomodebx = (short)videoentry.videomodebx;
- save_info->videomodecx = (short)videoentry.videomodecx;
- save_info->videomodedx = (short)videoentry.videomodedx;
- save_info->dotmode = (short)(videoentry.dotmode % 100);
- save_info->xdots = (short)videoentry.xdots;
- save_info->ydots = (short)videoentry.ydots;
- save_info->colors = (short)videoentry.colors;
- save_info->parm3 = 0; /* pre version==7 fields */
- save_info->parm4 = 0;
- save_info->dparm3 = param[2];
- save_info->dparm4 = param[3];
- save_info->dparm5 = param[4];
- save_info->dparm6 = param[5];
- save_info->dparm7 = param[6];
- save_info->dparm8 = param[7];
- save_info->dparm9 = param[8];
- save_info->dparm10 = param[9];
- save_info->fillcolor = (short)fillcolor;
- save_info->potential[0] = (float)potparam[0];
- save_info->potential[1] = (float)potparam[1];
- save_info->potential[2] = (float)potparam[2];
- save_info->rflag = (short)rflag;
- save_info->rseed = (short)rseed;
- save_info->inside = (short)inside;
- save_info->logmap = (short)LogFlag;
- save_info->invert[0] = (float)inversion[0];
- save_info->invert[1] = (float)inversion[1];
- save_info->invert[2] = (float)inversion[2];
- save_info->decomp[0] = (short)decomp[0];
- save_info->biomorph = (short)usr_biomorph;
- save_info->symmetry = (short)forcesymmetry;
- for (i = 0; i < 16; i++)
- save_info->init3d[i] = (short)init3d[i];
- save_info->previewfactor = (short)previewfactor;
- save_info->xtrans = (short)xtrans;
- save_info->ytrans = (short)ytrans;
- save_info->red_crop_left = (short)red_crop_left;
- save_info->red_crop_right = (short)red_crop_right;
- save_info->blue_crop_left = (short)blue_crop_left;
- save_info->blue_crop_right = (short)blue_crop_right;
- save_info->red_bright = (short)red_bright;
- save_info->blue_bright = (short)blue_bright;
- save_info->xadjust = (short)xadjust;
- save_info->yadjust = (short)yadjust;
- save_info->eyeseparation = (short)eyeseparation;
- save_info->glassestype = (short)glassestype;
- save_info->outside = (short)outside;
- save_info->x3rd = xx3rd;
- save_info->y3rd = yy3rd;
- save_info->calc_status = (short)calc_status;
- save_info->stdcalcmode = (char)((three_pass&&stdcalcmode=='3')?127:stdcalcmode);
- save_info->distest = (short)distest;
- save_info->floatflag = floatflag;
-
- if (bailout >= 4 && bailout <= 32000)
- save_info->bailoutold = (short)bailout;
- else
- save_info->bailoutold = 0;
-
- save_info->calctime = calctime;
- save_info->trigndx[0] = trigndx[0];
- save_info->trigndx[1] = trigndx[1];
- save_info->trigndx[2] = trigndx[2];
- save_info->trigndx[3] = trigndx[3];
- save_info->finattract = (short)finattract;
- save_info->initorbit[0] = initorbit.x;
- save_info->initorbit[1] = initorbit.y;
- save_info->useinitorbit = useinitorbit;
- save_info->periodicity = (short)periodicitycheck;
- save_info->pot16bit = (short)disk16bit;
- save_info->faspectratio = finalaspectratio;
- save_info->system = (short)save_system;
-
- /* the following should match code in MISCOVL.C */
- if (fractype == LYAPUNOV ||
- fractype == FROTH || fractype == FROTHFP ||
- fix_bof() || fix_period_bof() || use_old_distest || decomp[0] == 2)
- save_info->release = (short)min(save_release,release);
- else
- save_info->release = (short)release;
-
- save_info->flag3d = (short)display3d;
- save_info->ambient = (short)Ambient;
- save_info->randomize = (short)RANDOMIZE;
- save_info->haze = (short)haze;
- save_info->transparent[0] = (short)transparent[0];
- save_info->transparent[1] = (short)transparent[1];
- save_info->rotate_lo = (short)rotate_lo;
- save_info->rotate_hi = (short)rotate_hi;
- save_info->distestwidth = (short)distestwidth;
- save_info->mxmaxfp = mxmaxfp;
- save_info->mxminfp = mxminfp;
- save_info->mymaxfp = mymaxfp;
- save_info->myminfp = myminfp;
- save_info->zdots = (short)zdots;
- save_info->originfp = originfp;
- save_info->depthfp = depthfp;
- save_info->heightfp = heightfp;
- save_info->widthfp = widthfp;
- save_info->distfp = distfp;
- save_info->eyesfp = eyesfp;
- save_info->orbittype = (short)neworbittype;
- save_info->juli3Dmode = (short)juli3Dmode;
- save_info->maxfn = maxfn;
- save_info->inversejulia = (short)((major_method << 8) + minor_method); /* MVS */
- save_info->bailout = bailout;
- save_info->bailoutest = (short)bailoutest;
- save_info->iterations = maxit;
- save_info->bflength = (short)bnlength;
- save_info->bf_math = (short)bf_math;
- save_info->old_demm_colors = (short)old_demm_colors;
- for (i = 0; i < sizeof(save_info->future)/sizeof(short); i++)
- save_info->future[i] = 0;
- }
-