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