1 /*
2         Various routines that prompt for things.
3 */
4 
5 #include <string.h>
6 #include <ctype.h>
7 #ifndef XFRACT
8 #include <io.h>
9 #elif !defined(__386BSD__)
10 #include <sys/types.h>
11 #include <sys/stat.h>
12 
13 #ifdef DIRENT
14 #include <dirent.h>
15 #elif !defined(__SVR4) && !defined(__DragonFly__)
16 #include <sys/dir.h>
17 #else
18 #include <dirent.h>
19 #ifndef DIRENT
20 #define DIRENT
21 #endif
22 #endif
23 
24 #endif
25 #ifdef __TURBOC__
26 #include <alloc.h>
27 #elif defined(__APPLE__)
28 #include <malloc/malloc.h>
29 #elif !defined(BIG_ANSI_C)
30 #include <malloc.h>
31 #endif
32 
33 #ifdef XFRACT
34 #include <fcntl.h>
35 #endif
36 
37 #ifdef __hpux
38 #include <sys/param.h>
39 #endif
40 
41 #ifdef __SVR4
42 #include <sys/param.h>
43 #endif
44 
45   /* see Fractint.c for a description of the "include"  hierarchy */
46 #include "port.h"
47 #include "prototyp.h"
48 #include "fractype.h"
49 #include "helpdefs.h"
50 
51 /* Routines in this module      */
52 
53 static  int check_f6_key(int curkey,int choice);
54 static  int expand_dirname(char *dirname,char *drive);
55 static  int filename_speedstr(int, int, int, char *, int);
56 static  int get_screen_corners(void);
57 
58 /* speed key state values */
59 #define MATCHING         0      /* string matches list - speed key mode */
60 #define TEMPLATE        -2      /* wild cards present - buiding template */
61 #define SEARCHPATH      -3      /* no match - building path search name */
62 
63 #define   FILEATTR       0x37      /* File attributes; select all but volume labels */
64 #define   HIDDEN         2
65 #define   SYSTEM         4
66 #define   SUBDIR         16
67 #define   MAXNUMFILES    2977L
68 
69 struct DIR_SEARCH DTA;          /* Allocate DTA and define structure */
70 
71 #define GETFORMULA 0
72 #define GETLSYS    1
73 #define GETIFS     2
74 #define GETPARM    3
75 
76 char commandmask[MAX_NAME] = {"*.par"};
77 
78 /* --------------------------------------------------------------------- */
79 /*
80         get_toggles() is called from FRACTINT.C whenever the 'x' key
81         is pressed.  This routine prompts for several options,
82         sets the appropriate variables, and returns the following code
83         to the calling routine:
84 
85         -1  routine was ESCAPEd - no need to re-generate the image.
86          0  nothing changed, or minor variable such as "overwrite=".
87             No need to re-generate the image.
88          1  major variable changed (such as "inside=").  Re-generate
89             the image.
90 
91         Finally, remember to insert variables in the list *and* check
92         for them in the same order!!!
93 */
94 #define LOADCHOICES(X)     {\
95    static FCODE tmp[] = { X };\
96    far_strcpy(ptr,(char far *)tmp);\
97    choices[++k]= ptr;\
98    ptr += sizeof(tmp);\
99    }
get_toggles()100 int get_toggles()
101 {
102    static FCODE o_hdg[]={"Basic Options\n(not all combinations make sense)"};
103    char hdg[sizeof(o_hdg)];
104    char far *choices[20];
105    char far *ptr;
106    int oldhelpmode;
107    char prevsavename[FILE_MAX_DIR+1];
108    char *savenameptr;
109    struct fullscreenvalues uvalues[25];
110    int i, j, k;
111    char old_usr_stdcalcmode;
112    long old_maxit,old_logflag;
113    int old_inside,old_outside,old_soundflag;
114    int old_biomorph,old_decomp;
115    int old_fillcolor;
116    int old_stoppass;
117    double old_closeprox;
118    char *calcmodes[] ={"1","2","3","g","g1","g2","g3","g4","g5","g6","b","s","t","d","o"};
119    char *soundmodes[5]={s_off,s_beep,s_x,s_y,s_z};
120    char *insidemodes[]={"numb",s_maxiter,s_zmag,s_bof60,s_bof61,s_epscross,
121                          s_startrail,s_period,s_atan,s_fmod};
122    char *outsidemodes[]={"numb",s_iter,s_real,s_imag,s_mult,s_sum,s_atan,
123                          s_fmod,s_tdis};
124 
125    far_strcpy(hdg,o_hdg);
126    ptr = (char far *)MK_FP(extraseg,0);
127 
128    k = -1;
129 
130    LOADCHOICES("Passes (1,2,3, g[uess], b[ound], t[ess], d[iffu], o[rbit])");
131    uvalues[k].type = 'l';
132    uvalues[k].uval.ch.vlen = 3;
133    uvalues[k].uval.ch.llen = sizeof(calcmodes)/sizeof(*calcmodes);
134    uvalues[k].uval.ch.list = calcmodes;
135    uvalues[k].uval.ch.val = (usr_stdcalcmode == '1') ? 0
136                           : (usr_stdcalcmode == '2') ? 1
137                           : (usr_stdcalcmode == '3') ? 2
138                           : (usr_stdcalcmode == 'g' && stoppass == 0) ? 3
139                           : (usr_stdcalcmode == 'g' && stoppass == 1) ? 4
140                           : (usr_stdcalcmode == 'g' && stoppass == 2) ? 5
141                           : (usr_stdcalcmode == 'g' && stoppass == 3) ? 6
142                           : (usr_stdcalcmode == 'g' && stoppass == 4) ? 7
143                           : (usr_stdcalcmode == 'g' && stoppass == 5) ? 8
144                           : (usr_stdcalcmode == 'g' && stoppass == 6) ? 9
145                           : (usr_stdcalcmode == 'b') ? 10
146 			  : (usr_stdcalcmode == 's') ? 11
147 			  : (usr_stdcalcmode == 't') ? 12
148 			  : (usr_stdcalcmode == 'd') ? 13
149                           :        /* "o"rbits */      14;
150    old_usr_stdcalcmode = usr_stdcalcmode;
151    old_stoppass = stoppass;
152 #ifndef XFRACT
153    LOADCHOICES("Floating Point Algorithm");
154    uvalues[k].type = 'y';
155    uvalues[k].uval.ch.val = usr_floatflag;
156 #endif
157    LOADCHOICES("Maximum Iterations (2 to 2,147,483,647)");
158    uvalues[k].type = 'L';
159    uvalues[k].uval.Lval = old_maxit = maxit;
160 
161    LOADCHOICES("Inside Color (0-# of colors, if Inside=numb)");
162    uvalues[k].type = 'i';
163    if (inside >= 0)
164       uvalues[k].uval.ival = inside;
165    else
166       uvalues[k].uval.ival = 0;
167 
168    LOADCHOICES("Inside (numb,maxit,zmag,bof60,bof61,epscr,star,per,atan,fmod)");
169    uvalues[k].type = 'l';
170    uvalues[k].uval.ch.vlen = 12;
171    uvalues[k].uval.ch.llen = sizeof(insidemodes)/sizeof(*insidemodes);
172    uvalues[k].uval.ch.list = insidemodes;
173    if(inside >= 0)  /* numb */
174       uvalues[k].uval.ch.val = 0;
175    else if(inside == -1)  /* maxiter */
176       uvalues[k].uval.ch.val = 1;
177    else if(inside == ZMAG)
178       uvalues[k].uval.ch.val = 2;
179    else if(inside == BOF60)
180       uvalues[k].uval.ch.val = 3;
181    else if(inside == BOF61)
182       uvalues[k].uval.ch.val = 4;
183    else if(inside == EPSCROSS)
184       uvalues[k].uval.ch.val = 5;
185    else if(inside == STARTRAIL)
186       uvalues[k].uval.ch.val = 6;
187    else if(inside == PERIOD)
188       uvalues[k].uval.ch.val = 7;
189    else if(inside == ATANI)
190       uvalues[k].uval.ch.val = 8;
191    else if(inside == FMODI)
192       uvalues[k].uval.ch.val = 9;
193    old_inside = inside;
194 
195    LOADCHOICES("Outside Color (0-# of colors, if Outside=numb)");
196    uvalues[k].type = 'i';
197    if (outside >= 0)
198       uvalues[k].uval.ival = outside;
199    else
200       uvalues[k].uval.ival = 0;
201 
202    LOADCHOICES("Outside (numb,iter,real,imag,mult,summ,atan,fmod,tdis)");
203    uvalues[k].type = 'l';
204    uvalues[k].uval.ch.vlen = 4;
205    uvalues[k].uval.ch.llen = sizeof(outsidemodes)/sizeof(*outsidemodes);
206    uvalues[k].uval.ch.list = outsidemodes;
207    if(outside >= 0)  /* numb */
208       uvalues[k].uval.ch.val = 0;
209    else
210       uvalues[k].uval.ch.val = -outside;
211    old_outside = outside;
212 
213    LOADCHOICES("Savename (.GIF implied)");
214    uvalues[k].type = 's';
215    strcpy(prevsavename,savename);
216    savenameptr = strrchr(savename, SLASHC);
217    if(savenameptr == NULL)
218       savenameptr = savename;
219    else
220       savenameptr++; /* point past slash */
221    strcpy(uvalues[k].uval.sval,savenameptr);
222 
223    LOADCHOICES("File Overwrite ('overwrite=')");
224    uvalues[k].type = 'y';
225    uvalues[k].uval.ch.val = overwrite;
226 
227    LOADCHOICES("Sound (off, beep, x, y, z)");
228    uvalues[k].type = 'l';
229    uvalues[k].uval.ch.vlen = 4;
230    uvalues[k].uval.ch.llen = 5;
231    uvalues[k].uval.ch.list = soundmodes;
232    uvalues[k].uval.ch.val = (old_soundflag = soundflag)&7;
233 
234    if (rangeslen == 0) {
235       LOADCHOICES("Log Palette (0=no,1=yes,-1=old,+n=cmprsd,-n=sqrt, 2=auto)");
236       uvalues[k].type = 'L';
237       }
238    else {
239       LOADCHOICES("Log Palette (n/a, ranges= parameter is in effect)");
240       uvalues[k].type = '*';
241       }
242    uvalues[k].uval.Lval = old_logflag = LogFlag;
243 
244    LOADCHOICES("Biomorph Color (-1 means OFF)");
245    uvalues[k].type = 'i';
246    uvalues[k].uval.ival = old_biomorph = usr_biomorph;
247 
248    LOADCHOICES("Decomp Option (2,4,8,..,256, 0=OFF)");
249    uvalues[k].type = 'i';
250    uvalues[k].uval.ival = old_decomp = decomp[0];
251 
252    LOADCHOICES("Fill Color (normal,#) (works with passes=t, b and d)");
253    uvalues[k].type = 's';
254    if(fillcolor < 0)
255       strcpy(uvalues[k].uval.sval,s_normal);
256    else
257       sprintf(uvalues[k].uval.sval,"%d",fillcolor);
258    old_fillcolor = fillcolor;
259 
260    LOADCHOICES("Proximity value for inside=epscross and fmod");
261    uvalues[k].type = 'f'; /* should be 'd', but prompts get messed up JCO */
262    uvalues[k].uval.dval = old_closeprox = closeprox;
263 
264    oldhelpmode = helpmode;
265    helpmode = HELPXOPTS;
266    i = fullscreen_prompt(hdg,k+1,choices,uvalues,0,NULL);
267    helpmode = oldhelpmode;
268    if (i < 0) {
269       return(-1);
270       }
271 
272    /* now check out the results (*hopefully* in the same order <grin>) */
273    k = -1;
274    j = 0;   /* return code */
275 
276    usr_stdcalcmode = calcmodes[uvalues[++k].uval.ch.val][0];
277    stoppass = (int)calcmodes[uvalues[k].uval.ch.val][1] - (int)'0';
278 
279    if(stoppass < 0 || stoppass > 6 || usr_stdcalcmode != 'g')
280       stoppass = 0;
281 
282    if(usr_stdcalcmode == 'o' && fractype == LYAPUNOV) /* Oops,lyapunov type */
283                                        /* doesn't use 'new' & breaks orbits */
284       usr_stdcalcmode = old_usr_stdcalcmode;
285 
286    if (old_usr_stdcalcmode != usr_stdcalcmode) j++;
287    if (old_stoppass != stoppass) j++;
288 #ifndef XFRACT
289    if (uvalues[++k].uval.ch.val != usr_floatflag) {
290       usr_floatflag = (char)uvalues[k].uval.ch.val;
291       j++;
292       }
293    if (usr_stdcalcmode == 'o') { /* Need to force floating point for passes=o */
294       usr_floatflag = 1;
295       j++;
296       }
297 #endif
298    ++k;
299    maxit = uvalues[k].uval.Lval;
300    if (maxit < 0) maxit = old_maxit;
301    if (maxit < 2) maxit = 2;
302 
303    if (maxit != old_maxit) j++;
304 
305    inside = uvalues[++k].uval.ival;
306    if (inside < 0) inside = -inside;
307    if (inside >= colors) inside = (inside % colors) + (inside / colors);
308 
309    { int tmp;
310    tmp = uvalues[++k].uval.ch.val;
311    if (tmp > 0)
312       switch (tmp)
313       {
314       case 1:
315          inside = -1;  /* maxiter */
316          break;
317       case 2:
318          inside = ZMAG;
319          break;
320       case 3:
321          inside = BOF60;
322          break;
323       case 4:
324          inside = BOF61;
325          break;
326       case 5:
327          inside = EPSCROSS;
328          break;
329       case 6:
330          inside = STARTRAIL;
331          break;
332       case 7:
333          inside = PERIOD;
334          break;
335       case 8:
336          inside = ATANI;
337          break;
338       case 9:
339          inside = FMODI;
340          break;
341       }
342    }
343    if (inside != old_inside) j++;
344 
345    outside = uvalues[++k].uval.ival;
346    if (outside < 0) outside = -outside;
347    if (outside >= colors) outside = (outside % colors) + (outside / colors);
348 
349    { int tmp;
350    tmp = uvalues[++k].uval.ch.val;
351    if (tmp > 0)
352       outside = -tmp;
353    }
354    if (outside != old_outside) j++;
355 
356    strcpy(savenameptr,uvalues[++k].uval.sval);
357    if (strcmp(savename,prevsavename))
358       resave_flag = started_resaves = 0; /* forget pending increment */
359    overwrite = (char)uvalues[++k].uval.ch.val;
360 
361    soundflag = ((soundflag >> 3) << 3) | (uvalues[++k].uval.ch.val);
362    if (soundflag != old_soundflag && ((soundflag&7) > 1 || (old_soundflag&7) > 1))
363       j++;
364 
365    LogFlag = uvalues[++k].uval.Lval;
366    if (LogFlag != old_logflag) {
367       j++;
368       Log_Auto_Calc = 0;  /* turn it off, use the supplied value */
369    }
370 
371    usr_biomorph = uvalues[++k].uval.ival;
372    if (usr_biomorph >= colors) usr_biomorph = (usr_biomorph % colors) + (usr_biomorph / colors);
373    if (usr_biomorph != old_biomorph) j++;
374 
375    decomp[0] = uvalues[++k].uval.ival;
376    if (decomp[0] != old_decomp) j++;
377 
378    if(strncmp(strlwr(uvalues[++k].uval.sval),s_normal,4)==0)
379       fillcolor = -1;
380    else
381       fillcolor = atoi(uvalues[k].uval.sval);
382    if (fillcolor < 0) fillcolor = -1;
383    if (fillcolor >= colors) fillcolor = (fillcolor % colors) + (fillcolor / colors);
384    if (fillcolor != old_fillcolor) j++;
385 
386    ++k;
387    closeprox = uvalues[k].uval.dval;
388    if (closeprox != old_closeprox) j++;
389 
390 /* if (j >= 1) j = 1; need to know how many prompts changed for quick_calc JCO 6/23/2001 */
391 
392    return(j);
393 }
394 
395 /*
396         get_toggles2() is similar to get_toggles, invoked by 'y' key
397 */
398 
get_toggles2()399 int get_toggles2()
400 {
401    static FCODE o_hdg[]={"Extended Options\n\
402 (not all combinations make sense)"};
403    char hdg[sizeof(o_hdg)];
404    char far *ptr;
405    char far *choices[18];
406    int oldhelpmode;
407 
408    struct fullscreenvalues uvalues[23];
409    int i, j, k;
410 
411    int old_rotate_lo,old_rotate_hi;
412    int old_distestwidth;
413    double old_potparam[3],old_inversion[3];
414    long old_usr_distest;
415 
416    far_strcpy(hdg,o_hdg);
417    ptr = (char far *)MK_FP(extraseg,0);
418 
419    /* fill up the choices (and previous values) arrays */
420    k = -1;
421 
422    LOADCHOICES("Look for finite attractor (0=no,>0=yes,<0=phase)");
423    uvalues[k].type = 'i';
424    uvalues[k].uval.ch.val = finattract;
425 
426    LOADCHOICES("Potential Max Color (0 means off)");
427    uvalues[k].type = 'i';
428    uvalues[k].uval.ival = (int)(old_potparam[0] = potparam[0]);
429 
430    LOADCHOICES("          Slope");
431    uvalues[k].type = 'd';
432    uvalues[k].uval.dval = old_potparam[1] = potparam[1];
433 
434    LOADCHOICES("          Bailout");
435    uvalues[k].type = 'i';
436    uvalues[k].uval.ival = (int)(old_potparam[2] = potparam[2]);
437 
438    LOADCHOICES("          16 bit values");
439    uvalues[k].type = 'y';
440    uvalues[k].uval.ch.val = pot16bit;
441 
442    LOADCHOICES("Distance Estimator (0=off, <0=edge, >0=on):");
443    uvalues[k].type = 'L';
444    uvalues[k].uval.Lval = old_usr_distest = usr_distest;
445 
446    LOADCHOICES("          width factor:");
447    uvalues[k].type = 'i';
448    uvalues[k].uval.ival = old_distestwidth = distestwidth;
449 
450    LOADCHOICES("Inversion radius or \"auto\" (0 means off)");
451    LOADCHOICES("          center X coordinate or \"auto\"");
452    LOADCHOICES("          center Y coordinate or \"auto\"");
453    k = k - 3;
454    for (i= 0; i < 3; i++) {
455       uvalues[++k].type = 's';
456       if ((old_inversion[i] = inversion[i]) == AUTOINVERT)
457          sprintf(uvalues[k].uval.sval,"auto");
458       else
459          sprintf(uvalues[k].uval.sval,"%-1.15lg",inversion[i]);
460       }
461    LOADCHOICES("  (use fixed radius & center when zooming)");
462    uvalues[k].type = '*';
463 
464    LOADCHOICES("Color cycling from color (0 ... 254)");
465    uvalues[k].type = 'i';
466    uvalues[k].uval.ival = old_rotate_lo = rotate_lo;
467 
468    LOADCHOICES("              to   color (1 ... 255)");
469    uvalues[k].type = 'i';
470    uvalues[k].uval.ival = old_rotate_hi = rotate_hi;
471 
472    oldhelpmode = helpmode;
473    helpmode = HELPYOPTS;
474    i = fullscreen_prompt(hdg,k+1,choices,uvalues,0,NULL);
475    helpmode = oldhelpmode;
476    if (i < 0) {
477       return(-1);
478       }
479 
480    /* now check out the results (*hopefully* in the same order <grin>) */
481    k = -1;
482    j = 0;   /* return code */
483 
484    if (uvalues[++k].uval.ch.val != finattract) {
485       finattract = uvalues[k].uval.ch.val;
486       j = 1;
487       }
488 
489    potparam[0] = uvalues[++k].uval.ival;
490    if (potparam[0] != old_potparam[0]) j = 1;
491 
492    potparam[1] = uvalues[++k].uval.dval;
493    if (potparam[0] != 0.0 && potparam[1] != old_potparam[1]) j = 1;
494 
495    potparam[2] = uvalues[++k].uval.ival;
496    if (potparam[0] != 0.0 && potparam[2] != old_potparam[2]) j = 1;
497 
498    if (uvalues[++k].uval.ch.val != pot16bit) {
499       pot16bit = uvalues[k].uval.ch.val;
500       if (pot16bit) { /* turned it on */
501          if (potparam[0] != 0.0) j = 1;
502          }
503       else /* turned it off */
504          if (dotmode != 11) /* ditch the disk video */
505             enddisk();
506          else /* keep disk video, but ditch the fraction part at end */
507             disk16bit = 0;
508       }
509 
510    ++k;
511 /* usr_distest = (uvalues[k].uval.ival > 32000) ? 32000 : uvalues[k].uval.ival; */
512    usr_distest = uvalues[k].uval.Lval;
513    if (usr_distest != old_usr_distest) j = 1;
514    ++k;
515    distestwidth = uvalues[k].uval.ival;
516    if (usr_distest && distestwidth != old_distestwidth) j = 1;
517 
518    for (i = 0; i < 3; i++) {
519       if (uvalues[++k].uval.sval[0] == 'a' || uvalues[k].uval.sval[0] == 'A')
520          inversion[i] = AUTOINVERT;
521       else
522          inversion[i] = atof(uvalues[k].uval.sval);
523       if (old_inversion[i] != inversion[i]
524         && (i == 0 || inversion[0] != 0.0))
525          j = 1;
526       }
527    invert = (inversion[0] == 0.0) ? 0 : 3;
528    ++k;
529 
530    rotate_lo = uvalues[++k].uval.ival;
531    rotate_hi = uvalues[++k].uval.ival;
532    if (rotate_lo < 0 || rotate_hi > 255 || rotate_lo > rotate_hi) {
533       rotate_lo = old_rotate_lo;
534       rotate_hi = old_rotate_hi;
535       }
536 
537    return(j);
538 }
539 
540 
541 /*
542      passes_options invoked by <p> key
543 */
544 
passes_options(void)545 int passes_options(void)
546 {
547    static FCODE o_hdg[]={"Passes Options\n\
548 (not all combinations make sense)"};
549    static FCODE pressf2[] = {"\n(Press "FK_F2" for corner parameters)"};
550    static FCODE pressf6[] = {"\n(Press "FK_F6" for calculation parameters)"};
551    char hdg[sizeof(o_hdg)+sizeof(pressf2)+sizeof(pressf6)];
552    char far *ptr;
553    char far *choices[20];
554    int oldhelpmode;
555    char *passcalcmodes[] ={"rect","line"};
556 /*   char *passcalcmodes[] ={"rect","line","func"}; */
557 
558    struct fullscreenvalues uvalues[25];
559    int i, j, k;
560    int ret;
561 
562    int old_periodicity, old_orbit_delay, old_orbit_interval;
563    int old_keep_scrn_coords;
564    char old_drawmode;
565 
566    far_strcpy(hdg,o_hdg);
567    far_strcat(hdg,pressf2);
568    far_strcat(hdg,pressf6);
569    ptr = (char far *)MK_FP(extraseg,0);
570    ret = 0;
571 
572 pass_option_restart:
573    /* fill up the choices (and previous values) arrays */
574    k = -1;
575 
576    LOADCHOICES("Periodicity (0=off, <0=show, >0=on, -255..+255)");
577    uvalues[k].type = 'i';
578    uvalues[k].uval.ival = old_periodicity = usr_periodicitycheck;
579 
580    LOADCHOICES("Orbit delay (0 = none)");
581    uvalues[k].type = 'i';
582    uvalues[k].uval.ival = old_orbit_delay = orbit_delay;
583 
584    LOADCHOICES("Orbit interval (1 ... 255)");
585    uvalues[k].type = 'i';
586    uvalues[k].uval.ival = old_orbit_interval = (int)orbit_interval;
587 
588    LOADCHOICES("Maintain screen coordinates");
589    uvalues[k].type = 'y';
590    uvalues[k].uval.ch.val = old_keep_scrn_coords = keep_scrn_coords;
591 
592    LOADCHOICES("Orbit pass shape (rect,line)");
593 /*   LOADCHOICES("Orbit pass shape (rect,line,func)"); */
594    uvalues[k].type = 'l';
595    uvalues[k].uval.ch.vlen = 5;
596    uvalues[k].uval.ch.llen = sizeof(passcalcmodes)/sizeof(*passcalcmodes);
597    uvalues[k].uval.ch.list = passcalcmodes;
598    uvalues[k].uval.ch.val = (drawmode == 'r') ? 0
599                           : (drawmode == 'l') ? 1
600 			  :   /* function */    2;
601    old_drawmode = drawmode;
602 
603    oldhelpmode = helpmode;
604    helpmode = HELPPOPTS;
605    i = fullscreen_prompt(hdg,k+1,choices,uvalues,0x44,NULL);
606    helpmode = oldhelpmode;
607    if (i < 0) {
608       return(-1);
609       }
610 
611    /* now check out the results (*hopefully* in the same order <grin>) */
612    k = -1;
613    j = 0;   /* return code */
614 
615    usr_periodicitycheck = uvalues[++k].uval.ival;
616    if (usr_periodicitycheck > 255) usr_periodicitycheck = 255;
617    if (usr_periodicitycheck < -255) usr_periodicitycheck = -255;
618    if (usr_periodicitycheck != old_periodicity) j = 1;
619 
620 
621    orbit_delay = uvalues[++k].uval.ival;
622    if (orbit_delay != old_orbit_delay) j = 1;
623 
624 
625    orbit_interval = uvalues[++k].uval.ival;
626    if (orbit_interval > 255) orbit_interval = 255;
627    if (orbit_interval < 1) orbit_interval = 1;
628    if (orbit_interval != old_orbit_interval) j = 1;
629 
630    keep_scrn_coords = uvalues[++k].uval.ch.val;
631    if (keep_scrn_coords != old_keep_scrn_coords) j = 1;
632    if (keep_scrn_coords == 0) set_orbit_corners = 0;
633 
634    { int tmp;
635    tmp = uvalues[++k].uval.ch.val;
636       switch (tmp)
637       {
638       default:
639       case 0:
640          drawmode = 'r';
641          break;
642       case 1:
643          drawmode = 'l';
644          break;
645       case 2:
646          drawmode = 'f';
647          break;
648       }
649    }
650    if (drawmode != old_drawmode) j = 1;
651 
652    if (i == F2) {
653       if (get_screen_corners() > 0) {
654          ret = 1;
655       }
656       if (j) ret = 1;
657       goto pass_option_restart;
658    }
659 
660    if (i == F6) {
661       if (get_corners() > 0) {
662          ret = 1;
663       }
664       if (j) ret = 1;
665       goto pass_option_restart;
666    }
667 
668    return(j + ret);
669 }
670 
671 
672 /* for videomodes added new options "virtual x/y" that change "sx/ydots" */
673 /* for diskmode changed "viewx/ydots" to "virtual x/y" that do as above  */
674 /* (since for diskmode they were updated by x/ydots that should be the   */
675 /* same as sx/ydots for that mode)                                       */
676 /* videotable and videoentry are now updated even for non-disk modes     */
677 
678 /* --------------------------------------------------------------------- */
679 /*
680     get_view_params() is called from FRACTINT.C whenever the 'v' key
681     is pressed.  Return codes are:
682         -1  routine was ESCAPEd - no need to re-generate the image.
683          0  minor variable changed.  No need to re-generate the image.
684          1  View changed.  Re-generate the image.
685 */
686 
get_view_params()687 int get_view_params()
688 {
689    static FCODE o_hdg[]={"View Window Options"};
690    char hdg[sizeof(o_hdg)];
691    char far *choices[16];
692    char far *ptr;
693 
694    int oldhelpmode;
695    struct fullscreenvalues uvalues[25];
696    int i, k;
697    float old_viewreduction,old_aspectratio;
698    int old_viewwindow,old_viewxdots,old_viewydots,old_sxdots,old_sydots;
699    unsigned long estm_xmax=32767,estm_ymax=32767;
700 #ifndef XFRACT
701    unsigned long vidmem = (unsigned long)video_vram << 16;
702    int truebytes = videoentry.dotmode/1000;
703 
704    if (dotmode == 28)          /* setvideo might have changed mode 27 to 28 */
705       dotmode = videoentry.dotmode%100;
706 #endif
707 
708    far_strcpy(hdg,o_hdg);
709    ptr = (char far *)MK_FP(extraseg,0);
710 
711 /*
712    Because the scrolling (and virtual screen width) must be
713    aligned to 8 bytes, that gives:
714 
715    8 pixels for 8 bit (truebytes == 0; ++truebytes == 1;)
716    4 pixels for 15 bit (truebytes == 1; ++truebytes == 2;)
717    4 pixels for 16 bit (truebytes == 2;)
718    8 pixels for 24 bit (truebytes == 3;)
719    2 pixels for 32 bit (truebytes == 4;)
720 
721    so for odd truebytes (8 and 24 bit) it does &= ..FFF8 (&= -8)
722    if truebytes==2 (15 and 16 bit) it does &= ..FFFC (&= -4)
723    if truebytes==4 (32 bit) it does &= ..FFFE (&= -2)
724 */
725 
726 #ifndef XFRACT
727    if (dotmode == 28 && virtual) {
728       /* virtual screen limits estimation */
729       if (truebytes < 2)
730          ++truebytes;
731       vidmem /= truebytes;
732       if (vesa_yres)
733          estm_xmax = min(vidmem/vesa_yres,estm_xmax);
734       else
735          estm_xmax = 0;
736       if (vesa_xres)
737          estm_ymax = min(vidmem/vesa_xres,estm_ymax);
738       else
739          estm_ymax = 0;
740       estm_xmax &= truebytes&1 ? -8 : truebytes - 6;
741    }
742 #endif
743 
744    old_viewwindow    = viewwindow;
745    old_viewreduction = viewreduction;
746    old_aspectratio   = finalaspectratio;
747    old_viewxdots     = viewxdots;
748    old_viewydots     = viewydots;
749    old_sxdots        = sxdots;
750    old_sydots        = sydots;
751 
752 get_view_restart:
753    /* fill up the previous values arrays */
754    k = -1;
755 
756    if (dotmode != 11) {
757       LOADCHOICES("Preview display? (no for full screen)");
758       uvalues[k].type = 'y';
759       uvalues[k].uval.ch.val = viewwindow;
760 
761       LOADCHOICES("Auto window size reduction factor");
762       uvalues[k].type = 'f';
763       uvalues[k].uval.dval = viewreduction;
764 
765       LOADCHOICES("Final media overall aspect ratio, y/x");
766       uvalues[k].type = 'f';
767       uvalues[k].uval.dval = finalaspectratio;
768 
769       LOADCHOICES("Crop starting coordinates to new aspect ratio?");
770       uvalues[k].type = 'y';
771       uvalues[k].uval.ch.val = viewcrop;
772 
773       LOADCHOICES("Explicit size x pixels (0 for auto size)");
774       uvalues[k].type = 'i';
775       uvalues[k].uval.ival = viewxdots;
776 
777       LOADCHOICES("              y pixels (0 to base on aspect ratio)");
778       uvalues[k].type = 'i';
779       uvalues[k].uval.ival = viewydots;
780    }
781 
782    LOADCHOICES("");
783    uvalues[k].type = '*';
784 
785 #ifndef XFRACT
786    if (virtual && dotmode == 28 && chkd_vvs && !video_scroll) {
787       LOADCHOICES("Your graphics card does NOT support virtual screens.");
788       uvalues[k].type = '*';
789    }
790 #endif
791 
792    if (dotmode == 11 || (virtual && dotmode == 28)) {
793       LOADCHOICES("Virtual screen total x pixels");
794       uvalues[k].type = 'i';
795       uvalues[k].uval.ival = sxdots;
796 
797       if (dotmode == 11) {
798          LOADCHOICES("                     y pixels");
799       }
800       else {
801          LOADCHOICES("                     y pixels (0: by aspect ratio)");
802       }
803       uvalues[k].type = 'i';
804       uvalues[k].uval.ival = sydots;
805    }
806 
807 #ifndef XFRACT
808    if (virtual && dotmode == 28) {
809       char dim[50];
810       static FCODE xmsg[] = {"Video memory limits: (for y = "};
811       static FCODE ymsg[] = {"                     (for x = "};
812       static FCODE midxmsg[] = {") x <= "};
813       static FCODE midymsg[] = {") y <= "};
814       char *scrolltypes[] ={"fixed","relaxed"};
815 
816       LOADCHOICES("Keep aspect? (cuts both x & y when either too big)");
817       uvalues[k].type = 'y';
818       uvalues[k].uval.ch.val = video_cutboth;
819 
820       LOADCHOICES("Zoombox scrolling (f[ixed], r[elaxed])");
821       uvalues[k].type = 'l';
822       uvalues[k].uval.ch.vlen = 7;
823       uvalues[k].uval.ch.llen = sizeof(scrolltypes)/sizeof(*scrolltypes);
824       uvalues[k].uval.ch.list = scrolltypes;
825       uvalues[k].uval.ch.val = zscroll;
826 
827       LOADCHOICES("");
828       uvalues[k].type = '*';
829 
830       sprintf(dim,"%Fs%4u%Fs%lu",(char far *)xmsg,vesa_yres,(char far *)midxmsg,estm_xmax);
831       far_strcpy(ptr,(char far *)dim);
832       choices[++k]= ptr;
833       ptr += sizeof(dim);
834       uvalues[k].type = '*';
835 
836       sprintf(dim,"%Fs%4u%Fs%lu",(char far *)ymsg,vesa_xres,(char far *)midymsg,estm_ymax);
837       far_strcpy(ptr,(char far *)dim);
838       choices[++k]= ptr;
839       ptr += sizeof(dim);
840       uvalues[k].type = '*';
841 
842       LOADCHOICES("");
843       uvalues[k].type = '*';
844    }
845 #endif
846 
847    if (dotmode != 11) {
848       LOADCHOICES("Press "FK_F4" to reset view parameters to defaults.");
849       uvalues[k].type = '*';
850    }
851 
852    oldhelpmode = helpmode;     /* this prevents HELP from activating */
853    helpmode = HELPVIEW;
854    i = fullscreen_prompt(hdg,k+1,choices,uvalues,16,NULL);
855    helpmode = oldhelpmode;     /* re-enable HELP */
856    if (i < 0) {
857       return(-1);
858       }
859 
860    if (i == F4 && dotmode != 11) {
861       viewwindow = viewxdots = viewydots = 0;
862       viewreduction = (float)4.2;
863       viewcrop = 1;
864       finalaspectratio = screenaspect;
865       if (dotmode == 28) {
866          sxdots = vesa_xres ? vesa_xres : old_sxdots;
867          sydots = vesa_yres ? vesa_yres : old_sydots;
868          video_cutboth = 1;
869          zscroll = 1;
870       }
871       goto get_view_restart;
872       }
873 
874    /* now check out the results (*hopefully* in the same order <grin>) */
875    k = -1;
876 
877    if (dotmode != 11) {
878       viewwindow = uvalues[++k].uval.ch.val;
879 
880       viewreduction = (float)uvalues[++k].uval.dval;
881 
882       finalaspectratio = (float)uvalues[++k].uval.dval;
883 
884       viewcrop = uvalues[++k].uval.ch.val;
885 
886       viewxdots = uvalues[++k].uval.ival;
887       viewydots = uvalues[++k].uval.ival;
888    }
889 
890    ++k;
891 
892    if (virtual && dotmode == 28 && chkd_vvs && !video_scroll)
893       ++k;  /* add 1 if not supported line is inserted */
894 
895    if (dotmode == 11 || (virtual && dotmode == 28)) {
896       sxdots = uvalues[++k].uval.ival;
897       sydots = uvalues[++k].uval.ival;
898 #ifndef XFRACT
899       video_cutboth = uvalues[++k].uval.ch.val;
900       zscroll = uvalues[++k].uval.ch.val;
901 #endif
902 
903       if ((unsigned long)sxdots > estm_xmax)
904          sxdots = (int)estm_xmax;
905 #ifndef XFRACT
906       sxdots &= truebytes&1 ? -8 : truebytes - 6;
907 #endif
908       if (sxdots < 2)
909          sxdots = 2;
910       if (sydots == 0 && dotmode == 28) { /* auto by aspect ratio request */
911          if (finalaspectratio == 0.0) {
912             if (viewwindow && viewxdots != 0 && viewydots != 0)
913                finalaspectratio = (float)viewydots/viewxdots;
914             else
915                finalaspectratio = old_aspectratio;
916          }
917          sydots = (int)(finalaspectratio * sxdots + 0.5);
918       }
919       if ((unsigned long)sydots > estm_ymax)
920          sydots = (int)estm_ymax;
921       if (sydots < 2)
922          sydots = 2;
923    }
924 
925 #ifndef XFRACT
926    if (virtual && dotmode == 28) {
927 
928       /* virtual screen smaller than physical screen, use view window */
929       if (sxdots < vesa_xres && sydots < vesa_yres) {
930          viewwindow = 1;
931          viewxdots = sxdots;
932          viewydots = sydots;
933          sxdots    = vesa_xres;
934          sydots    = vesa_yres;
935       } else {
936          viewwindow = 0; /* make sure it is off */
937          viewxdots = 0;
938          viewydots = 0;
939       }
940 
941       /* if virtual screen is too large */
942       if( (unsigned long)((sxdots < vesa_xres) ? vesa_xres : sxdots)
943             * ((sydots < vesa_yres) ? vesa_yres : sydots) > vidmem) {
944         /* and we have to keep ratio */
945         if (video_cutboth) {
946            double tmp,virtaspect = (double)sydots / sxdots;
947 
948            /* we need vidmem >= x * y == x * x * virtaspect */
949            tmp = sqrt(vidmem / virtaspect);
950            sxdots = (tmp > (double)estm_xmax) ? (int)estm_xmax : (int)tmp;
951            sxdots &= truebytes&1 ? -8 : truebytes - 6;
952            if (sxdots < 2)
953                sxdots = 2;
954            tmp = sxdots * virtaspect;
955            sydots = (tmp > (double)estm_ymax) ? (int)estm_ymax : (int)tmp;
956            /* if sydots < 2 here, then sxdots > estm_xmax */
957         }
958         else { /* cut only the y value */
959            sydots = (int)((double)vidmem / ((sxdots < vesa_xres) ? vesa_xres : sxdots));
960         }
961       }
962    }
963 #endif
964 
965    if (dotmode == 11 || (virtual && dotmode == 28)) {
966       videoentry.xdots = sxdots;
967       videoentry.ydots = sydots;
968       far_memcpy((char far *)&videotable[adapter],(char far *)&videoentry,
969                     sizeof(videoentry));
970       if (finalaspectratio == 0.0)
971          finalaspectratio = (float)sydots/sxdots;
972    }
973 
974    if (viewxdots != 0 && viewydots != 0 && viewwindow && finalaspectratio == 0.0)
975       finalaspectratio = (float)viewydots/viewxdots;
976    else if (finalaspectratio == 0.0 && (viewxdots == 0 || viewydots == 0))
977       finalaspectratio = old_aspectratio;
978 
979    if (finalaspectratio != old_aspectratio && viewcrop)
980       aspectratio_crop(old_aspectratio,finalaspectratio);
981 
982    i = 0;
983    if (viewwindow != old_viewwindow
984       || sxdots != old_sxdots || sydots != old_sydots
985       || (viewwindow
986          && (  viewreduction != old_viewreduction
987             || finalaspectratio != old_aspectratio
988             || viewxdots != old_viewxdots
989             || (viewydots != old_viewydots && viewxdots) ) ) )
990       i = 1;
991 
992    return(i);
993 }
994 
995 /*
996     get_cmd_string() is called from FRACTINT.C whenever the 'g' key
997     is pressed.  Return codes are:
998         -1  routine was ESCAPEd - no need to re-generate the image.
999          0  parameter changed, no need to regenerate
1000         >0  parameter changed, regenerate
1001 */
1002 
get_cmd_string()1003 int get_cmd_string()
1004 {
1005    static FCODE o_msg[] = {"Enter command string to use."};
1006    char msg[sizeof(o_msg)];
1007    int oldhelpmode;
1008    int i;
1009    static char cmdbuf[61];
1010 
1011    far_strcpy(msg,o_msg);
1012    oldhelpmode = helpmode;
1013    helpmode = HELPCOMMANDS;
1014    i = field_prompt(0,msg,NULL,cmdbuf,60,NULL);
1015    helpmode = oldhelpmode;
1016    if (i >= 0 && cmdbuf[0] != 0) {
1017        i = cmdarg(cmdbuf, 2);
1018        if(debugflag == 98)
1019        {
1020           backwards_v18();
1021           backwards_v19();
1022           backwards_v20();
1023        }
1024    }
1025 
1026    return(i);
1027 }
1028 
1029 
1030 /* --------------------------------------------------------------------- */
1031 
1032 int Distribution = 30, Offset = 0, Slope = 25;
1033 long con;
1034 
1035 
1036        double starfield_values[4] = {
1037         30.0,100.0,5.0,0.0
1038         };
1039 
1040 char GreyFile[] = "altern.map";
1041 
starfield(void)1042 int starfield(void)
1043 {
1044    int c;
1045    busy = 1;
1046    if (starfield_values[0] <   1.0) starfield_values[0] =   1.0;
1047    if (starfield_values[0] > 100.0) starfield_values[0] = 100.0;
1048    if (starfield_values[1] <   1.0) starfield_values[1] =   1.0;
1049    if (starfield_values[1] > 100.0) starfield_values[1] = 100.0;
1050    if (starfield_values[2] <   1.0) starfield_values[2] =   1.0;
1051    if (starfield_values[2] > 100.0) starfield_values[2] = 100.0;
1052 
1053    Distribution = (int)(starfield_values[0]);
1054    con  = (long)(((starfield_values[1]) / 100.0) * (1L << 16));
1055    Slope = (int)(starfield_values[2]);
1056 
1057    if (ValidateLuts(GreyFile) != 0) {
1058       static FCODE msg[]={"Unable to load ALTERN.MAP"};
1059       stopmsg(0,msg);
1060       busy = 0;
1061       return(-1);
1062       }
1063    spindac(0,1);                 /* load it, but don't spin */
1064    for(row = 0; row < ydots; row++) {
1065       for(col = 0; col < xdots; col++) {
1066          if(keypressed()) {
1067             buzzer(1);
1068             busy = 0;
1069             return(1);
1070             }
1071          c = getcolor(col, row);
1072          if(c == inside)
1073             c = colors-1;
1074          putcolor(col, row, GausianNumber(c, colors));
1075       }
1076    }
1077    buzzer(0);
1078    busy = 0;
1079    return(0);
1080 }
1081 
get_starfield_params(void)1082 int get_starfield_params(void) {
1083    static FCODE o_hdg[]={"Starfield Parameters"};
1084    static FCODE o_sf1[] = {"Star Density in Pixels per Star"};
1085    static FCODE o_sf2[] = {"Percent Clumpiness"};
1086    static FCODE o_sf3[] = {"Ratio of Dim stars to Bright"};
1087    char hdg[sizeof(o_hdg)];
1088    char sf1[sizeof(o_sf1)];
1089    char sf2[sizeof(o_sf2)];
1090    char sf3[sizeof(o_sf3)];
1091    struct fullscreenvalues uvalues[3];
1092    int oldhelpmode;
1093    int i;
1094    char far *starfield_prompts[3];
1095    far_strcpy(hdg,o_hdg);
1096    far_strcpy(sf1,o_sf1);
1097    far_strcpy(sf2,o_sf2);
1098    far_strcpy(sf3,o_sf3);
1099    starfield_prompts[0] = sf1;
1100    starfield_prompts[1] = sf2;
1101    starfield_prompts[2] = sf3;
1102 
1103    if(colors < 255) {
1104       static FCODE msg[]={"starfield requires 256 color mode"};
1105       stopmsg(0,msg);
1106       return(-1);
1107    }
1108    for (i = 0; i < 3; i++) {
1109       uvalues[i].uval.dval = starfield_values[i];
1110       uvalues[i].type = 'f';
1111    }
1112    stackscreen();
1113    oldhelpmode = helpmode;
1114    helpmode = HELPSTARFLD;
1115    i = fullscreen_prompt(hdg,3,starfield_prompts,uvalues,0,NULL);
1116    helpmode = oldhelpmode;
1117    unstackscreen();
1118    if (i < 0) {
1119       return(-1);
1120       }
1121    for (i = 0; i < 3; i++)
1122       starfield_values[i] = uvalues[i].uval.dval;
1123 
1124    return(0);
1125 }
1126 
1127 static char *masks[] = {"*.pot","*.gif"};
1128 
get_rds_params(void)1129 int get_rds_params(void) {
1130    static FCODE o_hdg[] =  {"Random Dot Stereogram Parameters"};
1131    static FCODE o_rds0[] = {"Depth Effect (negative reverses front and back)"};
1132    static FCODE o_rds1[] = {"Image width in inches"};
1133    static FCODE o_rds2[] = {"Use grayscale value for depth? (if \"no\" uses color number)"};
1134    static FCODE o_rds3[] = {"Calibration bars"};
1135    static FCODE o_rds4[] = {"Use image map? (if \"no\" uses random dots)"};
1136    static FCODE o_rds5[] = {"  If yes, use current image map name? (see below)"};
1137 
1138    char hdg[sizeof(o_hdg)];
1139    char rds0[sizeof(o_rds0)];
1140    char rds1[sizeof(o_rds1)];
1141    char rds2[sizeof(o_rds2)];
1142    char rds3[sizeof(o_rds3)];
1143    char rds4[sizeof(o_rds4)];
1144    char rds5[sizeof(o_rds5)];
1145    char rds6[60];
1146    char *stereobars[] = {"none", "middle", "top"};
1147    struct fullscreenvalues uvalues[7];
1148    char far *rds_prompts[7];
1149    int oldhelpmode;
1150    int i,k;
1151    int ret;
1152    static char reuse = 0;
1153    stackscreen();
1154    for(;;)
1155    {
1156       ret = 0;
1157       /* copy to make safe from overlay change */
1158       far_strcpy(hdg,o_hdg);
1159       far_strcpy(rds0,o_rds0);
1160       far_strcpy(rds1,o_rds1);
1161       far_strcpy(rds2,o_rds2);
1162       far_strcpy(rds3,o_rds3);
1163       far_strcpy(rds4,o_rds4);
1164       far_strcpy(rds5,o_rds5);
1165       rds_prompts[0] = rds0;
1166       rds_prompts[1] = rds1;
1167       rds_prompts[2] = rds2;
1168       rds_prompts[3] = rds3;
1169       rds_prompts[4] = rds4;
1170       rds_prompts[5] = rds5;
1171       rds_prompts[6] = rds6;
1172 
1173       k=0;
1174       uvalues[k].uval.ival = AutoStereo_depth;
1175       uvalues[k++].type = 'i';
1176 
1177       uvalues[k].uval.dval = AutoStereo_width;
1178       uvalues[k++].type = 'f';
1179 
1180       uvalues[k].uval.ch.val = grayflag;
1181       uvalues[k++].type = 'y';
1182 
1183       uvalues[k].type = 'l';
1184       uvalues[k].uval.ch.list = stereobars;
1185       uvalues[k].uval.ch.vlen = 6;
1186       uvalues[k].uval.ch.llen = 3;
1187       uvalues[k++].uval.ch.val  = calibrate;
1188 
1189       uvalues[k].uval.ch.val = image_map;
1190       uvalues[k++].type = 'y';
1191 
1192 
1193       if(*stereomapname != 0 && image_map)
1194       {
1195          char *p;
1196          uvalues[k].uval.ch.val = reuse;
1197          uvalues[k++].type = 'y';
1198 
1199          uvalues[k++].type = '*';
1200          for(i=0;i<sizeof(rds6);i++)
1201             rds6[i] = ' ';
1202          if((p = strrchr(stereomapname,SLASHC))==NULL ||
1203                  strlen(stereomapname) < sizeof(rds6)-2)
1204             p = strlwr(stereomapname);
1205          else
1206             p++;
1207          /* center file name */
1208          rds6[(sizeof(rds6)-strlen(p)+2)/2] = 0;
1209          strcat(rds6,"[");
1210          strcat(rds6,p);
1211          strcat(rds6,"]");
1212       }
1213       else
1214          *stereomapname = 0;
1215       oldhelpmode = helpmode;
1216       helpmode = HELPRDS;
1217       i = fullscreen_prompt(hdg,k,rds_prompts,uvalues,0,NULL);
1218       helpmode = oldhelpmode;
1219       if (i < 0) {
1220          ret = -1;
1221          break;
1222          }
1223       else
1224       {
1225          k=0;
1226          AutoStereo_depth = uvalues[k++].uval.ival;
1227          AutoStereo_width = uvalues[k++].uval.dval;
1228          grayflag         = (char)uvalues[k++].uval.ch.val;
1229          calibrate        = (char)uvalues[k++].uval.ch.val;
1230          image_map        = (char)uvalues[k++].uval.ch.val;
1231          if(*stereomapname && image_map)
1232             reuse         = (char)uvalues[k++].uval.ch.val;
1233          else
1234             reuse = 0;
1235          if(image_map && !reuse)
1236          {
1237             static FCODE tmp[] = {"Select an Imagemap File"};
1238             char tmp1[sizeof(tmp)];
1239             /* tmp1 only a convenient buffer */
1240             far_strcpy(tmp1,tmp);
1241             if(getafilename(tmp1,masks[1],stereomapname))
1242                continue;
1243          }
1244       }
1245       break;
1246    }
1247    unstackscreen();
1248    return(ret);
1249 }
1250 
get_a_number(double * x,double * y)1251 int get_a_number(double *x, double *y)
1252 {
1253    static FCODE o_hdg[]={"Set Cursor Coordinates"};
1254    char hdg[sizeof(o_hdg)];
1255    char far *ptr;
1256    char far *choices[2];
1257 
1258    struct fullscreenvalues uvalues[2];
1259    int i, k;
1260 
1261    stackscreen();
1262    far_strcpy(hdg,o_hdg);
1263    ptr = (char far *)MK_FP(extraseg,0);
1264 
1265    /* fill up the previous values arrays */
1266    k = -1;
1267 
1268    LOADCHOICES("X coordinate at cursor");
1269    uvalues[k].type = 'd';
1270    uvalues[k].uval.dval = *x;
1271 
1272    LOADCHOICES("Y coordinate at cursor");
1273    uvalues[k].type = 'd';
1274    uvalues[k].uval.dval = *y;
1275 
1276    i = fullscreen_prompt(hdg,k+1,choices,uvalues,25,NULL);
1277    if (i < 0) {
1278       unstackscreen();
1279       return(-1);
1280       }
1281 
1282    /* now check out the results (*hopefully* in the same order <grin>) */
1283    k = -1;
1284 
1285    *x = uvalues[++k].uval.dval;
1286    *y = uvalues[++k].uval.dval;
1287 
1288    unstackscreen();
1289    return(i);
1290 }
1291 
1292 /* --------------------------------------------------------------------- */
1293 
get_commands()1294 int get_commands()              /* execute commands from file */
1295 {
1296    int ret;
1297    FILE *parmfile;
1298    long point;
1299    int oldhelpmode;
1300    ret = 0;
1301    oldhelpmode = helpmode;
1302    helpmode = HELPPARMFILE;
1303    if ((point = get_file_entry(GETPARM,"Parameter Set",
1304                                commandmask,CommandFile,CommandName)) >= 0
1305      && (parmfile = fopen(CommandFile,"rb")) != NULL) {
1306       fseek(parmfile,point,SEEK_SET);
1307       ret = load_commands(parmfile);
1308       }
1309    helpmode = oldhelpmode;
1310    return(ret);
1311 }
1312 
1313 /* --------------------------------------------------------------------- */
1314 
goodbye()1315 void goodbye()                  /* we done.  Bail out */
1316 {
1317    char goodbyemessage[40];
1318    int ret;
1319    static FCODE gbm[]={"   Thank You for using "FRACTINT};
1320 #ifndef XFRACT
1321    union REGS r;
1322 #endif
1323    if (resume_info != 0)
1324       end_resume();
1325    if (evolve_handle != 0)
1326       MemoryRelease(evolve_handle);
1327    if (gene_handle != 0)
1328       MemoryRelease(gene_handle);
1329    if (imgboxhandle != 0 || prmboxhandle != 0)
1330       ReleaseParamBox();
1331    if (history != 0)
1332       MemoryRelease(history);
1333    if (oldhistory_handle != 0)
1334       MemoryRelease(oldhistory_handle);
1335    enddisk();
1336    discardgraphics();
1337    ExitCheck();
1338    far_strcpy(goodbyemessage, gbm);
1339 #ifdef WINFRACT
1340    return;
1341 #endif
1342    if(*s_makepar != 0)
1343       setvideotext();
1344 #ifdef XFRACT
1345    UnixDone();
1346    printf("\n\n\n%s\n",goodbyemessage); /* printf takes far pointer */
1347 #else
1348    if(*s_makepar != 0)
1349    {
1350       r.h.al = (char)((mode7text == 0) ? exitmode : 7);
1351       r.h.ah = 0;
1352       int86(0x10, &r, &r);
1353       printf("\n\n\n%s\n",goodbyemessage); /* printf takes far pointer */
1354    }
1355 #endif
1356    if(*s_makepar != 0)
1357    {
1358       movecursor(6,0);
1359       discardgraphics(); /* if any emm/xmm tied up there, release it */
1360    }
1361    stopslideshow();
1362    end_help();
1363    ret = 0;
1364    if (initbatch == 3) /* exit with error code for batch file */
1365      ret = 2;
1366    else if (initbatch == 4)
1367      ret = 1;
1368    exit(ret);
1369 }
1370 
1371 
1372 /* --------------------------------------------------------------------- */
1373 
1374 #ifdef XFRACT
1375 static char searchdir[FILE_MAX_DIR];
1376 static char searchname[FILE_MAX_PATH];
1377 static char searchext[FILE_MAX_EXT];
1378 static DIR *currdir = NULL;
1379 #endif
fr_findfirst(char * path)1380 int  fr_findfirst(char *path)       /* Find 1st file (or subdir) meeting path/filespec */
1381 {
1382 #ifndef XFRACT
1383      union REGS regs;
1384      regs.h.ah = 0x1A;             /* Set DTA to filedata */
1385      regs.x.dx = (unsigned)&DTA;
1386      intdos(&regs, &regs);
1387      regs.h.ah = 0x4E;             /* Find 1st file meeting path */
1388      regs.x.dx = (unsigned)path;
1389      regs.x.cx = FILEATTR;
1390      intdos(&regs, &regs);
1391      return(regs.x.ax);            /* Return error code */
1392 #else
1393      if (currdir != NULL) {
1394          closedir(currdir);
1395          currdir = NULL;
1396      }
1397      splitpath(path,NULL,searchdir,searchname,searchext);
1398      if (searchdir[0]=='\0') {
1399          currdir = opendir(".");
1400      } else {
1401          currdir = opendir(searchdir);
1402      }
1403      if (currdir==NULL) {
1404          return -1;
1405      } else {
1406          return fr_findnext();
1407      }
1408 #endif
1409 }
1410 
fr_findnext()1411 int  fr_findnext()              /* Find next file (or subdir) meeting above path/filespec */
1412 {
1413 #ifndef XFRACT
1414      union REGS regs;
1415      regs.h.ah = 0x4F;             /* Find next file meeting path */
1416      regs.x.dx = (unsigned)&DTA;
1417      intdos(&regs, &regs);
1418      return(regs.x.ax);
1419 #else
1420 #ifdef DIRENT
1421      struct dirent *dirEntry;
1422 #else
1423      struct direct *dirEntry;
1424 #endif
1425      struct stat sbuf;
1426      char thisname[FILE_MAX_PATH];
1427      char tmpname[FILE_MAX_PATH];
1428      char thisext[FILE_MAX_EXT];
1429      for(;;) {
1430          dirEntry = readdir(currdir);
1431          if (dirEntry == NULL) {
1432              closedir(currdir);
1433              currdir = NULL;
1434              return -1;
1435          } else if (dirEntry->d_ino != 0) {
1436              splitpath(dirEntry->d_name,NULL,NULL,thisname,thisext);
1437              strncpy(DTA.filename,dirEntry->d_name,MAX_NAME);
1438              DTA.filename[MAX_NAME-1]='\0';
1439              strcpy(tmpname,searchdir);
1440              strcat(tmpname,dirEntry->d_name);
1441              stat(tmpname,&sbuf);
1442              DTA.size = sbuf.st_size;
1443              if ((sbuf.st_mode&S_IFMT)==S_IFREG &&
1444                  (searchname[0]=='*' || strcmp(searchname,thisname)==0) &&
1445                  (searchext[0]=='*' || strcmp(searchext,thisext)==0)) {
1446                  DTA.attribute = 0;
1447                  return 0;
1448              }
1449 	     else if (((sbuf.st_mode&S_IFMT)==S_IFDIR) &&
1450                  ((searchname[0]=='*' || searchext[0]=='*') ||
1451                  (strcmp(searchname,thisname)==0))) {
1452                  DTA.attribute = SUBDIR;
1453                  return 0;
1454              }
1455          }
1456      }
1457 #endif
1458 }
1459 
1460 
1461 #if 0
1462 void heap_sort(void far *ra1, int n, unsigned sz, int (__cdecl *fct)(VOIDFARPTR arg1,VOIDFARPTR arg2))
1463 {
1464    int ll,j,ir,i;
1465    void far *rra;
1466    char far *ra;
1467    ra = (char far *)ra1;
1468    ra -= sz;
1469    ll=(n>>1)+1;
1470    ir=n;
1471 
1472    for(;;)
1473    {
1474       if(ll>1)
1475          rra = *((char far *far *)(ra+(--ll)*sz));
1476       else
1477       {
1478          rra = *((char far * far *)(ra+ir*sz));
1479          *((char far * far *)(ra+ir*sz))=*((char far * far *)(ra+sz));
1480          if(--ir == 1)
1481          {
1482             *((char far * far *)(ra+sz))=rra;
1483             return;
1484          }
1485       }
1486       i = ll;
1487       j = ll <<1;
1488       while (j <= ir)
1489       {
1490          if(j<ir && (fct(ra+j*sz,ra+(j+1)*sz) < 0))
1491             ++j;
1492          if(fct(&rra,ra+j*sz) < 0)
1493          {
1494             *((char far * far *)(ra+i*sz)) = *((char far * far *)(ra+j*sz));
1495             j += (i=j);
1496          }
1497          else
1498             j=ir+1;
1499       }
1500       *((char far * far *)(ra+i*sz))=rra;
1501    }
1502 }
1503 #endif
1504 
lccompare(VOIDFARPTR arg1,VOIDFARPTR arg2)1505 int lccompare(VOIDFARPTR arg1, VOIDFARPTR arg2) /* for sort */
1506 {
1507    return(strncasecmp(*((char far * far *)arg1),*((char far *far *)arg2),40));
1508 }
1509 
1510 static int speedstate;
getafilename(char * hdg,char * template,char * flname)1511 int getafilename(char *hdg,char *template,char *flname)
1512 {
1513    int rds;  /* if getting an RDS image map */
1514    static FCODE o_instr[]={"Press "FK_F6" for default directory, "FK_F4" to toggle sort "};
1515    char far *instr;
1516    int masklen;
1517    char filename[FILE_MAX_PATH]; /* 13 is big enough for Fractint, but not Xfractint */
1518    char speedstr[81];
1519    char tmpmask[FILE_MAX_PATH];   /* used to locate next file in list */
1520    char old_flname[FILE_MAX_PATH];
1521    static int numtemplates = 1;
1522    int i,j;
1523    int out;
1524    int retried;
1525    static struct CHOICE
1526    {
1527       char name[MAX_NAME];
1528       char type;
1529    }
1530    far *far*choices;
1531    int far *attributes;
1532    int filecount;   /* how many files */
1533    int dircount;    /* how many directories */
1534    int notroot;     /* not the root directory */
1535 
1536    char drive[FILE_MAX_DRIVE];
1537    char dir[FILE_MAX_DIR];
1538    char fname[FILE_MAX_FNAME];
1539    char ext[FILE_MAX_EXT];
1540    static int dosort = 1;
1541    int options = 8;
1542 
1543    rds = (stereomapname == flname)?1:0;
1544 
1545    /* steal existing array for "choices" */
1546    choices = (struct CHOICE far *far*)MK_FP(extraseg,0);
1547    choices[0] = (struct CHOICE far *)(choices + MAXNUMFILES+1);
1548    attributes = (int far *)(choices[0] + MAXNUMFILES+1);
1549    instr = (char far *)(attributes + MAXNUMFILES +1);
1550    attributes[0] = 1;
1551    for(i=1;i<MAXNUMFILES+1;i++)
1552    {
1553       choices[i] = choices[i-1] + 1;
1554       attributes[i] = 1;
1555    }
1556    /* save filename */
1557    strcpy(old_flname,flname);
1558 restart:  /* return here if template or directory changes */
1559 
1560    tmpmask[0] = 0;
1561    if(flname[0] == 0)
1562       strcpy(flname,DOTSLASH);
1563    splitpath(flname ,drive,dir,fname,ext);
1564    makepath(filename,""   ,"" ,fname,ext);
1565    retried = 0;
1566 retry_dir:
1567    if (dir[0] == 0)
1568       strcpy(dir,".");
1569    expand_dirname(dir,drive);
1570    makepath(tmpmask,drive,dir,"","");
1571    fix_dirname(tmpmask);
1572    if (retried == 0 && strcmp(dir,SLASH) && strcmp(dir,DOTSLASH))
1573    {
1574       tmpmask[(j = strlen(tmpmask) - 1)] = 0; /* strip trailing \ */
1575       if (strchr(tmpmask,'*') || strchr(tmpmask,'?')
1576         || fr_findfirst(tmpmask) != 0
1577         || (DTA.attribute & SUBDIR) == 0)
1578       {
1579          strcpy(dir,DOTSLASH);
1580          ++retried;
1581          goto retry_dir;
1582       }
1583       tmpmask[j] = SLASHC;
1584    }
1585    if(template[0])
1586    {
1587       numtemplates = 1;
1588       splitpath(template,NULL,NULL,fname,ext);
1589    }
1590    else
1591       numtemplates = sizeof(masks)/sizeof(masks[0]);
1592    filecount = -1;
1593    dircount  = 0;
1594    notroot   = 0;
1595    j = 0;
1596    masklen = strlen(tmpmask);
1597    strcat(tmpmask,"*.*");
1598    out = fr_findfirst(tmpmask);
1599    while(out == 0 && filecount < MAXNUMFILES)
1600    {
1601       if((DTA.attribute & SUBDIR) && strcmp(DTA.filename,"."))
1602       {
1603 #ifndef XFRACT
1604          strlwr(DTA.filename);
1605 #endif
1606          if(strcmp(DTA.filename,".."))
1607             strcat(DTA.filename,SLASH);
1608          far_strncpy(choices[++filecount]->name,DTA.filename,MAX_NAME);
1609          choices[filecount]->name[MAX_NAME-1] = '\0';
1610          choices[filecount]->type = 1;
1611          dircount++;
1612          if(strcmp(DTA.filename,"..")==0)
1613             notroot = 1;
1614       }
1615       out = fr_findnext();
1616    }
1617    tmpmask[masklen] = 0;
1618    if(template[0])
1619       makepath(tmpmask,drive,dir,fname,ext);
1620    do
1621    {
1622       if(numtemplates > 1)
1623          strcpy(&(tmpmask[masklen]),masks[j]);
1624       out = fr_findfirst(tmpmask);
1625       while(out == 0 && filecount < MAXNUMFILES)
1626       {
1627          if(!(DTA.attribute & SUBDIR))
1628          {
1629             if(rds)
1630             {
1631                sprintf(speedstr,"%s",DTA.filename);
1632                putstringcenter(2,0,80,C_GENERAL_INPUT,speedstr);
1633 
1634                splitpath(DTA.filename,NULL,NULL,fname,ext);
1635                /* just using speedstr as a handy buffer */
1636                makepath(speedstr,drive,dir,fname,ext);
1637 #ifndef XFRACT
1638                strlwr(DTA.filename);
1639 #endif
1640                far_strncpy(choices[++filecount]->name,DTA.filename,MAX_NAME);
1641                choices[filecount]->type = 0;
1642             }
1643             else
1644             {
1645 #ifndef XFRACT
1646                strlwr(DTA.filename);
1647 #endif
1648                far_strncpy(choices[++filecount]->name,DTA.filename,MAX_NAME);
1649                choices[filecount]->type = 0;
1650             }
1651          }
1652          out = fr_findnext();
1653       }
1654    }
1655    while (++j < numtemplates);
1656    if (++filecount == 0)
1657    {
1658       far_strcpy(choices[filecount]->name,"*nofiles*");
1659       choices[filecount]->type = 0;
1660       ++filecount;
1661    }
1662 
1663    far_strcpy(instr,o_instr);
1664    if(dosort)
1665    {
1666       far_strcat(instr,"off");
1667       shell_sort((void far *far*)choices,filecount,sizeof(char far *),lccompare); /* sort file list */
1668    }
1669    else
1670       far_strcat(instr,"on");
1671    if(notroot == 0 && dir[0] && dir[0] != SLASHC) /* must be in root directory */
1672    {
1673       splitpath(tmpmask,drive,dir,fname,ext);
1674       strcpy(dir,SLASH);
1675       makepath(tmpmask,drive,dir,fname,ext);
1676    }
1677    if(numtemplates > 1)
1678    {
1679       strcat(tmpmask," ");
1680       strcat(tmpmask,masks[0]);
1681    }
1682    strcpy(temp1,hdg);
1683    strcat(temp1,"\nTemplate: ");
1684    strcat(temp1,tmpmask);
1685    strcpy(speedstr,filename);
1686    if (speedstr[0] == 0)
1687    {
1688       for (i=0; i<filecount; i++) /* find first file */
1689          if (choices[i]->type == 0)
1690             break;
1691       if (i >= filecount)
1692          i = 0;
1693    }
1694    if(dosort)
1695       options = 8;
1696    else
1697       options = 8+32;
1698    i = fullscreen_choice(options,temp1,NULL,instr,filecount,(char far *far*)choices,
1699           attributes,5,99,MAX_NAME-1,i,NULL,speedstr,filename_speedstr,check_f6_key);
1700    if (i==-F4)
1701    {
1702       dosort = 1 - dosort;
1703       goto restart;
1704    }
1705    if (i==-F6)
1706    {
1707       static int lastdir=0;
1708       if (lastdir==0)
1709       {
1710          strcpy(dir,fract_dir1);
1711       }
1712       else
1713       {
1714          strcpy(dir,fract_dir2);
1715       }
1716       fix_dirname(dir);
1717       makepath(flname,drive,dir,"","");
1718       lastdir = 1-lastdir;
1719       goto restart;
1720    }
1721    if (i < 0)
1722    {
1723       /* restore filename */
1724       strcpy(flname,old_flname);
1725       return(-1);
1726    }
1727    if(speedstr[0] == 0 || speedstate == MATCHING)
1728    {
1729       if(choices[i]->type)
1730       {
1731          if(far_strcmp(choices[i]->name,"..") == 0) /* go up a directory */
1732          {
1733             if(strcmp(dir,DOTSLASH) == 0)
1734                strcpy(dir,DOTDOTSLASH);
1735             else
1736             {
1737                char *s;
1738                if((s = strrchr(dir,SLASHC)) != NULL) /* trailing slash */
1739                {
1740                   *s = 0;
1741                   if((s = strrchr(dir,SLASHC)) != NULL)
1742                      *(s+1) = 0;
1743                }
1744             }
1745          }
1746          else  /* go down a directory */
1747             far_strcat(dir,choices[i]->name);
1748          fix_dirname(dir);
1749          makepath(flname,drive,dir,"","");
1750          goto restart;
1751       }
1752       splitpath(choices[i]->name,NULL,NULL,fname,ext);
1753       makepath(flname,drive,dir,fname,ext);
1754    }
1755    else
1756    {
1757       if (speedstate == SEARCHPATH
1758         && strchr(speedstr,'*') == 0 && strchr(speedstr,'?') == 0
1759         && ((fr_findfirst(speedstr) == 0
1760         && (DTA.attribute & SUBDIR))|| strcmp(speedstr,SLASH)==0)) /* it is a directory */
1761          speedstate = TEMPLATE;
1762 
1763       if(speedstate == TEMPLATE)
1764       {
1765          /* extract from tempstr the pathname and template information,
1766             being careful not to overwrite drive and directory if not
1767             newly specified */
1768          char drive1[FILE_MAX_DRIVE];
1769          char dir1[FILE_MAX_DIR];
1770          char fname1[FILE_MAX_FNAME];
1771          char ext1[FILE_MAX_EXT];
1772          splitpath(speedstr,drive1,dir1,fname1,ext1);
1773          if(drive1[0])
1774             strcpy(drive,drive1);
1775          if(dir1[0])
1776             strcpy(dir,dir1);
1777          makepath(flname,drive,dir,fname1,ext1);
1778          if(strchr(fname1,'*') || strchr(fname1,'?') ||
1779              strchr(ext1  ,'*') || strchr(ext1  ,'?'))
1780             makepath(template,"","",fname1,ext1);
1781          else if(isadirectory(flname))
1782             fix_dirname(flname);
1783          goto restart;
1784       }
1785       else /* speedstate == SEARCHPATH */
1786       {
1787          char fullpath[FILE_MAX_DIR];
1788          findpath(speedstr,fullpath);
1789          if(fullpath[0])
1790             strcpy(flname,fullpath);
1791          else
1792          {  /* failed, make diagnostic useful: */
1793             strcpy(flname,speedstr);
1794             if (strchr(speedstr,SLASHC) == NULL)
1795             {
1796                splitpath(speedstr,NULL,NULL,fname,ext);
1797                makepath(flname,drive,dir,fname,ext);
1798             }
1799          }
1800       }
1801    }
1802    makepath(browsename,"","",fname,ext);
1803    return(0);
1804 }
1805 
1806 #ifdef __CLINT__
1807 #pragma argsused
1808 #endif
1809 
check_f6_key(int curkey,int choice)1810 static int check_f6_key(int curkey,int choice)
1811 { /* choice is dummy used by other routines called by fullscreen_choice() */
1812    choice = 0; /* to suppress warning only */
1813    if (curkey == F6)
1814       return 0-F6;
1815    else if (curkey == F4)
1816       return 0-F4;
1817    return 0;
1818 }
1819 
filename_speedstr(int row,int col,int vid,char * speedstring,int speed_match)1820 static int filename_speedstr(int row, int col, int vid,
1821                              char *speedstring, int speed_match)
1822 {
1823    char *prompt;
1824    if ( strchr(speedstring,':')
1825      || strchr(speedstring,'*') || strchr(speedstring,'*')
1826      || strchr(speedstring,'?')) {
1827       speedstate = TEMPLATE;  /* template */
1828       prompt = "File Template";
1829       }
1830    else if (speed_match) {
1831       speedstate = SEARCHPATH; /* does not match list */
1832       prompt = "Search Path for";
1833       }
1834    else {
1835       speedstate = MATCHING;
1836       prompt = speed_prompt;
1837       }
1838    putstring(row,col,vid,prompt);
1839    return(strlen(prompt));
1840 }
1841 
isadirectory(char * s)1842 int isadirectory(char *s)
1843 {
1844    int len;
1845    char sv;
1846 #ifdef _MSC_VER
1847    unsigned attrib = 0;
1848 #endif
1849    despace(s);  /* scrunch out white space */
1850    if(strchr(s,'*') || strchr(s,'?'))
1851       return(0); /* for my purposes, not a directory */
1852 
1853    len = strlen(s);
1854    if(len > 0)
1855       sv = s[len-1];   /* last char */
1856    else
1857       sv = 0;
1858 
1859 #ifdef _MSC_VER
1860    if(_dos_getfileattr(s, &attrib) == 0 && ((attrib&_A_SUBDIR) != 0))
1861    {
1862       return(1);  /* not a directory or doesn't exist */
1863    }
1864    else if(sv == SLASHC)
1865    {
1866       /* strip trailing slash and try again */
1867       s[len-1] = 0;
1868       if(_dos_getfileattr(s, &attrib) == 0 && ((attrib&_A_SUBDIR) != 0))
1869       {
1870          s[len-1] = sv;
1871          return(1);
1872       }
1873       s[len-1] = sv;
1874    }
1875    return(0);
1876 #else
1877    if(fr_findfirst(s) != 0) /* couldn't find it */
1878    {
1879       /* any better ideas?? */
1880      if(sv == SLASHC) /* we'll guess it is a directory */
1881          return(1);
1882       else
1883          return(0);  /* no slashes - we'll guess it's a file */
1884    }
1885    else if((DTA.attribute & SUBDIR) != 0) {
1886       if(sv == SLASHC) {
1887       /* strip trailing slash and try again */
1888          s[len-1] = 0;
1889          if(fr_findfirst(s) != 0) /* couldn't find it */
1890              return(0);
1891          else if((DTA.attribute & SUBDIR) != 0)
1892              return(1);   /* we're SURE it's a directory */
1893          else
1894              return(0);
1895       } else
1896          return(1);   /* we're SURE it's a directory */
1897    }
1898    return(0);
1899 #endif
1900 }
1901 
1902 
1903 #ifndef XFRACT  /* This routine moved to unix.c so we can use it in hc.c */
1904 
splitpath(char far * template,char * drive,char * dir,char * fname,char * ext)1905 int splitpath(char far *template,char *drive,char *dir,char *fname,char *ext)
1906 {
1907    int length;
1908    int len;
1909    int offset;
1910    char far *tmp;
1911    if(drive)
1912       drive[0] = 0;
1913    if(dir)
1914       dir[0]   = 0;
1915    if(fname)
1916       fname[0] = 0;
1917    if(ext)
1918       ext[0]   = 0;
1919 
1920    if((length = far_strlen(template)) == 0)
1921       return(0);
1922 
1923    offset = 0;
1924 
1925    /* get drive */
1926    if(length >= 2)
1927       if(template[1] == ':')
1928       {
1929          if(drive)
1930          {
1931             drive[0] = template[offset++];
1932             drive[1] = template[offset++];
1933             drive[2] = 0;
1934          }
1935          else
1936          {
1937             offset++;
1938             offset++;
1939          }
1940       }
1941 
1942    /* get dir */
1943    if(offset < length)
1944    {
1945       tmp = far_strrchr(template,SLASHC);
1946       if(tmp)
1947       {
1948          tmp++;  /* first character after slash */
1949          len = tmp - (char far *)&template[offset];
1950          if(len >= 0 && len < FILE_MAX_DIR && dir)
1951             far_strncpy(dir,&template[offset],min(len,FILE_MAX_DIR));
1952          if(len < FILE_MAX_DIR && dir)
1953             dir[len] = 0;
1954          offset += len;
1955       }
1956    }
1957    else
1958       return(0);
1959 
1960    /* get fname */
1961    if(offset < length)
1962    {
1963       tmp = far_strrchr(template,'.');
1964       if(tmp < far_strrchr(template,SLASHC) || tmp < far_strrchr(template,':'))
1965          tmp = 0; /* in this case the '.' must be a directory */
1966       if(tmp)
1967       {
1968          /* tmp++; */ /* first character past "." */
1969          len = tmp - (char far *)&template[offset];
1970          if((len > 0) && (offset+len < length) && fname)
1971          {
1972             far_strncpy(fname,&template[offset],min(len,FILE_MAX_FNAME));
1973             if(len < FILE_MAX_FNAME)
1974                fname[len] = 0;
1975             else
1976                fname[FILE_MAX_FNAME-1] = 0;
1977          }
1978          offset += len;
1979          if((offset < length) && ext)
1980          {
1981             far_strncpy(ext,&template[offset],FILE_MAX_EXT);
1982             ext[FILE_MAX_EXT-1] = 0;
1983          }
1984       }
1985       else if((offset < length) && fname)
1986       {
1987          far_strncpy(fname,&template[offset],FILE_MAX_FNAME);
1988          fname[FILE_MAX_FNAME-1] = 0;
1989       }
1990    }
1991    return(0);
1992 }
1993 #endif
1994 
makepath(char * template,char * drive,char * dir,char * fname,char * ext)1995 int makepath(char *template,char *drive,char *dir,char *fname,char *ext)
1996 {
1997    if(template)
1998       *template = 0;
1999    else
2000       return(-1);
2001 #ifndef XFRACT
2002    if(drive)
2003       strcpy(template,drive);
2004 #endif
2005    if(dir)
2006       strcat(template,dir);
2007    if(fname)
2008       strcat(template,fname);
2009    if(ext)
2010       strcat(template,ext);
2011    return(0);
2012 }
2013 
2014 
2015 /* fix up directory names */
fix_dirname(char * dirname)2016 void fix_dirname(char *dirname)
2017 {
2018    int length;
2019    despace(dirname);
2020    length = strlen(dirname); /* index of last character */
2021 
2022    /* make sure dirname ends with a slash */
2023    if(length > 0)
2024       if(dirname[length-1] == SLASHC)
2025          return;
2026    strcat(dirname,SLASH);
2027 }
2028 
dir_name(char * target,char * dir,char * name)2029 static void dir_name(char *target, char *dir, char *name)
2030 {
2031    *target = 0;
2032    if(*dir != 0)
2033       strcpy(target,dir);
2034    strcat(target,name);
2035 }
2036 
2037 /* opens file in dir directory */
dir_open(char * dir,char * filename,int oflag,int pmode)2038 int dir_open(char *dir, char *filename, int oflag, int pmode)
2039 {
2040    char tmp[FILE_MAX_PATH];
2041    dir_name(tmp,dir,filename);
2042    return(open(tmp,oflag,pmode));
2043 }
2044 
2045 /* removes file in dir directory */
dir_remove(char * dir,char * filename)2046 int dir_remove(char *dir,char *filename)
2047 {
2048    char tmp[FILE_MAX_PATH];
2049    dir_name(tmp,dir,filename);
2050    return(remove(tmp));
2051 }
2052 
2053 /* fopens file in dir directory */
dir_fopen(char * dir,char * filename,char * mode)2054 FILE *dir_fopen(char *dir, char *filename, char *mode )
2055 {
2056    char tmp[FILE_MAX_PATH];
2057    dir_name(tmp,dir,filename);
2058    return(fopen(tmp,mode));
2059 }
2060 
2061 /* converts relative path to absolute path */
expand_dirname(char * dirname,char * drive)2062 static int expand_dirname(char *dirname,char *drive)
2063 {
2064 #ifdef XFRACT
2065    char *dummy; /* to quiet compiler */
2066 #endif
2067    fix_dirname(dirname);
2068    if (dirname[0] != SLASHC) {
2069       char buf[FILE_MAX_DIR+1],curdir[FILE_MAX_DIR+1];
2070 #ifndef XFRACT
2071       int i=0;
2072       union REGS regs;
2073       struct SREGS sregs;
2074       curdir[0] = 0;
2075       regs.h.ah = 0x47; /* get current directory */
2076       regs.h.dl = 0;
2077       if (drive[0] && drive[0] != ' ')
2078          regs.h.dl = (char)(tolower(drive[0])-'a'+1);
2079       regs.x.si = (unsigned int) &curdir[0];
2080       segread(&sregs);
2081       intdosx(&regs, &regs, &sregs);
2082 #else
2083       dummy = getcwd(curdir,FILE_MAX_DIR);
2084 #endif
2085       strcat(curdir,SLASH);
2086 #ifndef XFRACT
2087       while (curdir[i] != 0) {
2088          curdir[i] = (char)tolower(curdir[i]);
2089          i++;
2090       }
2091 #endif
2092       while (strncmp(dirname,DOTSLASH,2) == 0) {
2093          strcpy(buf,&dirname[2]);
2094          strcpy(dirname,buf);
2095          }
2096       while (strncmp(dirname,DOTDOTSLASH,3) == 0) {
2097          char *s;
2098          curdir[strlen(curdir)-1] = 0; /* strip trailing slash */
2099          if ((s = strrchr(curdir,SLASHC)) != NULL)
2100             *s = 0;
2101          strcat(curdir,SLASH);
2102          strcpy(buf,&dirname[3]);
2103          strcpy(dirname,buf);
2104          }
2105       strcpy(buf,dirname);
2106       dirname[0] = 0;
2107       if (curdir[0] != SLASHC)
2108          strcpy(dirname,SLASH);
2109       strcat(dirname,curdir);
2110       strcat(dirname,buf);
2111       }
2112    return(0);
2113 }
2114 
2115 
2116 /*
2117    See if double value was changed by input screen. Problem is that the
2118    conversion from double to string and back can make small changes
2119    in the value, so will it twill test as "different" even though it
2120    is not
2121 */
cmpdbl(double old,double new)2122 int cmpdbl(double old, double new)
2123 {
2124    char buf[81];
2125    struct fullscreenvalues val;
2126 
2127    /* change the old value with the same torture the new value had */
2128    val.type = 'd'; /* most values on this screen are type d */
2129    val.uval.dval = old;
2130    prompt_valuestring(buf,&val);   /* convert "old" to string */
2131 
2132    old = atof(buf);                /* convert back */
2133    return(fabs(old-new)<DBL_EPSILON?0:1);  /* zero if same */
2134 }
2135 
2136 #define LOADPROMPTS(X)     {\
2137    static FCODE tmp[] = { X };\
2138    far_strcpy(ptr,(char far *)tmp);\
2139    prompts[++nump]= ptr;\
2140    ptr += sizeof(tmp);\
2141    }
2142 
get_corners()2143 int get_corners()
2144 {
2145    char far *ptr;
2146    struct fullscreenvalues values[15];
2147    char far *prompts[15];
2148    static FCODE o_xprompt[]={"          X"};
2149    static FCODE o_yprompt[]={"          Y"};
2150    static FCODE o_zprompt[]={"          Z"};
2151    char xprompt[sizeof(o_xprompt)];
2152    char yprompt[sizeof(o_yprompt)];
2153    char zprompt[sizeof(o_zprompt)];
2154    int i,nump,prompt_ret;
2155    int cmag;
2156    double Xctr,Yctr;
2157    LDBL Magnification; /* LDBL not really needed here, but used to match function parameters */
2158    double Xmagfactor,Rotation,Skew;
2159    BYTE ousemag;
2160    double oxxmin,oxxmax,oyymin,oyymax,oxx3rd,oyy3rd;
2161    static FCODE hdg[]={"Image Coordinates"};
2162    int oldhelpmode;
2163 
2164    far_strcpy(xprompt,o_xprompt);
2165    far_strcpy(yprompt,o_yprompt);
2166    far_strcpy(zprompt,o_zprompt);
2167    ptr = (char far *)MK_FP(extraseg,0);
2168    oldhelpmode = helpmode;
2169    ousemag = usemag;
2170    oxxmin = xxmin; oxxmax = xxmax;
2171    oyymin = yymin; oyymax = yymax;
2172    oxx3rd = xx3rd; oyy3rd = yy3rd;
2173 
2174 gc_loop:
2175    for (i = 0; i < 15; ++i)
2176       values[i].type = 'd'; /* most values on this screen are type d */
2177    cmag = usemag;
2178    if (drawmode == 'l')
2179       cmag = 0;
2180    cvtcentermag(&Xctr, &Yctr, &Magnification, &Xmagfactor, &Rotation, &Skew);
2181 
2182    nump = -1;
2183    if (cmag) {
2184       LOADPROMPTS("Center X");
2185       values[nump].uval.dval = Xctr;
2186       LOADPROMPTS("Center Y");
2187       values[nump].uval.dval = Yctr;
2188       LOADPROMPTS("Magnification");
2189       values[nump].uval.dval = (double)Magnification;
2190       LOADPROMPTS("X Magnification Factor");
2191       values[nump].uval.dval = Xmagfactor;
2192       LOADPROMPTS("Rotation Angle (degrees)");
2193       values[nump].uval.dval = Rotation;
2194       LOADPROMPTS("Skew Angle (degrees)");
2195       values[nump].uval.dval = Skew;
2196       LOADPROMPTS("");
2197       values[nump].type = '*';
2198       LOADPROMPTS("Press "FK_F7" to switch to \"corners\" mode");
2199       values[nump].type = '*';
2200       }
2201 
2202    else {
2203       if (drawmode == 'l') {
2204          LOADPROMPTS("Left End Point");
2205          values[nump].type = '*';
2206          prompts[++nump] = xprompt;
2207          values[nump].uval.dval = xxmin;
2208          prompts[++nump] = yprompt;
2209          values[nump].uval.dval = yymax;
2210          LOADPROMPTS("Right End Point");
2211          values[nump].type = '*';
2212          prompts[++nump] = xprompt;
2213          values[nump].uval.dval = xxmax;
2214          prompts[++nump] = yprompt;
2215          values[nump].uval.dval = yymin;
2216       } else {
2217          LOADPROMPTS("Top-Left Corner");
2218          values[nump].type = '*';
2219          prompts[++nump] = xprompt;
2220          values[nump].uval.dval = xxmin;
2221          prompts[++nump] = yprompt;
2222          values[nump].uval.dval = yymax;
2223          LOADPROMPTS("Bottom-Right Corner");
2224          values[nump].type = '*';
2225          prompts[++nump] = xprompt;
2226          values[nump].uval.dval = xxmax;
2227          prompts[++nump] = yprompt;
2228          values[nump].uval.dval = yymin;
2229          if (xxmin == xx3rd && yymin == yy3rd)
2230             xx3rd = yy3rd = 0;
2231          LOADPROMPTS("Bottom-left (zeros for top-left X, bottom-right Y)");
2232          values[nump].type = '*';
2233          prompts[++nump] = xprompt;
2234          values[nump].uval.dval = xx3rd;
2235          prompts[++nump] = yprompt;
2236          values[nump].uval.dval = yy3rd;
2237          LOADPROMPTS("Press "FK_F7" to switch to \"center-mag\" mode");
2238          values[nump].type = '*';
2239       }
2240    }
2241 
2242    LOADPROMPTS("Press "FK_F4" to reset to type default values");
2243    values[nump].type = '*';
2244 
2245    oldhelpmode = helpmode;
2246    helpmode = HELPCOORDS;
2247    prompt_ret = fullscreen_prompt(hdg,nump+1, prompts, values, 0x90, NULL);
2248    helpmode = oldhelpmode;
2249 
2250    if (prompt_ret < 0) {
2251       usemag = ousemag;
2252       xxmin = oxxmin; xxmax = oxxmax;
2253       yymin = oyymin; yymax = oyymax;
2254       xx3rd = oxx3rd; yy3rd = oyy3rd;
2255       return(-1);
2256       }
2257 
2258    if (prompt_ret == F4) { /* reset to type defaults */
2259       xx3rd = xxmin = curfractalspecific->xmin;
2260       xxmax         = curfractalspecific->xmax;
2261       yy3rd = yymin = curfractalspecific->ymin;
2262       yymax         = curfractalspecific->ymax;
2263       if (viewcrop && finalaspectratio != screenaspect)
2264          aspectratio_crop(screenaspect,finalaspectratio);
2265       if(bf_math != 0)
2266          fractal_floattobf();
2267       goto gc_loop;
2268       }
2269 
2270    if (cmag) {
2271       if ( cmpdbl(Xctr         , values[0].uval.dval)
2272         || cmpdbl(Yctr         , values[1].uval.dval)
2273         || cmpdbl((double)Magnification, values[2].uval.dval)
2274         || cmpdbl(Xmagfactor   , values[3].uval.dval)
2275         || cmpdbl(Rotation     , values[4].uval.dval)
2276         || cmpdbl(Skew         , values[5].uval.dval))
2277       {
2278          Xctr          = values[0].uval.dval;
2279          Yctr          = values[1].uval.dval;
2280          Magnification = values[2].uval.dval;
2281          Xmagfactor    = values[3].uval.dval;
2282          Rotation      = values[4].uval.dval;
2283          Skew          = values[5].uval.dval;
2284          if (Xmagfactor == 0)
2285             Xmagfactor = 1;
2286          cvtcorners(Xctr, Yctr, Magnification, Xmagfactor, Rotation, Skew);
2287       }
2288    }
2289 
2290    else {
2291       if (drawmode == 'l') {
2292          nump = 1;
2293          xxmin = values[nump++].uval.dval;
2294          yymax = values[nump++].uval.dval;
2295          nump++;
2296          xxmax = values[nump++].uval.dval;
2297          yymin = values[nump++].uval.dval;
2298       } else {
2299          nump = 1;
2300          xxmin = values[nump++].uval.dval;
2301          yymax = values[nump++].uval.dval;
2302          nump++;
2303          xxmax = values[nump++].uval.dval;
2304          yymin = values[nump++].uval.dval;
2305          nump++;
2306          xx3rd = values[nump++].uval.dval;
2307          yy3rd = values[nump++].uval.dval;
2308          if (xx3rd == 0 && yy3rd == 0) {
2309             xx3rd = xxmin;
2310             yy3rd = yymin;
2311          }
2312       }
2313    }
2314 
2315    if (prompt_ret == F7 && drawmode != 'l') { /* toggle corners/center-mag mode */
2316       if (usemag == 0)
2317       {
2318          cvtcentermag(&Xctr, &Yctr, &Magnification, &Xmagfactor, &Rotation, &Skew);
2319             usemag = 1;
2320       }
2321       else
2322          usemag = 0;
2323       goto gc_loop;
2324       }
2325 
2326    if(!cmpdbl(oxxmin,xxmin) && !cmpdbl(oxxmax,xxmax) && !cmpdbl(oyymin,yymin) &&
2327       !cmpdbl(oyymax,yymax) && !cmpdbl(oxx3rd,xx3rd) && !cmpdbl(oyy3rd,yy3rd))
2328    {
2329      /* no change, restore values to avoid drift */
2330       xxmin = oxxmin; xxmax = oxxmax;
2331       yymin = oyymin; yymax = oyymax;
2332       xx3rd = oxx3rd; yy3rd = oyy3rd;
2333       return 0;
2334    }
2335    else
2336       return(1);
2337 }
2338 
get_screen_corners(void)2339 static int get_screen_corners(void)
2340 {
2341    char far *ptr;
2342    struct fullscreenvalues values[15];
2343    char far *prompts[15];
2344    static FCODE o_xprompt[]={"          X"};
2345    static FCODE o_yprompt[]={"          Y"};
2346    static FCODE o_zprompt[]={"          Z"};
2347    char xprompt[sizeof(o_xprompt)];
2348    char yprompt[sizeof(o_yprompt)];
2349    char zprompt[sizeof(o_zprompt)];
2350    int i,nump,prompt_ret;
2351    int cmag;
2352    double Xctr,Yctr;
2353    LDBL Magnification; /* LDBL not really needed here, but used to match function parameters */
2354    double Xmagfactor,Rotation,Skew;
2355    BYTE ousemag;
2356    double oxxmin,oxxmax,oyymin,oyymax,oxx3rd,oyy3rd;
2357    double svxxmin,svxxmax,svyymin,svyymax,svxx3rd,svyy3rd;
2358    static FCODE hdg[]={"Screen Coordinates"};
2359    int oldhelpmode;
2360 
2361    far_strcpy(xprompt,o_xprompt);
2362    far_strcpy(yprompt,o_yprompt);
2363    far_strcpy(zprompt,o_zprompt);
2364    ptr = (char far *)MK_FP(extraseg,0);
2365    oldhelpmode = helpmode;
2366    ousemag = usemag;
2367 
2368    svxxmin = xxmin;  /* save these for later since cvtcorners modifies them */
2369    svxxmax = xxmax;  /* and we need to set them for cvtcentermag to work */
2370    svxx3rd = xx3rd;
2371    svyymin = yymin;
2372    svyymax = yymax;
2373    svyy3rd = yy3rd;
2374 
2375    if (!set_orbit_corners && !keep_scrn_coords) {
2376       oxmin = xxmin;
2377       oxmax = xxmax;
2378       ox3rd = xx3rd;
2379       oymin = yymin;
2380       oymax = yymax;
2381       oy3rd = yy3rd;
2382    }
2383 
2384    oxxmin = oxmin; oxxmax = oxmax;
2385    oyymin = oymin; oyymax = oymax;
2386    oxx3rd = ox3rd; oyy3rd = oy3rd;
2387 
2388    xxmin = oxmin; xxmax = oxmax;
2389    yymin = oymin; yymax = oymax;
2390    xx3rd = ox3rd; yy3rd = oy3rd;
2391 
2392 gsc_loop:
2393    for (i = 0; i < 15; ++i)
2394       values[i].type = 'd'; /* most values on this screen are type d */
2395    cmag = usemag;
2396    cvtcentermag(&Xctr, &Yctr, &Magnification, &Xmagfactor, &Rotation, &Skew);
2397 
2398    nump = -1;
2399    if (cmag) {
2400       LOADPROMPTS("Center X");
2401       values[nump].uval.dval = Xctr;
2402       LOADPROMPTS("Center Y");
2403       values[nump].uval.dval = Yctr;
2404       LOADPROMPTS("Magnification");
2405       values[nump].uval.dval = (double)Magnification;
2406       LOADPROMPTS("X Magnification Factor");
2407       values[nump].uval.dval = Xmagfactor;
2408       LOADPROMPTS("Rotation Angle (degrees)");
2409       values[nump].uval.dval = Rotation;
2410       LOADPROMPTS("Skew Angle (degrees)");
2411       values[nump].uval.dval = Skew;
2412       LOADPROMPTS("");
2413       values[nump].type = '*';
2414       LOADPROMPTS("Press "FK_F7" to switch to \"corners\" mode");
2415       values[nump].type = '*';
2416    } else {
2417       LOADPROMPTS("Top-Left Corner");
2418       values[nump].type = '*';
2419       prompts[++nump] = xprompt;
2420       values[nump].uval.dval = oxmin;
2421       prompts[++nump] = yprompt;
2422       values[nump].uval.dval = oymax;
2423       LOADPROMPTS("Bottom-Right Corner");
2424       values[nump].type = '*';
2425       prompts[++nump] = xprompt;
2426       values[nump].uval.dval = oxmax;
2427       prompts[++nump] = yprompt;
2428       values[nump].uval.dval = oymin;
2429       if (oxmin == ox3rd && oymin == oy3rd)
2430          ox3rd = oy3rd = 0;
2431       LOADPROMPTS("Bottom-left (zeros for top-left X, bottom-right Y)");
2432       values[nump].type = '*';
2433       prompts[++nump] = xprompt;
2434       values[nump].uval.dval = ox3rd;
2435       prompts[++nump] = yprompt;
2436       values[nump].uval.dval = oy3rd;
2437       LOADPROMPTS("Press "FK_F7" to switch to \"center-mag\" mode");
2438       values[nump].type = '*';
2439    }
2440 
2441    LOADPROMPTS("Press "FK_F4" to reset to type default values");
2442    values[nump].type = '*';
2443 
2444    oldhelpmode = helpmode;
2445    helpmode = HELPSCRNCOORDS;
2446    prompt_ret = fullscreen_prompt(hdg,nump+1, prompts, values, 0x90, NULL);
2447    helpmode = oldhelpmode;
2448 
2449    if (prompt_ret < 0) {
2450       usemag = ousemag;
2451       oxmin = oxxmin; oxmax = oxxmax;
2452       oymin = oyymin; oymax = oyymax;
2453       ox3rd = oxx3rd; oy3rd = oyy3rd;
2454       /* restore corners */
2455       xxmin = svxxmin; xxmax = svxxmax;
2456       yymin = svyymin; yymax = svyymax;
2457       xx3rd = svxx3rd; yy3rd = svyy3rd;
2458       return(-1);
2459       }
2460 
2461    if (prompt_ret == F4) { /* reset to type defaults */
2462       ox3rd = oxmin = curfractalspecific->xmin;
2463       oxmax         = curfractalspecific->xmax;
2464       oy3rd = oymin = curfractalspecific->ymin;
2465       oymax         = curfractalspecific->ymax;
2466       xxmin = oxmin; xxmax = oxmax;
2467       yymin = oymin; yymax = oymax;
2468       xx3rd = ox3rd; yy3rd = oy3rd;
2469       if (viewcrop && finalaspectratio != screenaspect)
2470          aspectratio_crop(screenaspect,finalaspectratio);
2471 
2472       oxmin = xxmin; oxmax = xxmax;
2473       oymin = yymin; oymax = yymax;
2474       ox3rd = xxmin; oy3rd = yymin;
2475       goto gsc_loop;
2476       }
2477 
2478    if (cmag) {
2479       if ( cmpdbl(Xctr         , values[0].uval.dval)
2480         || cmpdbl(Yctr         , values[1].uval.dval)
2481         || cmpdbl((double)Magnification, values[2].uval.dval)
2482         || cmpdbl(Xmagfactor   , values[3].uval.dval)
2483         || cmpdbl(Rotation     , values[4].uval.dval)
2484         || cmpdbl(Skew         , values[5].uval.dval))
2485       {
2486          Xctr          = values[0].uval.dval;
2487          Yctr          = values[1].uval.dval;
2488          Magnification = values[2].uval.dval;
2489          Xmagfactor    = values[3].uval.dval;
2490          Rotation      = values[4].uval.dval;
2491          Skew          = values[5].uval.dval;
2492          if (Xmagfactor == 0)
2493             Xmagfactor = 1;
2494          cvtcorners(Xctr, Yctr, Magnification, Xmagfactor, Rotation, Skew);
2495          /* set screen corners */
2496          oxmin = xxmin; oxmax = xxmax;
2497          oymin = yymin; oymax = yymax;
2498          ox3rd = xx3rd; oy3rd = yy3rd;
2499       }
2500    }
2501    else {
2502       nump = 1;
2503       oxmin = values[nump++].uval.dval;
2504       oymax = values[nump++].uval.dval;
2505       nump++;
2506       oxmax = values[nump++].uval.dval;
2507       oymin = values[nump++].uval.dval;
2508       nump++;
2509       ox3rd = values[nump++].uval.dval;
2510       oy3rd = values[nump++].uval.dval;
2511       if (ox3rd == 0 && oy3rd == 0) {
2512          ox3rd = oxmin;
2513          oy3rd = oymin;
2514       }
2515    }
2516 
2517    if (prompt_ret == F7) { /* toggle corners/center-mag mode */
2518       if (usemag == 0)
2519       {
2520          cvtcentermag(&Xctr, &Yctr, &Magnification, &Xmagfactor, &Rotation, &Skew);
2521             usemag = 1;
2522       }
2523       else
2524          usemag = 0;
2525       goto gsc_loop;
2526       }
2527 
2528    if(!cmpdbl(oxxmin,oxmin) && !cmpdbl(oxxmax,oxmax) && !cmpdbl(oyymin,oymin) &&
2529       !cmpdbl(oyymax,oymax) && !cmpdbl(oxx3rd,ox3rd) && !cmpdbl(oyy3rd,oy3rd))
2530    {
2531      /* no change, restore values to avoid drift */
2532       oxmin = oxxmin; oxmax = oxxmax;
2533       oymin = oyymin; oymax = oyymax;
2534       ox3rd = oxx3rd; oy3rd = oyy3rd;
2535       /* restore corners */
2536       xxmin = svxxmin; xxmax = svxxmax;
2537       yymin = svyymin; yymax = svyymax;
2538       xx3rd = svxx3rd; yy3rd = svyy3rd;
2539       return 0;
2540    }
2541    else {
2542       set_orbit_corners = 1;
2543       keep_scrn_coords = 1;
2544       /* restore corners */
2545       xxmin = svxxmin; xxmax = svxxmax;
2546       yymin = svyymin; yymax = svyymax;
2547       xx3rd = svxx3rd; yy3rd = svyy3rd;
2548       return(1);
2549    }
2550 }
2551 
2552 /* get browse parameters , called from fractint.c and loadfile.c
2553    returns 3 if anything changes.  code pinched from get_view_params */
2554 
get_browse_params()2555 int get_browse_params()
2556 {
2557    static FCODE o_hdg[]={"Browse ('L'ook) Mode Options"};
2558    char hdg[sizeof(o_hdg)];
2559    char far *ptr;
2560    char far *choices[10];
2561 
2562    int oldhelpmode;
2563    struct fullscreenvalues uvalues[25];
2564    int i, k;
2565    int old_autobrowse,old_brwschecktype,old_brwscheckparms,old_doublecaution;
2566    int old_minbox;
2567    double old_toosmall;
2568    char old_browsemask[MAX_NAME];
2569 
2570    far_strcpy(hdg,o_hdg);
2571    ptr = (char far *)MK_FP(extraseg,0);
2572    old_autobrowse     = autobrowse;
2573    old_brwschecktype  = brwschecktype;
2574    old_brwscheckparms = brwscheckparms;
2575    old_doublecaution  = doublecaution;
2576    old_minbox         = minbox;
2577    old_toosmall       = toosmall;
2578    strcpy(old_browsemask,browsemask);
2579 
2580 get_brws_restart:
2581    /* fill up the previous values arrays */
2582    k = -1;
2583 
2584    LOADCHOICES("Autobrowsing? (y/n)");
2585    uvalues[k].type = 'y';
2586    uvalues[k].uval.ch.val = autobrowse;
2587 
2588    LOADCHOICES("Ask about GIF video mode? (y/n)");
2589    uvalues[k].type = 'y';
2590    uvalues[k].uval.ch.val = askvideo;
2591 
2592    LOADCHOICES("Check fractal type? (y/n)");
2593    uvalues[k].type = 'y';
2594    uvalues[k].uval.ch.val = brwschecktype;
2595 
2596    LOADCHOICES("Check fractal parameters (y/n)");
2597    uvalues[k].type = 'y';
2598    uvalues[k].uval.ch.val = brwscheckparms;
2599 
2600    LOADCHOICES("Confirm file deletes (y/n)");
2601    uvalues[k].type='y';
2602    uvalues[k].uval.ch.val = doublecaution;
2603 
2604    LOADCHOICES("Smallest window to display (size in pixels)");
2605    uvalues[k].type = 'f';
2606    uvalues[k].uval.dval = toosmall;
2607 
2608    LOADCHOICES("Smallest box size shown before crosshairs used (pix)");
2609    uvalues[k].type = 'i';
2610    uvalues[k].uval.ival = minbox;
2611     LOADCHOICES("Browse search filename mask ");
2612    uvalues[k].type = 's';
2613    strcpy(uvalues[k].uval.sval,browsemask);
2614 
2615    LOADCHOICES("");
2616    uvalues[k].type = '*';
2617 
2618    LOADCHOICES("Press "FK_F4" to reset browse parameters to defaults.");
2619    uvalues[k].type = '*';
2620 
2621    oldhelpmode = helpmode;     /* this prevents HELP from activating */
2622    helpmode = HELPBRWSPARMS;
2623    i = fullscreen_prompt(hdg,k+1,choices,uvalues,16,NULL);
2624    helpmode = oldhelpmode;     /* re-enable HELP */
2625    if (i < 0) {
2626       return(0);
2627       }
2628 
2629    if (i == F4) {
2630       toosmall = 6;
2631       autobrowse = FALSE;
2632       askvideo = TRUE;
2633       brwscheckparms = TRUE;
2634       brwschecktype  = TRUE;
2635       doublecaution  = TRUE;
2636       minbox = 3;
2637       strcpy(browsemask,"*.gif");
2638       goto get_brws_restart;
2639       }
2640 
2641    /* now check out the results (*hopefully* in the same order <grin>) */
2642    k = -1;
2643 
2644    autobrowse = uvalues[++k].uval.ch.val;
2645 
2646    askvideo = uvalues[++k].uval.ch.val;
2647 
2648    brwschecktype = (char)uvalues[++k].uval.ch.val;
2649 
2650    brwscheckparms = (char)uvalues[++k].uval.ch.val;
2651 
2652    doublecaution = uvalues[++k].uval.ch.val;
2653 
2654    toosmall  = uvalues[++k].uval.dval;
2655    if (toosmall < 0 ) toosmall = 0 ;
2656 
2657    minbox = uvalues[++k].uval.ival;
2658      if (minbox < 1 ) minbox = 1;
2659      if (minbox > 10) minbox = 10;
2660 
2661    strcpy(browsemask,uvalues[++k].uval.sval);
2662 
2663    i = 0;
2664    if (autobrowse != old_autobrowse ||
2665        brwschecktype != old_brwschecktype ||
2666        brwscheckparms != old_brwscheckparms ||
2667        doublecaution != old_doublecaution ||
2668        toosmall != old_toosmall ||
2669        minbox != old_minbox ||
2670        !stricmp(browsemask,old_browsemask) )
2671         i = -3;
2672 
2673    if (evolving) { /* can't browse */
2674       autobrowse = 0;
2675       i = 0;
2676    }
2677 
2678    return(i);
2679 }
2680 
2681 /* merge existing full path with new one  */
2682 /* attempt to detect if file or directory */
2683 
2684 #define ATFILENAME 0
2685 #define SSTOOLSINI 1
2686 #define ATCOMMANDINTERACTIVE 2
2687 #define ATFILENAMESETNAME  3
2688 
2689 #define GETPATH (mode < 2)
2690 
2691 #ifndef XFRACT
2692 #include <direct.h>
2693 #endif
2694 
2695 /* copies the proposed new filename to the fullpath variable */
2696 /* does not copy directories for PAR files (modes 2 and 3)   */
2697 /* attempts to extract directory and test for existence (modes 0 and 1) */
merge_pathnames(char * oldfullpath,char * newfilename,int mode)2698 int merge_pathnames(char *oldfullpath, char *newfilename, int mode)
2699 {
2700    int isadir = 0;
2701    int isafile = 0;
2702    int len;
2703    char drive[FILE_MAX_DRIVE];
2704    char dir[FILE_MAX_DIR];
2705    char fname[FILE_MAX_FNAME];
2706    char ext[FILE_MAX_EXT];
2707    char temp_path[FILE_MAX_PATH];
2708 
2709    char drive1[FILE_MAX_DRIVE];
2710    char dir1[FILE_MAX_DIR];
2711    char fname1[FILE_MAX_FNAME];
2712    char ext1[FILE_MAX_EXT];
2713 
2714    /* no dot or slash so assume a file */
2715    if(strchr(newfilename,'.')==NULL && strchr(newfilename,SLASHC) == NULL)
2716       isafile=1;
2717    if((isadir = isadirectory(newfilename)) != 0)
2718       fix_dirname(newfilename);
2719 #if 0
2720    /* if slash by itself, it's a directory */
2721    if(strcmp(newfilename,SLASH)==0)
2722       isadir = 1;
2723 #endif
2724 #ifndef XFRACT
2725    /* if drive, colon, slash, is a directory */
2726    if(strlen(newfilename) == 3 &&
2727            newfilename[1] == ':' &&
2728            newfilename[2] == SLASHC)
2729       isadir = 1;
2730    /* if drive, colon, with no slash, is a directory */
2731    if(strlen(newfilename) == 2 &&
2732            newfilename[1] == ':') {
2733       newfilename[2] = SLASHC;
2734       newfilename[3] = 0;
2735       isadir = 1;
2736       }
2737    /* if dot, slash, '0', its the current directory, set up full path */
2738    if(newfilename[0] == '.' &&
2739            newfilename[1] == SLASHC && newfilename[2] == 0) {
2740       temp_path[0] = (char)('a' + _getdrive() - 1);
2741       temp_path[1] = ':';
2742       temp_path[2] = 0;
2743       expand_dirname(newfilename,temp_path);
2744       strcat(temp_path,newfilename);
2745       strcpy(newfilename,temp_path);
2746       isadir = 1;
2747       }
2748    /* if dot, slash, its relative to the current directory, set up full path */
2749    if(newfilename[0] == '.' &&
2750            newfilename[1] == SLASHC) {
2751       int len, test_dir=0;
2752       temp_path[0] = (char)('a' + _getdrive() - 1);
2753       temp_path[1] = ':';
2754       temp_path[2] = 0;
2755       if (strrchr(newfilename,'.') == newfilename)
2756         test_dir = 1;  /* only one '.' assume its a directory */
2757       expand_dirname(newfilename,temp_path);
2758       strcat(temp_path,newfilename);
2759       strcpy(newfilename,temp_path);
2760       if (!test_dir) {
2761          len = strlen(newfilename);
2762          newfilename[len-1] = 0; /* get rid of slash added by expand_dirname */
2763       }
2764    }
2765 #else
2766    findpath(newfilename,temp_path);
2767    strcpy(newfilename,temp_path);
2768 #endif
2769    /* check existence */
2770    if(isadir==0 || isafile==1)
2771    {
2772        if(fr_findfirst(newfilename) == 0) {
2773           if(DTA.attribute & SUBDIR) /* exists and is dir */
2774           {
2775              fix_dirname(newfilename);  /* add trailing slash */
2776              isadir = 1;
2777              isafile = 0;
2778           }
2779           else
2780              isafile = 1;
2781        }
2782    }
2783 
2784    splitpath(newfilename,drive,dir,fname,ext);
2785    splitpath(oldfullpath,drive1,dir1,fname1,ext1);
2786    if(strlen(drive) != 0 && GETPATH)
2787       strcpy(drive1,drive);
2788    if(strlen(dir) != 0 && GETPATH)
2789       strcpy(dir1,dir);
2790    if(strlen(fname) != 0)
2791       strcpy(fname1,fname);
2792    if(strlen(ext) != 0)
2793       strcpy(ext1,ext);
2794    if(isadir == 0 && isafile == 0 && GETPATH)
2795    {
2796       makepath(oldfullpath,drive1,dir1,NULL,NULL);
2797       len = strlen(oldfullpath);
2798       if(len > 0)
2799       {
2800          char save;
2801          /* strip trailing slash */
2802          save = oldfullpath[len-1];
2803          if(save == SLASHC)
2804             oldfullpath[len-1] = 0;
2805          if(access(oldfullpath,0))
2806             isadir = -1;
2807          oldfullpath[len-1] = save;
2808       }
2809    }
2810    makepath(oldfullpath,drive1,dir1,fname1,ext1);
2811    return(isadir);
2812 }
2813 
2814 /* extract just the filename/extension portion of a path */
extract_filename(char * target,char * source)2815 void extract_filename(char *target, char *source)
2816 {
2817    char fname[FILE_MAX_FNAME];
2818    char ext[FILE_MAX_EXT];
2819    splitpath(source,NULL,NULL,fname,ext);
2820    makepath(target,"","",fname,ext);
2821 }
2822 
2823 /* tells if filename has extension */
2824 /* returns pointer to period or NULL */
has_ext(char * source)2825 char *has_ext(char *source)
2826 {
2827    char fname[FILE_MAX_FNAME];
2828    char ext[FILE_MAX_EXT];
2829    char *ret = NULL;
2830    splitpath(source,NULL,NULL,fname,ext);
2831    if(ext != NULL)
2832       if(*ext != 0)
2833          ret = strrchr(source,'.');
2834    return(ret);
2835 }
2836 
2837 
2838 /* I tried heap sort also - this is faster! */
shell_sort(void far * v1,int n,unsigned sz,int (__cdecl * fct)(VOIDFARPTR arg1,VOIDFARPTR arg2))2839 void shell_sort(void far *v1, int n, unsigned sz, int (__cdecl *fct)(VOIDFARPTR arg1,VOIDFARPTR arg2))
2840 {
2841    int gap,i,j;
2842    void far *temp;
2843    char far *v;
2844    v = (char far *)v1;
2845    for(gap = n/2; gap > 0; gap /= 2)
2846       for(i = gap; i<n; i++)
2847          for(j=i-gap;j>=0; j -= gap)
2848          {
2849             if(fct((char far *far*)(v+j*sz),(char far *far*)(v+(j+gap)*sz)) <= 0)
2850                break;
2851             temp = *(char far *far*)(v+j*sz);
2852             *(char far *far*)(v+j*sz) = *(char far *far*)(v+(j+gap)*sz);
2853             *(char far *far*)(v+(j+gap)*sz) = temp;
2854          }
2855 }
2856 
2857 #if (_MSC_VER >= 700)
2858 #pragma code_seg ("prompts3_text")     /* place following in an overlay */
2859 #endif
2860 
far_strncpy(char far * t,char far * s,int len)2861 void far_strncpy(char far *t, char far *s, int len)
2862 {
2863    while((len-- && (*t++ = *s++) != 0));
2864 }
2865 
far_strchr(char far * str,char c)2866 char far *far_strchr(char far *str, char c)
2867 {
2868    int len,i;
2869    len = far_strlen(str);
2870    i= -1;
2871    while (++i < len && c != str[i]);
2872    if(i == len)
2873       return(NULL);
2874    else
2875       return(&str[i]);
2876 }
2877 
far_strrchr(char far * str,char c)2878 char far *far_strrchr(char far *str, char c)
2879 {
2880    int len;
2881    len = far_strlen(str);
2882    while (--len > -1 && c != str[len]);
2883    if(len == -1)
2884       return(NULL);
2885    else
2886       return(&str[len]);
2887 }
2888 
2889 #if (_MSC_VER >= 700)
2890 #pragma code_seg ("")
2891 #endif
2892