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(®s, ®s);
1387 regs.h.ah = 0x4E; /* Find 1st file meeting path */
1388 regs.x.dx = (unsigned)path;
1389 regs.x.cx = FILEATTR;
1390 intdos(®s, ®s);
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(®s, ®s);
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(®s, ®s, &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