File: common\prompts1.c
1 /*
2 Various routines that prompt for things.
3 */
4
5 #include <string.h>
6 #include <ctype.h>
7 #ifdef XFRACT
8 #ifndef __386BSD__
9 #include <sys/types.h>
10 #include <sys/stat.h>
11 #endif 12 #endif
13 #ifdef __TURBOC__
15 #elif !defined(__386BSD__)
16 #include <malloc.h>
17 #endif
18
19 /* see Fractint.c for a description of the "include" hierarchy */
20 #include "port.h"
21 #include "prototyp.h"
22 #include "fractype.h"
23 #include "helpdefs.h"
24
25 #ifdef __hpux
26 #include <sys/param.h>
27 #define getwd(a) getcwd(a,MAXPATHLEN) 28 #endif
29
30 #ifdef __SVR4
31 #include <sys/param.h>
32 #define getwd(a) getcwd(a,MAXPATHLEN) 33 #endif
34
35 /* Routines used in prompts2.c */
36
37 int prompt_checkkey(int curkey);
38 int prompt_checkkey_scroll(int curkey);
39 long get_file_entry(int,char *,char *,char *,char *);
40
41 /* Routines in this module */
42
43 int prompt_valuestring(char *buf,struct fullscreenvalues *val);
44 static int input_field_list(int attr,char *fld,int vlen,char **list,int llen,
45 int row,int col,int (*checkkey)(int));
46 static int select_fracttype(int t);
47 static int sel_fractype_help(int curkey, int choice);
48 int select_type_params(int newfractype,int oldfractype);
49 void set_default_parms(void);
50 static long gfe_choose_entry(int,char *,char *,char *);
51 static int check_gfe_key(int curkey,int choice);
52 static void load_entry_text(FILE *entfile,char far *buf,int maxlines, int startrow, int startcol);
53 static void format_parmfile_line(int,char *);
54 static int get_light_params(void );
55 static int check_mapfile(void );
56 static int get_funny_glasses_params(void );
57
58 /* fullscreen_choice options */
59 #define CHOICEHELP 4
60
61 #define GETFORMULA 0
62 #define GETLSYS 1
63 #define GETIFS 2
64 #define GETPARM 3
65
66 static char funnyglasses_map_name[16];
67 char ifsmask[13] = {"*.ifs"};
68 char formmask[13] = {"*.frm"};
69 char lsysmask[13] = {"*.l"};
70 char Glasses1Map[] = "glasses1.map";
71 char MAP_name[FILE_MAX_DIR] = "";
72 int mapset = 0;
73 int julibrot; /* flag for julibrot */
74
75 /* --------------------------------------------------------------------- */
76
77 int promptfkeys;
78
79 /* These need to be global because F6 exits fullscreen_prompt() */
80 int scroll_row_status; /* will be set to first line of extra info to
81 be displayed ( 0 = top line) */
82 int scroll_column_status; /* will be set to first column of extra info to
83 be displayed ( 0 = leftmost column )*/
84
85 int fullscreen_prompt( /* full-screen prompting routine */
86 char far *hdg, /* heading, lines separated by \n */
87 int numprompts, /* there are this many prompts (max) */
88 char far **prompts, /* array of prompting pointers */
89 struct fullscreenvalues *values, /* array of values */
90 int fkeymask, /* bit n on if Fn to cause return */
91 char far *extrainfo /* extra info box to display, \n separated */
92 )
93 {
94 char far *hdgscan;
95 int titlelines,titlewidth,titlerow;
96 int maxpromptwidth,maxfldwidth,maxcomment;
97 int boxrow,boxlines;
98 int boxcol,boxwidth;
99 int extralines,extrawidth,extrarow;
100 int instrrow;
101 int promptrow,promptcol,valuecol;
102 int curchoice = 0;
103 int done, i, j;
104 int anyinput;
105 int savelookatmouse;
106 int curtype, curlen;
107 char buf[81];
108
109 /* scrolling related variables */
110 FILE * scroll_file = NULL; /* file with extrainfo entry to scroll */
111 long scroll_file_start = 0; /* where entry starts in scroll_file */
112 int in_scrolling_mode = 0; /* will be 1 if need to scroll extrainfo */
113 int lines_in_entry = 0; /* total lines in entry to be scrolled */
114 int vertical_scroll_limit = 0; /* don't scroll down if this is top line */
115 int widest_entry_line = 0; /* length of longest line in entry */
116 int rewrite_extrainfo = 0; /* if 1: rewrite extrainfo to text box */
117 char blanks[78]; /* used to clear text box */
118
119 static FCODE instr1[] = {"Use " UPARR1 " and " DNARR1 " to select values to change"};
120 static FCODE instr2a[] = {"Type in replacement value for selected field"};
121 static FCODE instr2b[] = {"Use " LTARR1 " or " RTARR1 " to change value of selected field"};
122 static FCODE instr3a[] = {"Press ENTER when finished (or ESCAPE to back out)"};
123 static FCODE instr3b[] = {"Press ENTER when finished, ESCAPE to back out, or "FK_F1" for help"};
124
125 static FCODE instr0[] = {"No changeable parameters;"};
126 static FCODE instr0a[] = {"Press ENTER to exit"};
127 static FCODE instr0b[] = {"Press ENTER to exit, ESC to back out, "FK_F1" for help"};
128
129 savelookatmouse = lookatmouse;
130 lookatmouse = 0;
131 promptfkeys = fkeymask;
132 memset(blanks,' ',77); /* initialize string of blanks */
133 blanks[77] = (char) 0;
134
135 /* If applicable, open file for scrolling extrainfo. The function
136 find_file_item() opens the file and sets the file pointer to the
137 beginning of the entry.
138 */
139
140 if((fractype == FORMULA || fractype == FFORMULA) && extrainfo && *extrainfo) {
141 find_file_item(FormFileName, FormName, &scroll_file, 1);
142 in_scrolling_mode = 1;
143 scroll_file_start = ftell(scroll_file);
144 }
145
146 else if(fractype == LSYSTEM && extrainfo && *extrainfo) {
147 find_file_item(LFileName, LName, &scroll_file, 2);
148 in_scrolling_mode = 1;
149 scroll_file_start = ftell(scroll_file);
150 }
151
152 else if((fractype == IFS || fractype == IFS3D) && extrainfo && *extrainfo) {
153 find_file_item(IFSFileName, IFSName, &scroll_file, 3);
154 in_scrolling_mode = 1;
155 scroll_file_start = ftell(scroll_file);
156 }
157
158 /* initialize widest_entry_line and lines_in_entry */
159 if(in_scrolling_mode && scroll_file != NULL) {
160 int comment = 0;
161 int c = 0;
162 int widthct = 0;
163 while((c = fgetc(scroll_file)) != EOF && c != '\032') {
164 if(c == ';')
165 comment = 1;
166 else if(c == '\n') {
167 comment = 0;
168 lines_in_entry++;
169 widthct = -1;
170 }
171 else if (c == '\t')
172 widthct += 7 - widthct % 8;
173 else if ( c == '\r')
174 continue;
175 if(++widthct > widest_entry_line)
176 widest_entry_line = widthct;
177 if (c == '}' && !comment) {
178 lines_in_entry++;
179 break;
180 }
181 }
182 if(c == EOF || c == '\032') { /* should never happen */
183 fclose(scroll_file);
184 in_scrolling_mode = 0;
185 }
186 }
187
188
189
190 helptitle(); /* clear screen, display title line */
191 setattr(1,0,C_PROMPT_BKGRD,24*80); /* init rest of screen to background */
192
193
194 hdgscan = hdg; /* count title lines, find widest */
195 i = titlewidth = 0;
196 titlelines = 1;
197 while (*hdgscan) {
198 if (*(hdgscan++) == '\n') {
199 ++titlelines;
200 i = -1;
201 }
202 if (++i > titlewidth)
203 titlewidth = i;
204 }
205 extralines = extrawidth = i = 0;
206 if ((hdgscan = extrainfo) != 0) {
207 if (*hdgscan == 0)
208 extrainfo = NULL;
209 else { /* count extra lines, find widest */
210 extralines = 3;
211 while (*hdgscan) {
212 if (*(hdgscan++) == '\n') {
213 if (extralines + numprompts + titlelines >= 20) {
214 *hdgscan = 0; /* full screen, cut off here */
215 break;
216 }
217 ++extralines;
218 i = -1;
219 }
220 if (++i > extrawidth)
221 extrawidth = i;
222 }
223 }
224 }
225
226 /* if entry fits in available space, shut off scrolling */
227 if(in_scrolling_mode && scroll_row_status == 0
228 && lines_in_entry == extralines - 2
229 && scroll_column_status == 0
230 && far_strchr(extrainfo, '\021') == NULL) {
231 in_scrolling_mode = 0;
232 fclose(scroll_file);
233 scroll_file = NULL;
234 }
235
236 /*initialize vertical scroll limit. When the top line of the text
237 box is the vertical scroll limit, the bottom line is the end of the
238 entry, and no further down scrolling is necessary.
239 */
240 if (in_scrolling_mode)
241 vertical_scroll_limit = lines_in_entry - (extralines - 2);
242
243 /* work out vertical positioning */
244 i = numprompts + titlelines + extralines + 3; /* total rows required */
245 j = (25 - i) / 2; /* top row of it all when centered */
246 j -= j / 4; /* higher is better if lots extra */
247 boxlines = numprompts;
248 titlerow = 1 + j;
249 promptrow = boxrow = titlerow + titlelines;
250 if (titlerow > 2) { /* room for blank between title & box? */
251 --titlerow;
252 --boxrow;
253 ++boxlines;
254 }
255 instrrow = boxrow+boxlines;
256 if (instrrow + 3 + extralines < 25) {
257 ++boxlines; /* blank at bottom of box */
258 ++instrrow;
259 if (instrrow + 3 + extralines < 25)
260 ++instrrow; /* blank before instructions */
261 }
262 extrarow = instrrow + 2;
263 if (numprompts > 1) /* 3 instructions lines */
264 ++extrarow;
265 if (extrarow + extralines < 25)
266 ++extrarow;
267
268 if(in_scrolling_mode) /* set box to max width if in scrolling mode */
269 extrawidth = 76;
270
271 /* work out horizontal positioning */
272 maxfldwidth = maxpromptwidth = maxcomment = anyinput = 0;
273 for (i = 0; i < numprompts; i++) {
274 if (values[i].type == 'y') {
275 static char *noyes[2] = {s_no,s_yes};
276 values[i].type = 'l';
277 values[i].uval.ch.vlen = 3;
278 values[i].uval.ch.list = noyes;
279 values[i].uval.ch.llen = 2;
280 }
281 j = far_strlen(prompts[i]);
282 if (values[i].type == '*') {
283 if (j > maxcomment) maxcomment = j;
284 }
285 else {
286 anyinput = 1;
287 if (j > maxpromptwidth) maxpromptwidth = j;
288 j = prompt_valuestring(buf,&values[i]);
289 if (j > maxfldwidth) maxfldwidth = j;
290 }
291 }
292 boxwidth = maxpromptwidth + maxfldwidth + 2;
293 if (maxcomment > boxwidth) boxwidth = maxcomment;
294 if ((boxwidth += 4) > 80) boxwidth = 80;
295 boxcol = (80 - boxwidth) / 2; /* center the box */
296 promptcol = boxcol + 2;
297 valuecol = boxcol + boxwidth - maxfldwidth - 2;
298 if (boxwidth <= 76) { /* make margin a bit wider if we can */
299 boxwidth += 2;
300 --boxcol;
301 }
302 if ((j = titlewidth) < extrawidth)
303 j = extrawidth;
304 if ((i = j + 4 - boxwidth) > 0) { /* expand box for title/extra */
305 if (boxwidth + i > 80)
306 i = 80 - boxwidth;
307 boxwidth += i;
308 boxcol -= i / 2;
309 }
310 i = (90 - boxwidth) / 20;
311 boxcol -= i;
312 promptcol -= i;
313 valuecol -= i;
314
315 /* display box heading */
316 for (i = titlerow; i < boxrow; ++i)
317 setattr(i,boxcol,C_PROMPT_HI,boxwidth);
318 {
319 char far *hdgline = hdg;
320 /* center each line of heading independently */
321 int i;
322 for(i=0;i<titlelines-1;i++)
323 {
324 char far *next;
325 if((next = far_strchr(hdgline,'\n')) == NULL)
326 break; /* shouldn't happen */
327 *next = '\0';
328 titlewidth = far_strlen(hdgline);
329 textcbase = boxcol + (boxwidth - titlewidth) / 2;
330 putstring(titlerow+i,0,C_PROMPT_HI,hdgline);
331 *next = '\n';
332 hdgline = next+1;
333 }
334 /* add scrolling key message, if applicable */
335 if(in_scrolling_mode) {
336 *(hdgline + 31) = (char) 0; /* replace the ')' */
337 far_strcat(hdgline, ". CTRL+(direction key) to scroll text.)");
338 }
339
340 titlewidth = far_strlen(hdgline);
341 textcbase = boxcol + (boxwidth - titlewidth) / 2;
342 putstring(titlerow+i,0,C_PROMPT_HI,hdgline);
343 }
344
345 /* display extra info */
346 if (extrainfo) {
347 #ifndef XFRACT
348 #define S1 '\xC4'
349 #define S2 "\xC0"
350 #define S3 "\xD9"
351 #define S4 "\xB3"
352 #define S5 "\xDA"
353 #define S6 "\xBF"
354 #else
355 #define S1 '-'
356 #define S2 "+" /* ll corner */
357 #define S3 "+" /* lr corner */
358 #define S4 "|"
359 #define S5 "+" /* ul corner */
360 #define S6 "+" /* ur corner */ 361 #endif
362 memset(buf,S1,80); buf[boxwidth-2] = 0;
363 textcbase = boxcol + 1;
364 putstring(extrarow,0,C_PROMPT_BKGRD,buf);
365 putstring(extrarow+extralines-1,0,C_PROMPT_BKGRD,buf);
366 --textcbase;
367 putstring(extrarow,0,C_PROMPT_BKGRD,S5);
368 putstring(extrarow+extralines-1,0,C_PROMPT_BKGRD,S2);
369 textcbase += boxwidth - 1;
370 putstring(extrarow,0,C_PROMPT_BKGRD,S6);
371 putstring(extrarow+extralines-1,0,C_PROMPT_BKGRD,S3);
372
373 textcbase = boxcol;
374
375 for (i = 1; i < extralines-1; ++i) {
376 putstring(extrarow+i,0,C_PROMPT_BKGRD,S4);
377 putstring(extrarow+i,boxwidth-1,C_PROMPT_BKGRD,S4);
378 }
379 textcbase += (boxwidth - extrawidth) / 2;
380 putstring(extrarow+1,0,C_PROMPT_TEXT,extrainfo);
381 }
382
383 textcbase = 0;
384
385 /* display empty box */
386 for (i = 0; i < boxlines; ++i)
387 setattr(boxrow+i,boxcol,C_PROMPT_LO,boxwidth);
388
389 /* display initial values */
390 for (i = 0; i < numprompts; i++) {
391 putstring(promptrow+i, promptcol, C_PROMPT_LO, prompts[i]);
392 prompt_valuestring(buf,&values[i]);
393 putstring(promptrow+i, valuecol, C_PROMPT_LO, buf);
394 }
395
396
397 if (!anyinput) {
398 putstringcenter(instrrow++,0,80,C_PROMPT_BKGRD,
399 instr0);
400 putstringcenter(instrrow,0,80,C_PROMPT_BKGRD,
401 (helpmode > 0) ? instr0b : instr0a);
402 movecursor(25,80);
403 textcbase = 2;
404 for(;;) {
405 if(rewrite_extrainfo) {
406 rewrite_extrainfo = 0;
407 fseek(scroll_file, scroll_file_start, SEEK_SET);
408 load_entry_text(scroll_file, extrainfo, extralines - 2,
409 scroll_row_status, scroll_column_status);
410 for(i=1; i <= extralines - 2; i++)
411 putstring(extrarow+i,0,C_PROMPT_TEXT,blanks);
412 putstring(extrarow+1,0,C_PROMPT_TEXT,extrainfo);
413 }
414 while (!keypressed()) { }
415 done = getakey();
416 switch(done) {
417 case ESC:
418 done = -1;
419 case ENTER:
420 case ENTER_2:
421 goto fullscreen_exit;
422 case DOWN_ARROW_2: /* scrolling key - down one row */
423 if(in_scrolling_mode && scroll_row_status < vertical_scroll_limit) {
424 scroll_row_status++;
425 rewrite_extrainfo = 1;
426 }
427 break;
428 case UP_ARROW_2: /* scrolling key - up one row */
429 if(in_scrolling_mode && scroll_row_status > 0) {
430 scroll_row_status--;
431 rewrite_extrainfo = 1;
432 }
433 break;
434 case LEFT_ARROW_2: /* scrolling key - left one column */
435 if(in_scrolling_mode && scroll_column_status > 0) {
436 scroll_column_status--;
437 rewrite_extrainfo = 1;
438 }
439 break;
440 case RIGHT_ARROW_2: /* scrolling key - right one column */
441 if(in_scrolling_mode && far_strchr(extrainfo, '\021') != NULL) {
442 scroll_column_status++;
443 rewrite_extrainfo = 1;
444 }
445 break;
446 case CTL_PAGE_DOWN: /* scrolling key - down one screen */
447 if(in_scrolling_mode && scroll_row_status < vertical_scroll_limit) {
448 scroll_row_status += extralines - 2;
449 if(scroll_row_status > vertical_scroll_limit)
450 scroll_row_status = vertical_scroll_limit;
451 rewrite_extrainfo = 1;
452 }
453 break;
454 case CTL_PAGE_UP: /* scrolling key - up one screen */
455 if(in_scrolling_mode && scroll_row_status > 0) {
456 scroll_row_status -= extralines - 2;
457 if(scroll_row_status < 0)
458 scroll_row_status = 0;
459 rewrite_extrainfo = 1;
460 }
461 break;
462 case CTL_END: /* scrolling key - to end of entry */
463 if(in_scrolling_mode) {
464 scroll_row_status = vertical_scroll_limit;
465 scroll_column_status = 0;
466 rewrite_extrainfo = 1;
467 }
468 break;
469 case CTL_HOME: /* scrolling key - to beginning of entry */
470 if(in_scrolling_mode) {
471 scroll_row_status = scroll_column_status = 0;
472 rewrite_extrainfo = 1;
473 }
474 break;
475 case F2:
476 case F3:
477 case F4:
478 case F5:
479 case F6:
480 case F7:
481 case F8:
482 case F9:
483 case F10:
484 if (promptfkeys & (1<<(done+1-F1)) )
485 goto fullscreen_exit;
486 }
487 }
488 }
489
490
491 /* display footing */
492 if (numprompts > 1)
493 putstringcenter(instrrow++,0,80,C_PROMPT_BKGRD,instr1);
494 putstringcenter(instrrow+1,0,80,C_PROMPT_BKGRD,
495 (helpmode > 0) ? instr3b : instr3a);
496
497 done = 0;
498 while (values[curchoice].type == '*') ++curchoice;
499
500 while (!done) {
501 if(rewrite_extrainfo) {
502 j = textcbase;
503 textcbase = 2;
504 fseek(scroll_file, scroll_file_start, SEEK_SET);
505 load_entry_text(scroll_file, extrainfo, extralines - 2,
506 scroll_row_status, scroll_column_status);
507 for(i=1; i <= extralines - 2; i++)
508 putstring(extrarow+i,0,C_PROMPT_TEXT,blanks);
509 putstring(extrarow+1,0,C_PROMPT_TEXT,extrainfo);
510 textcbase = j;
511 }
512
513 curtype = values[curchoice].type;
514 curlen = prompt_valuestring(buf,&values[curchoice]);
515 if(!rewrite_extrainfo)
516 putstringcenter(instrrow,0,80,C_PROMPT_BKGRD,
517 (curtype == 'l') ? instr2b : instr2a);
518 else
519 rewrite_extrainfo = 0;
520 putstring(promptrow+curchoice,promptcol,C_PROMPT_HI,prompts[curchoice]);
521
522 if (curtype == 'l') {
523 i = input_field_list(
524 C_PROMPT_CHOOSE, buf, curlen,
525 values[curchoice].uval.ch.list, values[curchoice].uval.ch.llen,
526 promptrow+curchoice,valuecol, in_scrolling_mode ? prompt_checkkey_scroll : prompt_checkkey);
527 for (j = 0; j < values[curchoice].uval.ch.llen; ++j)
528 if (strcmp(buf,values[curchoice].uval.ch.list[j]) == 0) break;
529 values[curchoice].uval.ch.val = j;
530 }
531 else {
532 j = 0;
533 if (curtype == 'i') j = 3;
534 if (curtype == 'L') j = 3;
535 if (curtype == 'd') j = 5;
536 if (curtype == 'D') j = 7;
537 if (curtype == 'f') j = 1;
538 i = input_field(j, C_PROMPT_INPUT, buf, curlen,
539 promptrow+curchoice,valuecol, in_scrolling_mode ? prompt_checkkey_scroll : prompt_checkkey);
540 switch (values[curchoice].type) {
541 case 'd':
542 case 'D':
543 values[curchoice].uval.dval = atof(buf);
544 break;
545 case 'f':
546 values[curchoice].uval.dval = atof(buf);
547 roundfloatd(&values[curchoice].uval.dval);
548 break;
549 case 'i':
550 values[curchoice].uval.ival = atoi(buf);
551 break;
552 case 'L':
553 values[curchoice].uval.Lval = atol(buf);
554 break;
555 case 's':
556 strncpy(values[curchoice].uval.sval,buf,16);
557 break;
558 default: /* assume 0x100+n */
559 far_strcpy(values[curchoice].uval.sbuf,buf);
560 }
561 }
562
563 putstring(promptrow+curchoice,promptcol,C_PROMPT_LO,prompts[curchoice]);
564 j = strlen(buf);
565 memset(&buf[j],' ',80-j); buf[curlen] = 0;
566 putstring(promptrow+curchoice, valuecol, C_PROMPT_LO, buf);
567
568 switch(i) {
569 case 0: /* enter */
570 done = 13;
571 break;
572 case -1: /* escape */
573 case F2:
574 case F3:
575 case F4:
576 case F5:
577 case F6:
578 case F7:
579 case F8:
580 case F9:
581 case F10:
582 done = i;
583 break;
584 case PAGE_UP:
585 curchoice = -1;
586 case DOWN_ARROW:
587 do {
588 if (++curchoice >= numprompts) curchoice = 0;
589 } while (values[curchoice].type == '*');
590 break;
591 case PAGE_DOWN:
592 curchoice = numprompts;
593 case UP_ARROW:
594 do {
595 if (--curchoice < 0) curchoice = numprompts - 1;
596 } while (values[curchoice].type == '*');
597 break;
598 case DOWN_ARROW_2: /* scrolling key - down one row */
599 if(in_scrolling_mode && scroll_row_status < vertical_scroll_limit) {
600 scroll_row_status++;
601 rewrite_extrainfo = 1;
602 }
603 break;
604 case UP_ARROW_2: /* scrolling key - up one row */
605 if(in_scrolling_mode && scroll_row_status > 0) {
606 scroll_row_status--;
607 rewrite_extrainfo = 1;
608 }
609 break;
610 case LEFT_ARROW_2: /*scrolling key - left one column */
611 if(in_scrolling_mode && scroll_column_status > 0) {
612 scroll_column_status--;
613 rewrite_extrainfo = 1;
614 }
615 break;
616 case RIGHT_ARROW_2: /* scrolling key - right one column */
617 if(in_scrolling_mode && far_strchr(extrainfo, '\021') != NULL) {
618 scroll_column_status++;
619 rewrite_extrainfo = 1;
620 }
621 break;
622 case CTL_PAGE_DOWN: /* scrolling key - down on screen */
623 if(in_scrolling_mode && scroll_row_status < vertical_scroll_limit) {
624 scroll_row_status += extralines - 2;
625 if(scroll_row_status > vertical_scroll_limit)
626 scroll_row_status = vertical_scroll_limit;
627 rewrite_extrainfo = 1;
628 }
629 break;
630 case CTL_PAGE_UP: /* scrolling key - up one screen */
631 if(in_scrolling_mode && scroll_row_status > 0) {
632 scroll_row_status -= extralines - 2;
633 if(scroll_row_status < 0)
634 scroll_row_status = 0;
635 rewrite_extrainfo = 1;
636 }
637 break;
638 case CTL_END: /* scrolling key - go to end of entry */
639 if(in_scrolling_mode) {
640 scroll_row_status = vertical_scroll_limit;
641 scroll_column_status = 0;
642 rewrite_extrainfo = 1;
643 }
644 break;
645 case CTL_HOME: /* scrolling key - go to beginning of entry */
646 if(in_scrolling_mode) {
647 scroll_row_status = scroll_column_status = 0;
648 rewrite_extrainfo = 1;
649 }
650 break;
651 }
652 }
653
654 fullscreen_exit:
655 movecursor(25,80);
656 lookatmouse = savelookatmouse;
657 if(scroll_file) {
658 fclose(scroll_file);
659 scroll_file = NULL;
660 }
661 return(done);
662 }
663
664 int prompt_valuestring(char *buf,struct fullscreenvalues *val)
665 { /* format value into buf, return field width */
666 int i,ret;
667 switch (val->type) {
668 case 'd':
669 ret = 20;
670 i = 16; /* cellular needs 16 (was 15)*/
671 for(;;) {
672 sprintf(buf,"%.*g",i,val->uval.dval);
673 if ((int)strlen(buf) <= ret) break;
674 --i;
675 }
676 break;
677 case 'D':
678 if (val->uval.dval<0) { /* We have to round the right way */
679 sprintf(buf,"%ld",(long)(val->uval.dval-.5));
680 }
681 else {
682 sprintf(buf,"%ld",(long)(val->uval.dval+.5));
683 }
684 ret = 20;
685 break;
686 case 'f':
687 sprintf(buf,"%.7g",val->uval.dval);
688 ret = 14;
689 break;
690 case 'i':
691 sprintf(buf,"%d",val->uval.ival);
692 ret = 6;
693 break;
694 case 'L':
695 sprintf(buf,"%ld",val->uval.Lval);
696 ret = 10;
697 break;
698 case '*':
699 *buf = (char)(ret = 0);
700 break;
701 case 's':
702 strncpy(buf,val->uval.sval,16);
703 buf[15] = 0;
704 ret = 15;
705 break;
706 case 'l':
707 strcpy(buf,val->uval.ch.list[val->uval.ch.val]);
708 ret = val->uval.ch.vlen;
709 break;
710 default: /* assume 0x100+n */
711 far_strcpy(buf,val->uval.sbuf);
712 ret = val->type & 0xff;
713 }
714 return ret;
715 }
716
717 int prompt_checkkey(int curkey)
718 {
719 switch(curkey) {
720 case PAGE_UP:
721 case DOWN_ARROW:
722 case PAGE_DOWN:
723 case UP_ARROW:
724 return(curkey);
725 case F2:
726 case F3:
727 case F4:
728 case F5:
729 case F6:
730 case F7:
731 case F8:
732 case F9:
733 case F10:
734 if (promptfkeys & (1<<(curkey+1-F1)) )
735 return(curkey);
736 }
737 return(0);
738 }
739
740 int prompt_checkkey_scroll(int curkey)
741 {
742 switch(curkey) {
743 case PAGE_UP:
744 case DOWN_ARROW:
745 case DOWN_ARROW_2:
746 case PAGE_DOWN:
747 case UP_ARROW:
748 case UP_ARROW_2:
749 case LEFT_ARROW_2:
750 case RIGHT_ARROW_2:
751 case CTL_PAGE_DOWN:
752 case CTL_PAGE_UP:
753 case CTL_END:
754 case CTL_HOME:
755 return(curkey);
756 case F2:
757 case F3:
758 case F4:
759 case F5:
760 case F6:
761 case F7:
762 case F8:
763 case F9:
764 case F10:
765 if (promptfkeys & (1<<(curkey+1-F1)) )
766 return(curkey);
767 }
768 return(0);
769 }
770
771 static int input_field_list(
772 int attr, /* display attribute */
773 char *fld, /* display form field value */
774 int vlen, /* field length */
775 char **list, /* list of values */
776 int llen, /* number of entries in list */
777 int row, /* display row */
778 int col, /* display column */
779 int (*checkkey)(int) /* routine to check non data keys, or NULL */
780 )
781 {
782 int initval,curval;
783 char buf[81];
784 int curkey;
785 int i, j;
786 int ret,savelookatmouse;
787 savelookatmouse = lookatmouse;
788 lookatmouse = 0;
789 for (initval = 0; initval < llen; ++initval)
790 if (strcmp(fld,list[initval]) == 0) break;
791 if (initval >= llen) initval = 0;
792 curval = initval;
793 ret = -1;
794 for(;;) {
795 strcpy(buf,list[curval]);
796 i = strlen(buf);
797 while (i < vlen)
798 buf[i++] = ' ';
799 buf[vlen] = 0;
800 putstring(row,col,attr,buf);
801 curkey = keycursor(row,col); /* get a keystroke */
802 switch (curkey) {
803 case ENTER:
804 case ENTER_2:
805 ret = 0;
806 goto inpfldl_end;
807 case ESC:
808 goto inpfldl_end;
809 case RIGHT_ARROW:
810 if (++curval >= llen)
811 curval = 0;
812 break;
813 case LEFT_ARROW:
814 if (--curval < 0)
815 curval = llen - 1;
816 break;
817 case F5:
818 curval = initval;
819 break;
820 default:
821 if (nonalpha(curkey)) {
822 if (checkkey && (ret = (*checkkey)(curkey)) != 0)
823 goto inpfldl_end;
824 break; /* non alphanum char */
825 }
826 j = curval;
827 for (i = 0; i < llen; ++i) {
828 if (++j >= llen)
829 j = 0;
830 if ( (*list[j] & 0xdf) == (curkey & 0xdf)) {
831 curval = j;
832 break;
833 }
834 }
835 }
836 }
837 inpfldl_end:
838 strcpy(fld,list[curval]);
839 lookatmouse = savelookatmouse;
840 return(ret);
841 }
842
843
844 /* --------------------------------------------------------------------- */
845
846 /* MCP 7-7-91, This is static code, but not called anywhere */
847 #ifdef DELETE_UNUSED_CODE
865 #endif
866
867 /* --------------------------------------------------------------------- */
868
869 int get_fracttype() /* prompt for and select fractal type */
870 {
871 int done,i,oldfractype,t;
872 done = -1;
873 oldfractype = fractype;
874 for(;;) {
875 if ((t = select_fracttype(fractype)) < 0)
876 break;
877 if ((i = select_type_params(t, fractype)) == 0) { /* ok, all done */
878 done = 0;
879 break;
880 }
881 if (i > 0) /* can't return to prior image anymore */
882 done = 1;
883 }
884 if (done < 0)
885 fractype = oldfractype;
886 curfractalspecific = &fractalspecific[fractype];
887 return(done);
888 }
889
890 struct FT_CHOICE {
891 char name[15];
892 int num;
893 };
894 static struct FT_CHOICE far **ft_choices; /* for sel_fractype_help subrtn */
895
896 static int select_fracttype(int t) /* subrtn of get_fracttype, separated */
897 /* so that storage gets freed up */
898 {
899 static FCODE head1[] = {"Select a Fractal Type"};
900 static FCODE head2[] = {"Select Orbit Algorithm for Julibrot"};
901 static FCODE o_instr[] = {"Press "FK_F2" for a description of the highlighted type"};
902 char instr[sizeof(o_instr)];
903 char head[40];
904 int oldhelpmode;
905 int numtypes, done;
906 int i, j;
907 #define MAXFTYPES 200
908 char tname[40];
909 struct FT_CHOICE far *choices[MAXFTYPES];
910 int attributes[MAXFTYPES];
911
912 /* steal existing array for "choices" */
913 choices[0] = (struct FT_CHOICE far *)boxy;
914 attributes[0] = 1;
915 for (i = 1; i < MAXFTYPES; ++i) {
916 choices[i] = choices[i-1] + 1;
917 attributes[i] = 1;
918 }
919 ft_choices = &choices[0];
920
921 /* setup context sensitive help */
922 oldhelpmode = helpmode;
923 helpmode = HELPFRACTALS;
924 far_strcpy(instr,o_instr);
925 if(julibrot)
926 far_strcpy(head,head2);
927 else
928 far_strcpy(head,head1);
929 if (t == IFS3D) t = IFS;
930 i = j = -1;
931 while(fractalspecific[++i].name) {
932 if(julibrot)
933 if (!((fractalspecific[i].flags & OKJB) && *fractalspecific[i].name != '*'))
934 continue;
935 if (fractalspecific[i].name[0] == '*')
936 continue;
937 far_strcpy(choices[++j]->name,fractalspecific[i].name);
938 choices[j]->name[14] = 0; /* safety */
939 choices[j]->num = i; /* remember where the real item is */
940 }
941 numtypes = j + 1;
942 shell_sort(choices,numtypes,sizeof(char far *),lccompare); /* sort list */
943 j = 0;
944 for (i = 0; i < numtypes; ++i) /* find starting choice in sorted list */
945 if (choices[i]->num == t || choices[i]->num == fractalspecific[t].tofloat)
946 j = i;
947
948 tname[0] = 0;
949 done = fullscreen_choice(CHOICEHELP+8,head,NULL,instr,numtypes,
950 (char far *far*)choices,attributes,0,0,0,j,NULL,tname,NULL,sel_fractype_help);
951 if (done >= 0) {
952 done = choices[done]->num;
953 if((done == FORMULA || done == FFORMULA) && !strcmp(FormFileName, CommandFile))
954 strcpy(FormFileName, searchfor.frm);
955 if(done == LSYSTEM && !strcmp(LFileName, CommandFile))
956 strcpy(LFileName, searchfor.lsys);
957 if((done == IFS || done == IFS3D) && !strcmp(IFSFileName, CommandFile))
958 strcpy(IFSFileName, searchfor.ifs);
959 }
960
961
962 helpmode = oldhelpmode;
963 return(done);
964 }
965
966 static int sel_fractype_help(int curkey,int choice)
967 {
968 int oldhelpmode;
969 if (curkey == F2) {
970 oldhelpmode = helpmode;
971 helpmode = fractalspecific[(*(ft_choices+choice))->num].helptext;
972 help(0);
973 helpmode = oldhelpmode;
974 }
975 return(0);
976 }
977
978 int select_type_params( /* prompt for new fractal type parameters */
979 int newfractype, /* new fractal type */
980 int oldfractype /* previous fractal type */
981 )
982 {
983 int ret,oldhelpmode;
984
985 oldhelpmode = helpmode;
986 sel_type_restart:
987 ret = 0;
988 fractype = newfractype;
989 curfractalspecific = &fractalspecific[fractype];
990
991 if (fractype == LSYSTEM) {
992 helpmode = HT_LSYS;
993 if (get_file_entry(GETLSYS,"L-System",lsysmask,LFileName,LName) < 0) {
994 ret = 1;
995 goto sel_type_exit;
996 }
997 }
998 if (fractype == FORMULA || fractype == FFORMULA) {
999 helpmode = HT_FORMULA;
1000 if (get_file_entry(GETFORMULA,"Formula",formmask,FormFileName,FormName) < 0) {
1001 ret = 1;
1002 goto sel_type_exit;
1003 }
1004 }
1005 if (fractype == IFS || fractype == IFS3D) {
1006 helpmode = HT_IFS;
1007 if (get_file_entry(GETIFS,"IFS",ifsmask,IFSFileName,IFSName) < 0) {
1008 ret = 1;
1009 goto sel_type_exit;
1010 }
1011 }
1012
1013 /* Added the following to accommodate fn bifurcations. JCO 7/2/92 */
1014 if(((fractype == BIFURCATION) || (fractype == LBIFURCATION)) &&
1015 !((oldfractype == BIFURCATION) || (oldfractype == LBIFURCATION)))
1016 set_trig_array(0,s_ident);
1017 if(((fractype == BIFSTEWART) || (fractype == LBIFSTEWART)) &&
1018 !((oldfractype == BIFSTEWART) || (oldfractype == LBIFSTEWART)))
1019 set_trig_array(0,s_ident);
1020 if(((fractype == BIFLAMBDA) || (fractype == LBIFLAMBDA)) &&
1021 !((oldfractype == BIFLAMBDA) || (oldfractype == LBIFLAMBDA)))
1022 set_trig_array(0,s_ident);
1023 if(((fractype == BIFEQSINPI) || (fractype == LBIFEQSINPI)) &&
1024 !((oldfractype == BIFEQSINPI) || (oldfractype == LBIFEQSINPI)))
1025 set_trig_array(0,s_sin);
1026 if(((fractype == BIFADSINPI) || (fractype == LBIFADSINPI)) &&
1027 !((oldfractype == BIFADSINPI) || (oldfractype == LBIFADSINPI)))
1028 set_trig_array(0,s_sin);
1029
1030 /*
1031 * Next assumes that user going between popcorn and popcornjul
1032 * might not want to change function variables
1033 */
1034 if(((fractype == FPPOPCORN ) || (fractype == LPOPCORN ) ||
1035 (fractype == FPPOPCORNJUL) || (fractype == LPOPCORNJUL)) &&
1036 !((oldfractype == FPPOPCORN ) || (oldfractype == LPOPCORN ) ||
1037 (oldfractype == FPPOPCORNJUL) || (oldfractype == LPOPCORNJUL)))
1038 set_function_parm_defaults();
1039
1040 /* set LATOO function defaults */
1041 if(fractype == LATOO && oldfractype != LATOO)
1042 {
1043 set_function_parm_defaults();
1044 }
1045 set_default_parms();
1046
1047 if (get_fract_params(0) < 0)
1048 if (fractype == FORMULA || fractype == FFORMULA ||
1049 fractype == IFS || fractype == IFS3D ||
1050 fractype == LSYSTEM)
1051 goto sel_type_restart;
1052 else
1053 ret = 1;
1054 else {
1055 if (newfractype != oldfractype) {
1056 invert = 0;
1057 inversion[0] = inversion[1] = inversion[2] = 0;
1058 }
1059 }
1060
1061 sel_type_exit:
1062 helpmode = oldhelpmode;
1063 return(ret);
1064
1065 }
1066
1067 void set_default_parms()
1068 {
1069 int i,extra;
1070 xxmin = curfractalspecific->xmin;
1071 xxmax = curfractalspecific->xmax;
1072 yymin = curfractalspecific->ymin;
1073 yymax = curfractalspecific->ymax;
1074 xx3rd = xxmin;
1075 yy3rd = yymin;
1076
1077 if (viewcrop && finalaspectratio != screenaspect)
1078 aspectratio_crop(screenaspect,finalaspectratio);
1079 for (i = 0; i < 4; i++) {
1080 param[i] = curfractalspecific->paramvalue[i];
1081 if (fractype != CELLULAR && fractype != FROTH && fractype != FROTHFP &&
1082 fractype != ANT)
1083 roundfloatd(¶m[i]); /* don't round cellular, frothybasin or ant */
1084 }
1085 if((extra=find_extra_param(fractype)) > -1)
1086 for(i=0;i<MAXPARAMS-4;i++)
1087 param[i+4] = moreparams[extra].paramvalue[i];
1088 if(debugflag != 3200)
1089 bf_math = 0;
1090 else if(bf_math)
1091 fractal_floattobf();
1092 }
1093
1094 #define MAXFRACTALS 25
1095
1096 int build_fractal_list(int fractals[], int *last_val, char *nameptr[])
1097 {
1098 int numfractals,i;
1099
1100 numfractals = 0;
1101 for (i = 0; i < num_fractal_types; i++)
1102 {
1103 if ((fractalspecific[i].flags & OKJB) && *fractalspecific[i].name != '*')
1104 {
1105 fractals[numfractals] = i;
1106 if (i == neworbittype || i == fractalspecific[neworbittype].tofloat)
1107 *last_val = numfractals;
1108 nameptr[numfractals] = fractalspecific[i].name;
1109 numfractals++;
1110 if (numfractals >= MAXFRACTALS)
1111 break;
1112 }
1113 }
1114 return (numfractals);
1115 }
1116
1117 static FCODE v0a[] = {"From cx (real part)"};
1118 static FCODE v1a[] = {"From cy (imaginary part)"};
1119 static FCODE v2a[] = {"To cx (real part)"};
1120 static FCODE v3a[] = {"To cy (imaginary part)"};
1121
1122 /* 4D Mandelbrot */
1123 static FCODE v0b[] = {"From cj (3rd dim)"};
1124 static FCODE v1b[] = {"From ck (4th dim)"};
1125 static FCODE v2b[] = {"To cj (3rd dim)"};
1126 static FCODE v3b[] = {"To ck (4th dim)"};
1127
1128 /* 4D Julia */
1129 static FCODE v0c[] = {"From zj (3rd dim)"};
1130 static FCODE v1c[] = {"From zk (4th dim)"};
1131 static FCODE v2c[] = {"To zj (3rd dim)"};
1132 static FCODE v3c[] = {"To zk (4th dim)"};
1133
1134 static FCODE v4[] = {"Number of z pixels"};
1135 static FCODE v5[] = {"Location of z origin"};
1136 static FCODE v6[] = {"Depth of z"};
1137 static FCODE v7[] = {"Screen height"};
1138 static FCODE v8[] = {"Screen width"};
1139 static FCODE v9[] = {"Distance to Screen"};
1140 static FCODE v10[] = {"Distance between eyes"};
1141 static FCODE v11[] = {"3D Mode"};
1142 char *juli3Doptions[] = {"monocular","lefteye","righteye","red-blue"};
1143
1144 /* JIIM */
1145 #ifdef RANDOM_RUN
1146 static FCODE JIIMstr1[] = "Breadth first, Depth first, Random Walk, Random Run?";
1147 char *JIIMmethod[] = {"breadth", "depth", "walk", "run"}; 1148 #else
1149 static FCODE JIIMstr1[] = "Breadth first, Depth first, Random Walk";
1150 char *JIIMmethod[] = {"breadth", "depth", "walk"};
1151 #endif
1152 static FCODE JIIMstr2[] = "Left first or Right first?";
1153 char *JIIMleftright[] = {"left", "right"};
1154
1155 /* moved from miscres.c so sizeof structure can be accessed here */
1156 struct trig_funct_lst trigfn[] =
1157 /* changing the order of these alters meaning of *.fra file */
1158 /* maximum 6 characters in function names or recheck all related code */
1159 {
1160 #ifndef XFRACT
1161 {s_sin, lStkSin, dStkSin, mStkSin },
1162 {s_cosxx, lStkCosXX, dStkCosXX, mStkCosXX },
1163 {s_sinh, lStkSinh, dStkSinh, mStkSinh },
1164 {s_cosh, lStkCosh, dStkCosh, mStkCosh },
1165 {s_exp, lStkExp, dStkExp, mStkExp },
1166 {s_log, lStkLog, dStkLog, mStkLog },
1167 {s_sqr, lStkSqr, dStkSqr, mStkSqr },
1168 {s_recip, lStkRecip, dStkRecip, mStkRecip }, /* from recip on new in v16 */
1169 {s_ident, StkIdent, StkIdent, StkIdent },
1170 {s_cos, lStkCos, dStkCos, mStkCos },
1171 {s_tan, lStkTan, dStkTan, mStkTan },
1172 {s_tanh, lStkTanh, dStkTanh, mStkTanh },
1173 {s_cotan, lStkCoTan, dStkCoTan, mStkCoTan },
1174 {s_cotanh,lStkCoTanh,dStkCoTanh,mStkCoTanh},
1175 {s_flip, lStkFlip, dStkFlip, mStkFlip },
1176 {s_conj, lStkConj, dStkConj, mStkConj },
1177 {s_zero, lStkZero, dStkZero, mStkZero },
1178 {s_asin, lStkASin, dStkASin, mStkASin },
1179 {s_asinh, lStkASinh, dStkASinh, mStkASinh },
1180 {s_acos, lStkACos, dStkACos, mStkACos },
1181 {s_acosh, lStkACosh, dStkACosh, mStkACosh },
1182 {s_atan, lStkATan, dStkATan, mStkATan },
1183 {s_atanh, lStkATanh, dStkATanh, mStkATanh },
1184 {s_cabs, lStkCAbs, dStkCAbs, mStkCAbs },
1185 {s_abs, lStkAbs, dStkAbs, mStkAbs },
1186 {s_sqrt, lStkSqrt, dStkSqrt, mStkSqrt },
1187 {s_floor, lStkFloor, dStkFloor, mStkFloor },
1188 {s_ceil, lStkCeil, dStkCeil, mStkCeil },
1189 {s_trunc, lStkTrunc, dStkTrunc, mStkTrunc },
1190 {s_round, lStkRound, dStkRound, mStkRound },
1191 {s_one, lStkOne, dStkOne, mStkOne },
1192 #else
1193 {s_sin, dStkSin, dStkSin, dStkSin },
1194 {s_cosxx, dStkCosXX, dStkCosXX, dStkCosXX },
1195 {s_sinh, dStkSinh, dStkSinh, dStkSinh },
1196 {s_cosh, dStkCosh, dStkCosh, dStkCosh },
1197 {s_exp, dStkExp, dStkExp, dStkExp },
1198 {s_log, dStkLog, dStkLog, dStkLog },
1199 {s_sqr, dStkSqr, dStkSqr, dStkSqr },
1200 {s_recip, dStkRecip, dStkRecip, dStkRecip }, /* from recip on new in v16 */
1201 {s_ident, StkIdent, StkIdent, StkIdent },
1202 {s_cos, dStkCos, dStkCos, dStkCos },
1203 {s_tan, dStkTan, dStkTan, dStkTan },
1204 {s_tanh, dStkTanh, dStkTanh, dStkTanh },
1205 {s_cotan, dStkCoTan, dStkCoTan, dStkCoTan },
1206 {s_cotanh,dStkCoTanh,dStkCoTanh,dStkCoTanh},
1207 {s_flip, dStkFlip, dStkFlip, dStkFlip },
1208 {s_conj, dStkConj, dStkConj, dStkConj },
1209 {s_zero, dStkZero, dStkZero, dStkZero },
1210 {s_asin, dStkASin, dStkASin, dStkASin },
1211 {s_asinh, dStkASinh, dStkASinh, dStkASinh },
1212 {s_acos, dStkACos, dStkACos, dStkACos },
1213 {s_acosh, dStkACosh, dStkACosh, dStkACosh },
1214 {s_atan, dStkATan, dStkATan, dStkATan },
1215 {s_atanh, dStkATanh, dStkATanh, dStkATanh },
1216 {s_cabs, dStkCAbs, dStkCAbs, dStkCAbs },
1217 {s_abs, dStkAbs, dStkAbs, dStkAbs },
1218 {s_sqrt, dStkSqrt, dStkSqrt, dStkSqrt },
1219 {s_floor, dStkFloor, dStkFloor, dStkFloor },
1220 {s_ceil, dStkCeil, dStkCeil, dStkCeil },
1221 {s_trunc, dStkTrunc, dStkTrunc, dStkTrunc },
1222 {s_round, dStkRound, dStkRound, dStkRound },
1223 {s_one, dStkOne, dStkOne, dStkOne }, 1224 #endif
1225 };
1226
1227 #define NUMTRIGFN sizeof(trigfn)/sizeof(struct trig_funct_lst)
1228
1229 const int numtrigfn = NUMTRIGFN;
1230
1231 /* --------------------------------------------------------------------- */
1232 int get_fract_params(int caller) /* prompt for type-specific parms */
1233 {
1234 char far *v0 = v0a;
1235 char far *v1 = v1a;
1236 char far *v2 = v2a;
1237 char far *v3 = v3a;
1238 char *juliorbitname = NULL;
1239 int i,j,k;
1240 int curtype,numparams,numtrig;
1241 struct fullscreenvalues paramvalues[30];
1242 char far *choices[30];
1243 long oldbailout = 0L;
1244 int promptnum;
1245 char msg[120];
1246 char *typename, *tmpptr;
1247 char bailoutmsg[50];
1248 int ret = 0;
1249 int oldhelpmode;
1250 char parmprompt[MAXPARAMS][55];
1251 static FCODE t1[] = {"First Function"};
1252 static FCODE t2[] = {"Second Function"};
1253 static FCODE t3[] = {"Third Function"};
1254 static FCODE t4[] = {"Fourth Function"};
1255 static FCODE *trg[] = {t1, t2, t3, t4};
1256 char *filename,*entryname;
1257 FILE *entryfile;
1258 char *trignameptr[NUMTRIGFN];
1259 #ifdef XFRACT
1260 static /* Can't initialize aggregates on the stack */ 1261 #endif
1262 char *bailnameptr[] = {s_mod,s_real,s_imag,s_or,s_and,s_manh,s_manr};
1263 struct fractalspecificstuff far *jborbit = NULL;
1264 struct fractalspecificstuff far *savespecific;
1265 int firstparm = 0;
1266 int lastparm = MAXPARAMS;
1267 double oldparam[MAXPARAMS];
1268 int fkeymask = 0x40;
1269 oldbailout = bailout;
1270 if(fractype==JULIBROT || fractype==JULIBROTFP)
1271 julibrot = 1;
1272 else
1273 julibrot = 0;
1274 curtype = fractype;
1275 if (curfractalspecific->name[0] == '*'
1276 && (i = curfractalspecific->tofloat) != NOFRACTAL /* FIXED BUG HERE!! */
1277 && fractalspecific[i].name[0] != '*')
1278 curtype = i;
1279 curfractalspecific = &fractalspecific[curtype];
1280 tstack[0] = 0;
1281 if ((i = curfractalspecific->helpformula) < -1) {
1282 if (i == -2) { /* special for formula */
1283 filename = FormFileName;
1284 entryname = FormName;
1285 }
1286 else if (i == -3) { /* special for lsystem */
1287 filename = LFileName;
1288 entryname = LName;
1289 }
1290 else if (i == -4) { /* special for ifs */
1291 filename = IFSFileName;
1292 entryname = IFSName;
1293 }
1294 else { /* this shouldn't happen */
1295 filename = NULL;
1296 entryname = NULL;
1297 }
1298 if (find_file_item(filename,entryname,&entryfile, -1-i) == 0) {
1299 load_entry_text(entryfile,tstack,17, 0, 0);
1300 fclose(entryfile);
1301 if(fractype == FORMULA || fractype == FFORMULA)
1302 frm_get_param_stuff(entryname); /* no error check, should be okay, from above */
1303 }
1304 }
1305 else if (i >= 0) {
1306 int c,lines;
1307 read_help_topic(i,0,2000,tstack); /* need error handling here ?? */
1308 tstack[2000-i] = 0;
1309 i = j = lines = 0; k = 1;
1310 while ((c = tstack[i++]) != 0) {
1311 /* stop at ctl, blank, or line with col 1 nonblank, max 16 lines */
1312 if (k && c == ' ' && ++k <= 5) { } /* skip 4 blanks at start of line */
1313 else {
1314 if (c == '\n') {
1315 if (k) break; /* blank line */
1316 if (++lines >= 16) break;
1317 k = 1;
1318 }
1319 else if (c < 16) /* a special help format control char */
1320 break;
1321 else {
1322 if (k == 1) /* line starts in column 1 */
1323 break;
1324 k = 0;
1325 }
1326 tstack[j++] = (char)c;
1327 }
1328 }
1329 while (--j >= 0 && tstack[j] == '\n') { }
1330 tstack[j+1] = 0;
1331 }
1332 gfp_top:
1333 promptnum = 0;
1334 if (julibrot)
1335 {
1336 i = select_fracttype(neworbittype);
1337 if (i < 0)
1338 {
1339 if (ret == 0)
1340 ret = -1;
1341 julibrot = 0;
1342 goto gfp_exit;
1343 }
1344 else
1345 neworbittype = i;
1346 jborbit = &fractalspecific[neworbittype];
1347 juliorbitname = jborbit->name;
1348 }
1349
1350 if(fractype == FORMULA || fractype == FFORMULA) {
1351 if(uses_p1) /* set first parameter */
1352 firstparm = 0;
1353 else if(uses_p2)
1354 firstparm = 2;
1355 else if(uses_p3)
1356 firstparm = 4;
1357 else if(uses_p4)
1358 firstparm = 6;
1359 else
1360 firstparm = 8; /* uses_p5 or no parameter */
1361
1362 if(uses_p5) /* set last parameter */
1363 lastparm = 10;
1364 else if(uses_p4)
1365 lastparm = 8;
1366 else if(uses_p3)
1367 lastparm = 6;
1368 else if(uses_p2)
1369 lastparm = 4;
1370 else
1371 lastparm = 2; /* uses_p1 or no parameter */
1372 }
1373
1374 savespecific = curfractalspecific;
1375 if(julibrot)
1376 {
1377 curfractalspecific = jborbit;
1378 firstparm = 2; /* in most case Julibrot does not need first two parms */
1379 if(neworbittype == QUATJULFP || /* all parameters needed */
1380 neworbittype == HYPERCMPLXJFP)
1381 {
1382 firstparm = 0;
1383 lastparm = 4;
1384 }
1385 if(neworbittype == QUATFP || /* no parameters needed */
1386 neworbittype == HYPERCMPLXFP)
1387 firstparm = 4;
1388 }
1389 numparams = 0;
1390 j = 0;
1391 for (i = firstparm; i < lastparm; i++)
1392 {
1393 char tmpbuf[30];
1394 if (!typehasparm(julibrot?neworbittype:fractype,i,parmprompt[j])) {
1395 if(curtype == FORMULA || curtype == FFORMULA)
1396 if(paramnotused(i))
1397 continue;
1398 break;
1399 }
1400 numparams++;
1401 choices[promptnum] = parmprompt[j++];
1402 paramvalues[promptnum].type = 'd';
1403
1404 if (choices[promptnum][0] == '+')
1405 {
1406 choices[promptnum]++;
1407 paramvalues[promptnum].type = 'D';
1408 }
1409 else if (choices[promptnum][0] == '#')
1410 choices[promptnum]++;
1411 sprintf(tmpbuf,"%.17g",param[i]);
1412 paramvalues[promptnum].uval.dval = atof(tmpbuf);
1413 oldparam[i] = paramvalues[promptnum++].uval.dval;
1414 }
1415
1416 /* The following is a goofy kludge to make reading in the formula
1417 * parameters work.
1418 */
1419 if(curtype == FORMULA || curtype == FFORMULA)
1420 numparams = lastparm - firstparm;
1421
1422 numtrig = (curfractalspecific->flags >> 6) & 7;
1423 if(curtype==FORMULA || curtype==FFORMULA ) {
1424 numtrig = maxfn;
1425 }
1426
1427 i = NUMTRIGFN;
1428 while (--i >= 0)
1429 trignameptr[i] = trigfn[i].name;
1430 for (i = 0; i < numtrig; i++) {
1431 paramvalues[promptnum].type = 'l';
1432 paramvalues[promptnum].uval.ch.val = trigndx[i];
1433 paramvalues[promptnum].uval.ch.llen = NUMTRIGFN;
1434 paramvalues[promptnum].uval.ch.vlen = 6;
1435 paramvalues[promptnum].uval.ch.list = trignameptr;
1436 choices[promptnum++] = (char far *)trg[i];
1437 }
1438 if (*(typename = curfractalspecific->name) == '*')
1439 ++typename;
1440
1441 i = curfractalspecific->orbit_bailout;
1442
1443 if( i != 0 && curfractalspecific->calctype == StandardFractal &&
1444 (curfractalspecific->flags & BAILTEST) ) {
1445 static FCODE bailteststr[] = {"Bailout Test (mod, real, imag, or, and, manh, manr)"};
1446 paramvalues[promptnum].type = 'l';
1447 paramvalues[promptnum].uval.ch.val = (int)bailoutest;
1448 paramvalues[promptnum].uval.ch.llen = 7;
1449 paramvalues[promptnum].uval.ch.vlen = 6;
1450 paramvalues[promptnum].uval.ch.list = bailnameptr;
1451 choices[promptnum++] = bailteststr;
1452 }
1453
1454 if (i) {
1455 if (potparam[0] != 0.0 && potparam[2] != 0.0)
1456 {
1457 static FCODE bailpotstr[] = {"Bailout: continuous potential (Y screen) value in use"};
1458 paramvalues[promptnum].type = '*';
1459 choices[promptnum++] = bailpotstr;
1460 }
1461 else
1462 {
1463 static FCODE bailoutstr[] = {"Bailout value (0 means use default)"};
1464 choices[promptnum] = bailoutstr;
1465 paramvalues[promptnum].type = 'L';
1466 paramvalues[promptnum++].uval.Lval = (oldbailout = bailout);
1467 paramvalues[promptnum].type = '*';
1468 tmpptr = typename;
1469 if (usr_biomorph != -1)
1470 {
1471 i = 100;
1472 tmpptr = "biomorph";
1473 }
1474 sprintf(bailoutmsg," (%s default is %d)",tmpptr,i);
1475 choices[promptnum++] = bailoutmsg;
1476 }
1477 }
1478 if (julibrot)
1479 {
1480 switch(neworbittype)
1481 {
1482 case QUATFP:
1483 case HYPERCMPLXFP:
1484 v0 = v0b; v1 = v1b; v2 = v2b; v3 = v3b;
1485 break;
1486 case QUATJULFP:
1487 case HYPERCMPLXJFP:
1488 v0 = v0c; v1 = v1c; v2 = v2c; v3 = v3c;
1489 break;
1490 default:
1491 v0 = v0a; v1 = v1a; v2 = v2a; v3 = v3a;
1492 break;
1493 }
1494
1495 curfractalspecific = savespecific;
1496 paramvalues[promptnum].uval.dval = mxmaxfp;
1497 paramvalues[promptnum].type = 'f';
1498 choices[promptnum++] = v0;
1499 paramvalues[promptnum].uval.dval = mymaxfp;
1500 paramvalues[promptnum].type = 'f';
1501 choices[promptnum++] = v1;
1502 paramvalues[promptnum].uval.dval = mxminfp;
1503 paramvalues[promptnum].type = 'f';
1504 choices[promptnum++] = v2;
1505 paramvalues[promptnum].uval.dval = myminfp;
1506 paramvalues[promptnum].type = 'f';
1507 choices[promptnum++] = v3;
1508 paramvalues[promptnum].uval.ival = zdots;
1509 paramvalues[promptnum].type = 'i';
1510 choices[promptnum++] = v4;
1511
1512 paramvalues[promptnum].type = 'l';
1513 paramvalues[promptnum].uval.ch.val = juli3Dmode;
1514 paramvalues[promptnum].uval.ch.llen = 4;
1515 paramvalues[promptnum].uval.ch.vlen = 9;
1516 paramvalues[promptnum].uval.ch.list = juli3Doptions;
1517 choices[promptnum++] = v11;
1518
1519 paramvalues[promptnum].uval.dval = eyesfp;
1520 paramvalues[promptnum].type = 'f';
1521 choices[promptnum++] = v10;
1522 paramvalues[promptnum].uval.dval = originfp;
1523 paramvalues[promptnum].type = 'f';
1524 choices[promptnum++] = v5;
1525 paramvalues[promptnum].uval.dval = depthfp;
1526 paramvalues[promptnum].type = 'f';
1527 choices[promptnum++] = v6;
1528 paramvalues[promptnum].uval.dval = heightfp;
1529 paramvalues[promptnum].type = 'f';
1530 choices[promptnum++] = v7;
1531 paramvalues[promptnum].uval.dval = widthfp;
1532 paramvalues[promptnum].type = 'f';
1533 choices[promptnum++] = v8;
1534 paramvalues[promptnum].uval.dval = distfp;
1535 paramvalues[promptnum].type = 'f';
1536 choices[promptnum++] = v9;
1537 }
1538
1539 if (curtype == INVERSEJULIA || curtype == INVERSEJULIAFP)
1540 {
1541 choices[promptnum] = JIIMstr1;
1542 paramvalues[promptnum].type = 'l';
1543 paramvalues[promptnum].uval.ch.list = JIIMmethod;
1544 paramvalues[promptnum].uval.ch.vlen = 7;
1545 #ifdef RANDOM_RUN
1547 #else
1548 paramvalues[promptnum].uval.ch.llen = 3; /* disable random run */
1549 #endif
1550 paramvalues[promptnum++].uval.ch.val = major_method;
1551
1552 choices[promptnum] = JIIMstr2;
1553 paramvalues[promptnum].type = 'l';
1554 paramvalues[promptnum].uval.ch.list = JIIMleftright;
1555 paramvalues[promptnum].uval.ch.vlen = 5;
1556 paramvalues[promptnum].uval.ch.llen = 2;
1557 paramvalues[promptnum++].uval.ch.val = minor_method;
1558 }
1559
1560 if((curtype==FORMULA || curtype==FFORMULA) && uses_ismand) {
1561 choices[promptnum] = (char far *)s_ismand;
1562 paramvalues[promptnum].type = 'y';
1563 paramvalues[promptnum++].uval.ch.val = ismand?1:0;
1564 }
1565
1566 if (caller /* <z> command ? */
1567 /* && (display3d > 0 || promptnum == 0)) */
1568 && (display3d > 0))
1569 {
1570 static FCODE msg[]={"Current type has no type-specific parameters"};
1571 stopmsg(20,msg);
1572 goto gfp_exit;
1573 }
1574 if(julibrot)
1575 sprintf(msg,"Julibrot Parameters (orbit= %s)",juliorbitname);
1576 else
1577 sprintf(msg,"Parameters for fractal type %s",typename);
1578 if(bf_math == 0)
1579 {
1580 static FCODE pressf6[] = {"\n(Press "FK_F6" for corner parameters)"};
1581 far_strcat(msg,pressf6);
1582 }
1583 else
1584 fkeymask = 0;
1585 scroll_row_status = 0; /* make sure we start at beginning of entry */
1586 scroll_column_status = 0;
1587 for(;;)
1588 {
1589 oldhelpmode = helpmode;
1590 helpmode = curfractalspecific->helptext;
1591 i = fullscreen_prompt(msg,promptnum,choices,paramvalues,fkeymask,tstack);
1592 helpmode = oldhelpmode;
1593 if (i < 0)
1594 {
1595 if(julibrot)
1596 goto gfp_top;
1597 if (ret == 0)
1598 ret = -1;
1599 goto gfp_exit;
1600 }
1601 if (i != F6)
1602 break;
1603 if(bf_math == 0)
1604 if (get_corners() > 0)
1605 ret = 1;
1606 }
1607 promptnum = 0;
1608 for ( i = firstparm; i < numparams+firstparm; i++)
1609 {
1610 if(curtype == FORMULA || curtype == FFORMULA)
1611 if(paramnotused(i))
1612 continue;
1613 if (oldparam[i] != paramvalues[promptnum].uval.dval)
1614 {
1615 param[i] = paramvalues[promptnum].uval.dval;
1616 ret = 1;
1617 }
1618 ++promptnum;
1619 }
1620
1621 for ( i = 0; i < numtrig; i++)
1622 {
1623 if (paramvalues[promptnum].uval.ch.val != (int)trigndx[i])
1624 {
1625 set_trig_array(i,trigfn[paramvalues[promptnum].uval.ch.val].name);
1626 ret = 1;
1627 }
1628 ++promptnum;
1629 }
1630
1631 if(julibrot)
1632 {
1633 savespecific = curfractalspecific;
1634 curfractalspecific = jborbit;
1635 }
1636
1637 i = curfractalspecific->orbit_bailout;
1638
1639 if( i != 0 && curfractalspecific->calctype == StandardFractal &&
1640 (curfractalspecific->flags & BAILTEST) ) {
1641 if (paramvalues[promptnum].uval.ch.val != (int)bailoutest) {
1642 bailoutest = (enum bailouts)paramvalues[promptnum].uval.ch.val;
1643 ret = 1;
1644 }
1645 promptnum++;
1646 }
1647 else
1648 bailoutest = Mod;
1649 setbailoutformula(bailoutest);
1650
1651 if (i) {
1652 if (potparam[0] != 0.0 && potparam[2] != 0.0)
1653 promptnum++;
1654 else
1655 {
1656 bailout = paramvalues[promptnum++].uval.Lval;
1657 if (bailout != 0 && (bailout < 1 || bailout > 2100000000L))
1658 bailout = oldbailout;
1659 if (bailout != oldbailout)
1660 ret = 1;
1661 promptnum++;
1662 }
1663 }
1664 if (julibrot)
1665 {
1666 mxmaxfp = paramvalues[promptnum++].uval.dval;
1667 mymaxfp = paramvalues[promptnum++].uval.dval;
1668 mxminfp = paramvalues[promptnum++].uval.dval;
1669 myminfp = paramvalues[promptnum++].uval.dval;
1670 zdots = paramvalues[promptnum++].uval.ival;
1671 juli3Dmode = paramvalues[promptnum++].uval.ch.val;
1672 eyesfp = (float)paramvalues[promptnum++].uval.dval;
1673 originfp = (float)paramvalues[promptnum++].uval.dval;
1674 depthfp = (float)paramvalues[promptnum++].uval.dval;
1675 heightfp = (float)paramvalues[promptnum++].uval.dval;
1676 widthfp = (float)paramvalues[promptnum++].uval.dval;
1677 distfp = (float)paramvalues[promptnum++].uval.dval;
1678 ret = 1; /* force new calc since not resumable anyway */
1679 }
1680 if (curtype == INVERSEJULIA || curtype == INVERSEJULIAFP)
1681 {
1682 if (paramvalues[promptnum].uval.ch.val != major_method ||
1683 paramvalues[promptnum+1].uval.ch.val != minor_method)
1684 ret = 1;
1685 major_method = (enum Major)paramvalues[promptnum++].uval.ch.val;
1686 minor_method = (enum Minor)paramvalues[promptnum++].uval.ch.val;
1687 }
1688 if((curtype==FORMULA || curtype==FFORMULA) && uses_ismand)
1689 {
1690 if (ismand != (short int)paramvalues[promptnum].uval.ch.val)
1691 {
1692 ismand = (short int)paramvalues[promptnum].uval.ch.val;
1693 ret = 1;
1694 }
1695 ++promptnum;
1696 }
1697 gfp_exit:
1698 curfractalspecific = &fractalspecific[fractype];
1699 return(ret);
1700 }
1701
1702 int find_extra_param(int type)
1703 {
1704 int i,ret,curtyp;
1705 ret = -1;
1706 i= -1;
1707
1708 if(fractalspecific[type].flags&MORE)
1709 {
1710 while((curtyp=moreparams[++i].type) != type && curtyp != -1);
1711 if(curtyp == type)
1712 ret = i;
1713 }
1714 return(ret);
1715 }
1716
1717 void load_params(int fractype)
1718 {
1719 int i, extra;
1720 for (i = 0; i < 4; ++i)
1721 {
1722 param[i] = fractalspecific[fractype].paramvalue[i];
1723 if(fractype != CELLULAR && fractype != ANT)
1724 roundfloatd(¶m[i]); /* don't round cellular or ant */
1725 }
1726 if((extra=find_extra_param(fractype)) > -1)
1727 for(i=0;i<MAXPARAMS-4;i++)
1728 param[i+4] = moreparams[extra].paramvalue[i];
1729 }
1730
1731 int check_orbit_name(char *orbitname)
1732 {
1733 int i, numtypes, bad;
1734 char *nameptr[MAXFRACTALS];
1735 int fractals[MAXFRACTALS];
1736 int last_val;
1737
1738 numtypes = build_fractal_list(fractals, &last_val, nameptr);
1739 bad = 1;
1740 for(i=0;i<numtypes;i++)
1741 {
1742 if(strcmp(orbitname,nameptr[i]) == 0)
1743 {
1744 neworbittype = fractals[i];
1745 bad = 0;
1746 break;
1747 }
1748 }
1749 return(bad);
1750 }
1751
1752 /* --------------------------------------------------------------------- */
1753
1754 static FILE *gfe_file;
1755
1756 long get_file_entry(int type,char *title,char *fmask,
1757 char *filename,char *entryname)
1758 {
1759 /* Formula, LSystem, etc type structure, select from file */
1760 /* containing definitions in the form name { ... } */
1761 int newfile,firsttry;
1762 long entry_pointer;
1763 newfile = 0;
1764 for(;;) {
1765 firsttry = 0;
1766 /* pb: binary mode used here - it is more work, but much faster, */
1767 /* especially when ftell or fgetpos is used */
1768 while (newfile || (gfe_file = fopen(filename, "rb")) == NULL) {
1769 char buf[60];
1770 newfile = 0;
1771 if (firsttry) {
1772 sprintf(temp1,s_cantfind, filename);
1773 stopmsg(0,temp1);
1774 }
1775 sprintf(buf,"Select %s File",title);
1776 if (getafilename(buf,fmask,filename) < 0)
1777 return -1;
1778
1779 firsttry = 1; /* if around open loop again it is an error */
1780 }
1781 setvbuf(gfe_file,tstack,_IOFBF,4096); /* improves speed when file is big */
1782 newfile = 0;
1783 if ((entry_pointer = gfe_choose_entry(type,title,filename,entryname)) == -2) {
1784 newfile = 1; /* go to file list, */
1785 continue; /* back to getafilename */
1786 }
1787 if (entry_pointer == -1)
1788 return -1;
1789 switch (type) {
1790 case GETFORMULA:
1791 if (RunForm(entryname, 1) == 0) return 0;
1792 break;
1793 case GETLSYS:
1794 if (LLoad() == 0) return 0;
1795 break;
1796 case GETIFS:
1797 if (ifsload() == 0) {
1798 fractype = (ifs_type == 0) ? IFS : IFS3D;
1799 curfractalspecific = &fractalspecific[fractype];
1800 set_default_parms(); /* to correct them if 3d */
1801 return 0;
1802 }
1803 break;
1804 case GETPARM:
1805 return entry_pointer;
1806 }
1807 }
1808 }
1809
1810 struct entryinfo {
1811 char name[ITEMNAMELEN+2];
1812 long point; /* points to the ( or the { following the name */
1813 };
1814 static struct entryinfo far *far*gfe_choices; /* for format_getparm_line */
1815 static char *gfe_title;
1816
1817 /* skip to next non-white space character and return it */
1818 int skip_white_space(FILE *infile, long *file_offset)
1819 {
1820 int c;
1821 do
1822 {
1823 c = getc(infile);
1824 (*file_offset)++;
1825 }
1826 while (c == ' ' || c == '\t' || c == '\n' || c == '\r');
1827 return(c);
1828 }
1829
1830 /* skip to end of line */
1831 int skip_comment(FILE *infile, long *file_offset)
1832 {
1833 int c;
1834 do
1835 {
1836 c = getc(infile);
1837 (*file_offset)++;
1838 }
1839 while (c != '\n' && c != '\r' && c != EOF && c != '\032');
1840 return(c);
1841 }
1842
1843 #define MAXENTRIES 2000L
1844
1845 int scan_entries(FILE * infile, void far * ch, char *itemname)
1846 {
1847 /*
1848 function returns the number of entries found; if a
1849 specific entry is being looked for, returns -1 if
1850 the entry is found, 0 otherwise.
1851 */
1852 struct entryinfo far *far * choices;
1853 char buf[101];
1854 int exclude_entry;
1855 long name_offset, temp_offset; /*rev 5/23/96 to add temp_offset,
1856 used below to skip any '{' that
1857 does not have a corresponding
1858 '}' - GGM */
1859 long file_offset = -1;
1860 int numentries = 0;
1861
1862 choices = (struct entryinfo far * far *) ch;
1863
1864 for (;;)
1865 { /* scan the file for entry names */
1866 int c, len;
1867 top:
1868 if ((c = skip_white_space(infile, &file_offset)) == ';')
1869 {
1870 c = skip_comment(infile, &file_offset);
1871 if (c == EOF || c == '\032')
1872 break;
1873 continue;
1874 }
1875 name_offset = temp_offset = file_offset;
1876 /* next equiv roughly to fscanf(..,"%40[^* \n\r\t({\032]",buf) */
1877 len = 0;
1878 /* allow spaces in entry names in next JCO 9/2/2003 */
1879 while (c != ' ' && c != '\t' && c != '(' && c != ';'
1880 && c != '{' && c != '\n' && c != '\r' && c != EOF && c != '\032')
1881 {
1882 if (len < 40)
1883 buf[len++] = (char) c;
1884 c = getc(infile);
1885 ++file_offset;
1886 if(c == '\n' || c == '\r')
1887 goto top;
1888 }
1889 buf[len] = 0;
1890 while (c != '{' && c != EOF && c != '\032')
1891 {
1892 if(c == ';')
1893 c = skip_comment(infile, &file_offset);
1894 else
1895 {
1896 c = getc(infile);
1897 ++file_offset;
1898 if(c == '\n' || c == '\r')
1899 goto top;
1900 }
1901 }
1902 if (c == '{')
1903 {
1904 while (c != '}' && c != EOF && c != '\032')
1905 {
1906 if(c == ';')
1907 c = skip_comment(infile, &file_offset);
1908 else
1909 {
1910 if(c == '\n' || c == '\r') /* reset temp_offset to */
1911 temp_offset = file_offset; /* beginning of new line */
1912 c = getc(infile);
1913 ++file_offset;
1914 }
1915 if(c == '{') /*second '{' found*/
1916 {
1917 if (temp_offset == name_offset) /*if on same line, skip line*/
1918 {
1919 c = skip_comment(infile, &file_offset);
1920 goto top;
1921 }
1922 else
1923 {
1924 fseek(infile, temp_offset, SEEK_SET); /*else, go back to */
1925 file_offset = temp_offset - 1; /*beginning of line*/
1926 goto top;
1927 }
1928 }
1929 }
1930 if (c != '}') /* i.e. is EOF or '\032'*/
1931 break;
1932
1933 if (strnicmp(buf, "frm:", 4) == 0 ||
1934 strnicmp(buf, "ifs:", 4) == 0 ||
1935 strnicmp(buf, "par:", 4) == 0)
1936 exclude_entry = 4;
1937 else if (strnicmp(buf, "lsys:", 5) == 0)
1938 exclude_entry = 5;
1939 else
1940 exclude_entry = 0;
1941
1942 buf[ITEMNAMELEN + exclude_entry] = 0;
1943 if (itemname != NULL) /* looking for one entry */
1944 {
1945 if (stricmp(buf, itemname) == 0)
1946 {
1947 fseek(infile, name_offset + (long) exclude_entry, SEEK_SET);
1948 return (-1);
1949 }
1950 }
1951 else /* make a whole list of entries */
1952 {
1953 if (buf[0] != 0 && stricmp(buf, "comment") != 0 && !exclude_entry)
1954 {
1955 far_strcpy(choices[numentries]->name, buf);
1956 choices[numentries]->point = name_offset;
1957 if (++numentries >= MAXENTRIES)
1958 {
1959 sprintf(buf, "Too many entries in file, first %ld used", MAXENTRIES);
1960 stopmsg(0, buf);
1961 break;
1962 }
1963 }
1964 }
1965 }
1966 else if (c == EOF || c == '\032')
1967 break;
1968 }
1969 return (numentries);
1970 }
1971
1972 static long gfe_choose_entry(int type,char *title,char *filename,char *entryname)
1973 /* subrtn of get_file_entry, separated so that storage gets freed up */
1974 {
1975 #ifdef XFRACT
1976 static FCODE o_instr[]={"Press "FK_F6" to select file, "FK_F2" for details, "FK_F4" to toggle sort "};
1977 /* keep the above line length < 80 characters */ 1978 #else
1979 static FCODE o_instr[]={"Press "FK_F6" to select different file, "FK_F2" for details, "FK_F4" to toggle sort "};
1980 #endif
1981 int numentries, i;
1982 char buf[101];
1983 struct entryinfo far * far *choices;
1984 int far *attributes;
1985 void (*formatitem)(int, char *);
1986 int boxwidth,boxdepth,colwidth;
1987 static int dosort = 1;
1988 int options = 8;
1989 char far *instr;
1990 /* steal existing array for "choices" */
1991 choices = (struct entryinfo far *far*)MK_FP(extraseg,0);
1992 /* leave room for details F2 */
1993 choices = choices + (2048/sizeof(struct entryinfo far *far*));
1994 choices[0] = (struct entryinfo far *)(choices + MAXENTRIES+1);
1995 attributes = (int far *)(choices[0] + MAXENTRIES+1);
1996 instr = (char far *)(attributes + MAXENTRIES +1);
1997 gfe_choices = &choices[0];
1998 gfe_title = title;
1999 retry:
2000 attributes[0] = 1;
2001 for(i=1;i<MAXENTRIES+1;i++)
2002 {
2003 choices[i] = choices[i-1] + 1;
2004 attributes[i] = 1;
2005 }
2006
2007 numentries = 0;
2008 helptitle(); /* to display a clue when file big and next is slow */
2009
2010 numentries=scan_entries(gfe_file,choices,NULL);
2011 if (numentries == 0) {
2012 static FCODE msg[]={"File doesn't contain any valid entries"};
2013 stopmsg(0,msg);
2014 fclose(gfe_file);
2015 return -2; /* back to file list */
2016 }
2017 far_strcpy(instr,o_instr);
2018 if(dosort)
2019 {
2020 far_strcat(instr,"off");
2021 shell_sort((char far *)choices,numentries,sizeof(char far *),lccompare);
2022 }
2023 else
2024 far_strcat(instr,"on");
2025
2026 strcpy(buf,entryname); /* preset to last choice made */
2027 sprintf(temp1,"%s Selection\nFile: %s",title,filename);
2028 formatitem = NULL;
2029 boxwidth = colwidth = boxdepth = 0;
2030 if (type == GETPARM) {
2031 formatitem = format_parmfile_line;
2032 boxwidth = 1;
2033 boxdepth = 16;
2034 colwidth = 76;
2035 }
2036 if(dosort)
2037 options = 8;
2038 else
2039 options = 8+32;
2040 i = fullscreen_choice(options,temp1,NULL,instr,numentries,(char far*far*)choices,
2041 attributes,boxwidth,boxdepth,colwidth,0,
2042 formatitem,buf,NULL,check_gfe_key);
2043 if (i == 0-F4)
2044 {
2045 rewind(gfe_file);
2046 dosort = 1-dosort;
2047 goto retry;
2048 }
2049 fclose(gfe_file);
2050 if (i < 0) {
2051 if (i == 0-F6)
2052 return -2; /* go back to file list */
2053 return -1; /* cancel */
2054 }
2055 far_strcpy(entryname, choices[i]->name);
2056 return(choices[i]->point);
2057 }
2058
2059
2060 static int check_gfe_key(int curkey,int choice)
2061 {
2062 char infhdg[60];
2063 char far *infbuf;
2064 int in_scrolling_mode = 0; /* 1 if entry doesn't fit available space */
2065 int top_line = 0;
2066 int left_column = 0;
2067 int i;
2068 int done = 0;
2069 int rewrite_infbuf = 0; /* if 1: rewrite the entry portion of screen */
2070 char blanks[79]; /* used to clear the entry portion of screen */
2071 memset(blanks, ' ', 78);
2072 blanks[78] = (char) 0;
2073
2074 if (curkey == F6)
2075 return 0-F6;
2076 if (curkey == F4)
2077 return 0-F4;
2078 if (curkey == F2) {
2079 int widest_entry_line = 0;
2080 int lines_in_entry = 0;
2081 int comment = 0;
2082 int c = 0;
2083 int widthct = 0;
2084 infbuf = MK_FP(extraseg,0);
2085 fseek(gfe_file,gfe_choices[choice]->point,SEEK_SET);
2086 while((c = fgetc(gfe_file)) != EOF && c != '\032') {
2087 if(c == ';')
2088 comment = 1;
2089 else if(c == '\n') {
2090 comment = 0;
2091 lines_in_entry++;
2092 widthct = -1;
2093 }
2094 else if (c == '\t')
2095 widthct += 7 - widthct % 8;
2096 else if ( c == '\r')
2097 continue;
2098 if(++widthct > widest_entry_line)
2099 widest_entry_line = widthct;
2100 if (c == '}' && !comment) {
2101 lines_in_entry++;
2102 break;
2103 }
2104 }
2105 if(c == EOF || c == '\032') { /* should never happen */
2106 fseek(gfe_file,gfe_choices[choice]->point,SEEK_SET);
2107 in_scrolling_mode = 0;
2108 }
2109 fseek(gfe_file,gfe_choices[choice]->point,SEEK_SET);
2110 load_entry_text(gfe_file,infbuf, 17, 0, 0);
2111 if(lines_in_entry > 17 || widest_entry_line > 74)
2112 in_scrolling_mode = 1;
2113 strcpy(infhdg,gfe_title);
2114 strcat(infhdg," file entry:\n\n");
2115 /* ... instead, call help with buffer? heading added */
2116 stackscreen();
2117 helptitle();
2118 setattr(1,0,C_GENERAL_MED,24*80);
2119
2120 textcbase = 0;
2121 putstring(2,1,C_GENERAL_HI,infhdg);
2122 textcbase = 2; /* left margin is 2 */
2123 putstring(4,0,C_GENERAL_MED,infbuf);
2124
2125 {
2126 static FCODE msg[] = {"\n\n Use "UPARR1", "DNARR1", "RTARR1", "LTARR1", PgUp, PgDown, Home, and End to scroll text\nAny other key to return to selection list"};
2127 putstring(-1,0,C_GENERAL_LO,msg);
2128 }
2129
2130 while(!done) {
2131 if(rewrite_infbuf) {
2132 rewrite_infbuf = 0;
2133 fseek(gfe_file,gfe_choices[choice]->point,SEEK_SET);
2134 load_entry_text(gfe_file, infbuf, 17, top_line, left_column);
2135 for(i = 4; i < (lines_in_entry < 17 ? lines_in_entry + 4 : 21); i++)
2136 putstring(i,0,C_GENERAL_MED,blanks);
2137 putstring(4,0,C_GENERAL_MED,infbuf);
2138 }
2139 if((i = getakeynohelp()) == DOWN_ARROW || i == DOWN_ARROW_2
2140 || i == UP_ARROW || i == UP_ARROW_2
2141 || i == LEFT_ARROW || i == LEFT_ARROW_2
2142 || i == RIGHT_ARROW || i == RIGHT_ARROW_2
2143 || i == HOME || i == CTL_HOME
2144 || i == END || i == CTL_END
2145 || i == PAGE_UP || i == CTL_PAGE_UP
2146 || i == PAGE_DOWN || i == CTL_PAGE_DOWN) {
2147 switch(i) {
2148 case DOWN_ARROW: case DOWN_ARROW_2: /* down one line */
2149 if(in_scrolling_mode && top_line < lines_in_entry - 17) {
2150 top_line++;
2151 rewrite_infbuf = 1;
2152 }
2153 break;
2154 case UP_ARROW: case UP_ARROW_2: /* up one line */
2155 if(in_scrolling_mode && top_line > 0) {
2156 top_line--;
2157 rewrite_infbuf = 1;
2158 }
2159 break;
2160 case LEFT_ARROW: case LEFT_ARROW_2: /* left one column */
2161 if(in_scrolling_mode && left_column > 0) {
2162 left_column--;
2163 rewrite_infbuf = 1;
2164 }
2165 break;
2166 case RIGHT_ARROW: case RIGHT_ARROW_2: /* right one column */
2167 if(in_scrolling_mode && far_strchr(infbuf, '\021') != NULL) {
2168 left_column++;
2169 rewrite_infbuf = 1;
2170 }
2171 break;
2172 case PAGE_DOWN: case CTL_PAGE_DOWN: /* down 17 lines */
2173 if(in_scrolling_mode && top_line < lines_in_entry - 17) {
2174 top_line += 17;
2175 if(top_line > lines_in_entry - 17)
2176 top_line = lines_in_entry - 17;
2177 rewrite_infbuf = 1;
2178 }
2179 break;
2180 case PAGE_UP: case CTL_PAGE_UP: /* up 17 lines */
2181 if(in_scrolling_mode && top_line > 0) {
2182 top_line -= 17;
2183 if(top_line < 0)
2184 top_line = 0;
2185 rewrite_infbuf = 1;
2186 }
2187 break;
2188 case END: case CTL_END: /* to end of entry */
2189 if(in_scrolling_mode) {
2190 top_line = lines_in_entry - 17;
2191 left_column = 0;
2192 rewrite_infbuf = 1;
2193 }
2194 break;
2195 case HOME: case CTL_HOME: /* to beginning of entry */
2196 if(in_scrolling_mode) {
2197 top_line = left_column = 0;
2198 rewrite_infbuf = 1;
2199 }
2200 break;
2201 default:
2202 break;
2203 }
2204 }
2205 else
2206 done = 1; /* a key other than scrolling key was pressed */
2207 }
2208 textcbase = 0;
2209 movecursor(25,80);
2210 unstackscreen();
2211 }
2212 return 0;
2213 }
2214
2215 static void load_entry_text(
2216 FILE *entfile,
2217 char far *buf,
2218 int maxlines,
2219 int startrow,
2220 int startcol)
2221 {
2222 /* Revised 12/14/96 by George Martin. Up to maxlines of an entry
2223 is copied to *buf starting from row "startrow", and skipping
2224 characters in each line up to "startcol". The terminating '\n'
2225 is deleted if maxlines is reached before the end of the entry.
2226 */
2227
2228 int linelen, i;
2229 int comment=0;
2230 int c = 0;
2231 int tabpos = 7 - (startcol % 8);
2232
2233 if(maxlines <= 0) { /* no lines to get! */
2234 *buf = (char) 0;
2235 return;
2236 }
2237
2238 /*move down to starting row*/
2239 for(i = 0; i < startrow; i++) {
2240 while((c=fgetc(entfile)) != '\n' && c != EOF && c != '\032') {
2241 if(c == ';')
2242 comment = 1;
2243 if(c == '}' && !comment) /* end of entry before start line */
2244 break; /* this should never happen */
2245 }
2246 if(c == '\n')
2247 comment = 0;
2248 else { /* reached end of file or end of entry */
2249 *buf = (char) 0;
2250 return;
2251 }
2252 }
2253
2254 /* write maxlines of entry */
2255 while(maxlines-- > 0) {
2256 comment = linelen = i = c = 0;
2257
2258 /* skip line up to startcol */
2259 while (i++ < startcol && (c = fgetc(entfile)) != EOF && c != '\032') {
2260 if(c == ';')
2261 comment = 1;
2262 if(c == '}' && !comment) { /*reached end of entry*/
2263 *buf = (char) 0;
2264 return;
2265 }
2266 if ( c == '\r') {
2267 i--;
2268 continue;
2269 }
2270 if(c == '\t')
2271 i += 7 - (i % 8);
2272 if(c == '\n') { /*need to insert '\n', even for short lines*/
2273 *(buf++) = (char)c;
2274 break;
2275 }
2276 }
2277 if(c == EOF || c == '\032') { /* unexpected end of file */
2278 *buf = (char) 0;
2279 return;
2280 }
2281 if(c == '\n') /* line is already completed */
2282 continue;
2283
2284 if(i > startcol) { /* can happen because of <tab> character */
2285 while(i-- > startcol) {
2286 *(buf++) = ' ';
2287 linelen++;
2288 }
2289 }
2290
2291 /*process rest of line into buf */
2292 while ((c = fgetc(entfile)) != EOF && c != '\032') {
2293 if (c == ';')
2294 comment = 1;
2295 else if (c == '\n' || c == '\r')
2296 comment = 0;
2297 if (c != '\r') {
2298 if (c == '\t') {
2299 while ((linelen % 8) != tabpos && linelen < 75) { /* 76 wide max */
2300 *(buf++) = ' ';
2301 ++linelen;
2302 }
2303 c = ' ';
2304 }
2305 if (c == '\n') {
2306 *(buf++) = '\n';
2307 break;
2308 }
2309 if (++linelen > 75) {
2310 if (linelen == 76)
2311 *(buf++) = '\021';
2312 }
2313 else
2314 *(buf++) = (char)c;
2315 if (c == '}' && !comment) { /*reached end of entry*/
2316 *(buf) = (char) 0;
2317 return;
2318 }
2319 }
2320 }
2321 if(c == EOF || c == '\032') { /* unexpected end of file */
2322 *buf = (char) 0;
2323 return;
2324 }
2325 }
2326 if(*(buf-1) == '\n') /* specified that buf will not end with a '\n' */
2327 buf--;
2328 *buf = (char) 0;
2329 }
2330
2331 static void format_parmfile_line(int choice,char *buf)
2332 {
2333 int c,i;
2334 char line[80];
2335 fseek(gfe_file,gfe_choices[choice]->point,SEEK_SET);
2336 while (getc(gfe_file) != '{') { }
2337 while ((c = getc(gfe_file)) == ' ' || c == '\t' || c == ';') { }
2338 i = 0;
2339 while (i < 56 && c != '\n' && c != '\r' && c != EOF && c != '\032') {
2340 line[i++] = (char)((c == '\t') ? ' ' : c);
2341 c = getc(gfe_file);
2342 }
2343 line[i] = 0;
2344 #ifndef XFRACT
2345 sprintf(buf,"%-20Fs%-56s",gfe_choices[choice]->name,line);
2348 #endif
2349 }
2350
2351 /* --------------------------------------------------------------------- */
2352
2353 int get_fract3d_params() /* prompt for 3D fractal parameters */
2354 {
2355 int i,k,ret,oldhelpmode;
2356 static FCODE hdg[] = {"3D Parameters"};
2357 static FCODE p1[] = {"X-axis rotation in degrees"};
2358 static FCODE p2[] = {"Y-axis rotation in degrees"};
2359 static FCODE p3[] = {"Z-axis rotation in degrees"};
2360 static FCODE p4[] = {"Perspective distance [1 - 999, 0 for no persp]"};
2361 static FCODE p5[] = {"X shift with perspective (positive = right)"};
2362 static FCODE p6[] = {"Y shift with perspective (positive = up )"};
2363 static FCODE p7[] = {"Stereo (R/B 3D)? (0=no,1=alternate,2=superimpose,3=photo,4=stereo pair)"};
2364 struct fullscreenvalues uvalues[20];
2365 char far *ifs3d_prompts[8];
2366
2367 stackscreen();
2368 ifs3d_prompts[0] = p1;
2369 ifs3d_prompts[1] = p2;
2370 ifs3d_prompts[2] = p3;
2371 ifs3d_prompts[3] = p4;
2372 ifs3d_prompts[4] = p5;
2373 ifs3d_prompts[5] = p6;
2374 ifs3d_prompts[6] = p7;
2375 k = 0;
2376 uvalues[k].type = 'i';
2377 uvalues[k++].uval.ival = XROT;
2378 uvalues[k].type = 'i';
2379 uvalues[k++].uval.ival = YROT;
2380 uvalues[k].type = 'i';
2381 uvalues[k++].uval.ival = ZROT;
2382 uvalues[k].type = 'i';
2383 uvalues[k++].uval.ival = ZVIEWER;
2384 uvalues[k].type = 'i';
2385 uvalues[k++].uval.ival = XSHIFT;
2386 uvalues[k].type = 'i';
2387 uvalues[k++].uval.ival = YSHIFT;
2388 uvalues[k].type = 'i';
2389 uvalues[k++].uval.ival = glassestype;
2390
2391 oldhelpmode = helpmode;
2392 helpmode = HELP3DFRACT;
2393 i = fullscreen_prompt(hdg,k,ifs3d_prompts,uvalues,0,NULL);
2394 helpmode = oldhelpmode;
2395 if (i < 0) {
2396 ret = -1;
2397 goto get_f3d_exit;
2398 }
2399
2400 ret = k = 0;
2401 XROT = uvalues[k++].uval.ival;
2402 YROT = uvalues[k++].uval.ival;
2403 ZROT = uvalues[k++].uval.ival;
2404 ZVIEWER = uvalues[k++].uval.ival;
2405 XSHIFT = uvalues[k++].uval.ival;
2406 YSHIFT = uvalues[k++].uval.ival;
2407 glassestype = uvalues[k++].uval.ival;
2408 if (glassestype < 0 || glassestype > 4) glassestype = 0;
2409 if (glassestype)
2410 if (get_funny_glasses_params() || check_mapfile())
2411 ret = -1;
2412
2413 get_f3d_exit:
2414 unstackscreen();
2415 return(ret);
2416 }
2417
2418 /* --------------------------------------------------------------------- */
2419 /* These macros streamline the "save near space" campaign */
2420
2421 #define LOADPROMPTS3D(X) {\
2422 static FCODE tmp[] = { X };\
2423 prompts3d[++k]= tmp;\
2424 }
2425
2426 #define LOADPROMPTSCHOICES(X) {\
2427 static FCODE tmp[] = { X };\
2428 choices[k++]= tmp;\
2429 }
2430
2431 int get_3d_params() /* prompt for 3D parameters */
2432 {
2433 static FCODE hdg[]={"3D Mode Selection"};
2434 static FCODE hdg1[]={"Select 3D Fill Type"};
2435 char far *choices[11];
2436 int attributes[21];
2437 int sphere;
2438 char far *s;
2439 static FCODE s1[] = {"Sphere 3D Parameters\n\
2440 Sphere is on its side; North pole to right\n\
2441 Long. 180 is top, 0 is bottom; Lat. -90 is left, 90 is right"};
2442 static FCODE s2[]={"Planar 3D Parameters\n\
2443 Pre-rotation X axis is screen top; Y axis is left side\n\
2444 Pre-rotation Z axis is coming at you out of the screen!"};
2445 char far *prompts3d[21];
2446 struct fullscreenvalues uvalues[21];
2447 int i, k;
2448 int oldhelpmode;
2449
2450 #ifdef WINFRACT
2451 {
2452 extern int far wintext_textmode;
2453 if (wintext_textmode != 2) /* are we in textmode? */
2454 return(0); /* no - prompts are already handled */
2455 } 2456 #endif
2457 restart_1:
2458 if (Targa_Out && overlay3d)
2459 Targa_Overlay = 1;
2460
2461 k= -1;
2462
2463 LOADPROMPTS3D("Preview Mode?");
2464 uvalues[k].type = 'y';
2465 uvalues[k].uval.ch.val = preview;
2466
2467 LOADPROMPTS3D(" Show Box?");
2468 uvalues[k].type = 'y';
2469 uvalues[k].uval.ch.val = showbox;
2470
2471 LOADPROMPTS3D("Coarseness, preview/grid/ray (in y dir)");
2472 uvalues[k].type = 'i';
2473 uvalues[k].uval.ival = previewfactor;
2474
2475 LOADPROMPTS3D("Spherical Projection?");
2476 uvalues[k].type = 'y';
2477 uvalues[k].uval.ch.val = sphere = SPHERE;
2478
2479 LOADPROMPTS3D("Stereo (R/B 3D)? (0=no,1=alternate,2=superimpose,");
2480 uvalues[k].type = 'i';
2481 uvalues[k].uval.ival = glassestype;
2482
2483 LOADPROMPTS3D(" 3=photo,4=stereo pair)");
2484 uvalues[k].type = '*';
2485
2486 LOADPROMPTS3D("Ray trace out? (0=No, 1=DKB/POVRay, 2=VIVID, 3=RAW,");
2487 uvalues[k].type = 'i';
2488 uvalues[k].uval.ival = RAY;
2489
2490 LOADPROMPTS3D(" 4=MTV, 5=RAYSHADE, 6=ACROSPIN, 7=DXF)");
2491 uvalues[k].type = '*';
2492
2493 LOADPROMPTS3D(" Brief output?");
2494 uvalues[k].type = 'y';
2495 uvalues[k].uval.ch.val = BRIEF;
2496
2497 check_writefile(ray_name,".ray");
2498 LOADPROMPTS3D(" Output File Name");
2499 uvalues[k].type = 's';
2500 strcpy(uvalues[k].uval.sval,ray_name);
2501
2502 LOADPROMPTS3D("Targa output?");
2503 uvalues[k].type = 'y';
2504 uvalues[k].uval.ch.val = Targa_Out;
2505
2506 LOADPROMPTS3D("Use grayscale value for depth? (if \"no\" uses color number)");
2507 uvalues[k].type = 'y';
2508 uvalues[k].uval.ch.val = grayflag;
2509
2510 oldhelpmode = helpmode;
2511 helpmode = HELP3DMODE;
2512
2513 k = fullscreen_prompt(hdg,k+1,prompts3d,uvalues,0,NULL);
2514 helpmode = oldhelpmode;
2515 if (k < 0) {
2516 return(-1);
2517 }
2518
2519 k=0;
2520
2521 preview = (char)uvalues[k++].uval.ch.val;
2522
2523 showbox = (char)uvalues[k++].uval.ch.val;
2524
2525 previewfactor = uvalues[k++].uval.ival;
2526
2527 sphere = uvalues[k++].uval.ch.val;
2528
2529 glassestype = uvalues[k++].uval.ival;
2530 k++;
2531
2532 RAY = uvalues[k++].uval.ival;
2533 k++;
2534 {
2535 static FCODE msg[] = {
2536 "DKB/POV-Ray output is obsolete but still works. See \"Ray Tracing Output\" in\n\
2537 the online documentation."};
2538 if(RAY == 1)
2539 stopmsg(0,msg);
2540 }
2541 BRIEF = uvalues[k++].uval.ch.val;
2542
2543 strcpy(ray_name,uvalues[k++].uval.sval);
2544
2545 Targa_Out = uvalues[k++].uval.ch.val;
2546 grayflag = (char)uvalues[k++].uval.ch.val;
2547
2548 /* check ranges */
2549 if(previewfactor < 2)
2550 previewfactor = 2;
2551 if(previewfactor > 2000)
2552 previewfactor = 2000;
2553
2554 if(sphere && !SPHERE)
2555 {
2556 SPHERE = TRUE;
2557 set_3d_defaults();
2558 }
2559 else if(!sphere && SPHERE)
2560 {
2561 SPHERE = FALSE;
2562 set_3d_defaults();
2563 }
2564
2565 if(glassestype < 0)
2566 glassestype = 0;
2567 if(glassestype > 4)
2568 glassestype = 4;
2569 if(glassestype)
2570 whichimage = 1;
2571
2572 if (RAY < 0)
2573 RAY = 0;
2574 if (RAY > 7)
2575 RAY = 7;
2576
2577 if (!RAY)
2578 {
2579 k = 0;
2580 LOADPROMPTSCHOICES("make a surface grid");
2581 LOADPROMPTSCHOICES("just draw the points");
2582 LOADPROMPTSCHOICES("connect the dots (wire frame)");
2583 LOADPROMPTSCHOICES("surface fill (colors interpolated)");
2584 LOADPROMPTSCHOICES("surface fill (colors not interpolated)");
2585 LOADPROMPTSCHOICES("solid fill (bars up from \"ground\")");
2586 if(SPHERE)
2587 {
2588 LOADPROMPTSCHOICES("light source");
2589 }
2590 else
2591 {
2592 LOADPROMPTSCHOICES("light source before transformation");
2593 LOADPROMPTSCHOICES("light source after transformation");
2594 }
2595 for (i = 0; i < k; ++i)
2596 attributes[i] = 1;
2597 helpmode = HELP3DFILL;
2598 i = fullscreen_choice(CHOICEHELP,hdg1,NULL,NULL,k,(char far * far *)choices,attributes,
2599 0,0,0,FILLTYPE+1,NULL,NULL,NULL,NULL);
2600 helpmode = oldhelpmode;
2601 if (i < 0)
2602 goto restart_1;
2603 FILLTYPE = i-1;
2604
2605 if(glassestype)
2606 {
2607 if(get_funny_glasses_params())
2608 goto restart_1;
2609 }
2610 if (check_mapfile())
2611 goto restart_1;
2612 }
2613 restart_3:
2614
2615 if(SPHERE)
2616 {
2617 k = -1;
2618 LOADPROMPTS3D("Longitude start (degrees)");
2619 LOADPROMPTS3D("Longitude stop (degrees)");
2620 LOADPROMPTS3D("Latitude start (degrees)");
2621 LOADPROMPTS3D("Latitude stop (degrees)");
2622 LOADPROMPTS3D("Radius scaling factor in pct");
2623 }
2624 else
2625 {
2626 k = -1;
2627 if (!RAY)
2628 {
2629 LOADPROMPTS3D("X-axis rotation in degrees");
2630 LOADPROMPTS3D("Y-axis rotation in degrees");
2631 LOADPROMPTS3D("Z-axis rotation in degrees");
2632 }
2633 LOADPROMPTS3D("X-axis scaling factor in pct");
2634 LOADPROMPTS3D("Y-axis scaling factor in pct");
2635 }
2636 k = -1;
2637 if (!(RAY && !SPHERE))
2638 {
2639 uvalues[++k].uval.ival = XROT ;
2640 uvalues[k].type = 'i';
2641 uvalues[++k].uval.ival = YROT ;
2642 uvalues[k].type = 'i';
2643 uvalues[++k].uval.ival = ZROT ;
2644 uvalues[k].type = 'i';
2645 }
2646 uvalues[++k].uval.ival = XSCALE ;
2647 uvalues[k].type = 'i';
2648
2649 uvalues[++k].uval.ival = YSCALE ;
2650 uvalues[k].type = 'i';
2651
2652 LOADPROMPTS3D("Surface Roughness scaling factor in pct");
2653 uvalues[k].type = 'i';
2654 uvalues[k].uval.ival = ROUGH ;
2655
2656 LOADPROMPTS3D("'Water Level' (minimum color value)");
2657 uvalues[k].type = 'i';
2658 uvalues[k].uval.ival = WATERLINE ;
2659
2660 if(!RAY)
2661 {
2662 LOADPROMPTS3D("Perspective distance [1 - 999, 0 for no persp])");
2663 uvalues[k].type = 'i';
2664 uvalues[k].uval.ival = ZVIEWER ;
2665
2666 LOADPROMPTS3D("X shift with perspective (positive = right)");
2667 uvalues[k].type = 'i';
2668 uvalues[k].uval.ival = XSHIFT ;
2669
2670 LOADPROMPTS3D("Y shift with perspective (positive = up )");
2671 uvalues[k].type = 'i';
2672 uvalues[k].uval.ival = YSHIFT ;
2673
2674 LOADPROMPTS3D("Image non-perspective X adjust (positive = right)");
2675 uvalues[k].type = 'i';
2676 uvalues[k].uval.ival = xtrans ;
2677
2678 LOADPROMPTS3D("Image non-perspective Y adjust (positive = up)");
2679 uvalues[k].type = 'i';
2680 uvalues[k].uval.ival = ytrans ;
2681
2682 LOADPROMPTS3D("First transparent color");
2683 uvalues[k].type = 'i';
2684 uvalues[k].uval.ival = transparent[0];
2685
2686 LOADPROMPTS3D("Last transparent color");
2687 uvalues[k].type = 'i';
2688 uvalues[k].uval.ival = transparent[1];
2689 }
2690
2691 LOADPROMPTS3D("Randomize Colors (0 - 7, '0' disables)");
2692 uvalues[k].type = 'i';
2693 uvalues[k++].uval.ival = RANDOMIZE;
2694
2695 if (SPHERE)
2696 s = s1;
2697 else
2698 s = s2;
2699
2700 helpmode = HELP3DPARMS;
2701 k = fullscreen_prompt(s,k,prompts3d,uvalues,0,NULL);
2702 helpmode = oldhelpmode;
2703 if (k < 0)
2704 goto restart_1;
2705
2706 k = 0;
2707 if (!(RAY && !SPHERE))
2708 {
2709 XROT = uvalues[k++].uval.ival;
2710 YROT = uvalues[k++].uval.ival;
2711 ZROT = uvalues[k++].uval.ival;
2712 }
2713 XSCALE = uvalues[k++].uval.ival;
2714 YSCALE = uvalues[k++].uval.ival;
2715 ROUGH = uvalues[k++].uval.ival;
2716 WATERLINE = uvalues[k++].uval.ival;
2717 if (!RAY)
2718 {
2719 ZVIEWER = uvalues[k++].uval.ival;
2720 XSHIFT = uvalues[k++].uval.ival;
2721 YSHIFT = uvalues[k++].uval.ival;
2722 xtrans = uvalues[k++].uval.ival;
2723 ytrans = uvalues[k++].uval.ival;
2724 transparent[0] = uvalues[k++].uval.ival;
2725 transparent[1] = uvalues[k++].uval.ival;
2726 }
2727 RANDOMIZE = uvalues[k++].uval.ival;
2728 if (RANDOMIZE >= 7) RANDOMIZE = 7;
2729 if (RANDOMIZE <= 0) RANDOMIZE = 0;
2730
2731 if ((Targa_Out || ILLUMINE || RAY))
2732 if(get_light_params())
2733 goto restart_3;
2734 return(0);
2735 }
2736
2737 /* --------------------------------------------------------------------- */
2738 static int get_light_params()
2739 {
2740 static FCODE hdg[]={"Light Source Parameters"};
2741 char far *prompts3d[13];
2742 struct fullscreenvalues uvalues[13];
2743
2744 int k;
2745 int oldhelpmode;
2746
2747 /* defaults go here */
2748
2749 k = -1;
2750
2751 if (ILLUMINE || RAY)
2752 {
2753 LOADPROMPTS3D("X value light vector");
2754 uvalues[k].type = 'i';
2755 uvalues[k].uval.ival = XLIGHT ;
2756
2757 LOADPROMPTS3D("Y value light vector");
2758 uvalues[k].type = 'i';
2759 uvalues[k].uval.ival = YLIGHT ;
2760
2761 LOADPROMPTS3D("Z value light vector");
2762 uvalues[k].type = 'i';
2763 uvalues[k].uval.ival = ZLIGHT ;
2764
2765 if (!RAY)
2766 {
2767 LOADPROMPTS3D("Light Source Smoothing Factor");
2768 uvalues[k].type = 'i';
2769 uvalues[k].uval.ival = LIGHTAVG ;
2770
2771 LOADPROMPTS3D("Ambient");
2772 uvalues[k].type = 'i';
2773 uvalues[k].uval.ival = Ambient;
2774 }
2775 }
2776
2777 if (Targa_Out && !RAY)
2778 {
2779 LOADPROMPTS3D("Haze Factor (0 - 100, '0' disables)");
2780 uvalues[k].type = 'i';
2781 uvalues[k].uval.ival= haze;
2782
2783 if (!Targa_Overlay)
2784 check_writefile(light_name,".tga");
2785 LOADPROMPTS3D("Targa File Name (Assume .tga)");
2786 uvalues[k].type = 's';
2787 strcpy(uvalues[k].uval.sval,light_name);
2788
2789 LOADPROMPTS3D("Back Ground Color (0 - 255)");
2790 uvalues[k].type = '*';
2791
2792 LOADPROMPTS3D(" Red");
2793 uvalues[k].type = 'i';
2794 uvalues[k].uval.ival = (int)back_color[0];
2795
2796 LOADPROMPTS3D(" Green");
2797 uvalues[k].type = 'i';
2798 uvalues[k].uval.ival = (int)back_color[1];
2799
2800 LOADPROMPTS3D(" Blue");
2801 uvalues[k].type = 'i';
2802 uvalues[k].uval.ival = (int)back_color[2];
2803
2804 LOADPROMPTS3D("Overlay Targa File? (Y/N)");
2805 uvalues[k].type = 'y';
2806 uvalues[k].uval.ch.val = Targa_Overlay;
2807
2808 }
2809
2810 LOADPROMPTS3D("");
2811
2812 oldhelpmode = helpmode;
2813 helpmode = HELP3DLIGHT;
2814 k = fullscreen_prompt(hdg,k,prompts3d,uvalues,0,NULL);
2815 helpmode = oldhelpmode;
2816 if (k < 0)
2817 return(-1);
2818
2819 k = 0;
2820 if (ILLUMINE)
2821 {
2822 XLIGHT = uvalues[k++].uval.ival;
2823 YLIGHT = uvalues[k++].uval.ival;
2824 ZLIGHT = uvalues[k++].uval.ival;
2825 if (!RAY)
2826 {
2827 LIGHTAVG = uvalues[k++].uval.ival;
2828 Ambient = uvalues[k++].uval.ival;
2829 if (Ambient >= 100) Ambient = 100;
2830 if (Ambient <= 0) Ambient = 0;
2831 }
2832 }
2833
2834 if (Targa_Out && !RAY)
2835 {
2836 haze = uvalues[k++].uval.ival;
2837 if (haze >= 100) haze = 100;
2838 if (haze <= 0) haze = 0;
2839 strcpy(light_name,uvalues[k++].uval.sval);
2840 /* In case light_name conflicts with an existing name it is checked
2841 again in line3d */
2842 k++;
2843 back_color[0] = (char)(uvalues[k++].uval.ival % 255);
2844 back_color[1] = (char)(uvalues[k++].uval.ival % 255);
2845 back_color[2] = (char)(uvalues[k++].uval.ival % 255);
2846 Targa_Overlay = uvalues[k].uval.ch.val;
2847 }
2848 return(0);
2849 }
2850
2851 /* --------------------------------------------------------------------- */
2852
2853
2854 static int check_mapfile()
2855 {
2856 int askflag = 0;
2857 int i,oldhelpmode;
2858 if(dontreadcolor)
2859 return(0);
2860 strcpy(temp1,"*");
2861 if (mapset)
2862 strcpy(temp1,MAP_name);
2863 if (!(glassestype == 1 || glassestype == 2))
2864 askflag = 1;
2865 else
2866 merge_pathnames(temp1,funnyglasses_map_name,0);
2867
2868 for(;;) {
2869 if (askflag) {
2870 static FCODE msg[] = {"\
2871 Enter name of .MAP file to use,\n\
2872 or '*' to use palette from the image to be loaded."};
2873 oldhelpmode = helpmode;
2874 helpmode = -1;
2875 i = field_prompt(0,msg,NULL,temp1,60,NULL);
2876 helpmode = oldhelpmode;
2877 if (i < 0)
2878 return(-1);
2879 if (temp1[0] == '*') {
2880 mapset = 0;
2881 break;
2882 }
2883 }
2884 memcpy(olddacbox,dacbox,256*3); /* save the DAC */
2885 i = ValidateLuts(temp1);
2886 memcpy(dacbox,olddacbox,256*3); /* restore the DAC */
2887 if (i != 0) { /* Oops, somethings wrong */
2888 askflag = 1;
2889 continue;
2890 }
2891 mapset = 1;
2892 merge_pathnames(MAP_name,temp1,0);
2893 break;
2894 }
2895 return(0);
2896 }
2897
2898 static int get_funny_glasses_params()
2899 {
2900 static FCODE hdg[]={"Funny Glasses Parameters"};
2901 char far *prompts3d[10];
2902
2903 struct fullscreenvalues uvalues[10];
2904
2905 int k;
2906 int oldhelpmode;
2907
2908 /* defaults */
2909 if(ZVIEWER == 0)
2910 ZVIEWER = 150;
2911 if(eyeseparation == 0)
2912 {
2913 if(fractype==IFS3D || fractype==LLORENZ3D || fractype==FPLORENZ3D)
2914 {
2915 eyeseparation = 2;
2916 xadjust = -2;
2917 }
2918 else
2919 {
2920 eyeseparation = 3;
2921 xadjust = 0;
2922 }
2923 }
2924
2925 if(glassestype == 1)
2926 strcpy(funnyglasses_map_name,Glasses1Map);
2927 else if(glassestype == 2)
2928 {
2929 if(FILLTYPE == -1)
2930 strcpy(funnyglasses_map_name,"grid.map");
2931 else
2932 {
2933 strcpy(funnyglasses_map_name,Glasses1Map);
2934 funnyglasses_map_name[7] = '2';
2935 }
2936 }
2937
2938 k = -1;
2939 LOADPROMPTS3D("Interocular distance (as % of screen)");
2940 uvalues[k].type = 'i';
2941 uvalues[k].uval.ival= eyeseparation;
2942
2943 LOADPROMPTS3D("Convergence adjust (positive = spread greater)");
2944 uvalues[k].type = 'i';
2945 uvalues[k].uval.ival = xadjust;
2946
2947 LOADPROMPTS3D("Left red image crop (% of screen)");
2948 uvalues[k].type = 'i';
2949 uvalues[k].uval.ival = red_crop_left;
2950
2951 LOADPROMPTS3D("Right red image crop (% of screen)");
2952 uvalues[k].type = 'i';
2953 uvalues[k].uval.ival = red_crop_right;
2954
2955 LOADPROMPTS3D("Left blue image crop (% of screen)");
2956 uvalues[k].type = 'i';
2957 uvalues[k].uval.ival = blue_crop_left;
2958
2959 LOADPROMPTS3D("Right blue image crop (% of screen)");
2960 uvalues[k].type = 'i';
2961 uvalues[k].uval.ival = blue_crop_right;
2962
2963 LOADPROMPTS3D("Red brightness factor (%)");
2964 uvalues[k].type = 'i';
2965 uvalues[k].uval.ival = red_bright;
2966
2967 LOADPROMPTS3D("Blue brightness factor (%)");
2968 uvalues[k].type = 'i';
2969 uvalues[k].uval.ival = blue_bright;
2970
2971 if(glassestype == 1 || glassestype == 2)
2972 {
2973 LOADPROMPTS3D("Map File name");
2974 uvalues[k].type = 's';
2975 strcpy(uvalues[k].uval.sval,funnyglasses_map_name);
2976 }
2977
2978 oldhelpmode = helpmode;
2979 helpmode = HELP3DGLASSES;
2980 k = fullscreen_prompt(hdg,k+1,prompts3d,uvalues,0,NULL);
2981 helpmode = oldhelpmode;
2982 if (k < 0)
2983 return(-1);
2984
2985 k = 0;
2986 eyeseparation = uvalues[k++].uval.ival;
2987 xadjust = uvalues[k++].uval.ival;
2988 red_crop_left = uvalues[k++].uval.ival;
2989 red_crop_right = uvalues[k++].uval.ival;
2990 blue_crop_left = uvalues[k++].uval.ival;
2991 blue_crop_right = uvalues[k++].uval.ival;
2992 red_bright = uvalues[k++].uval.ival;
2993 blue_bright = uvalues[k++].uval.ival;
2994
2995 if(glassestype == 1 || glassestype == 2)
2996 strcpy(funnyglasses_map_name,uvalues[k].uval.sval);
2997 return(0);
2998 }
2999
3000 void setbailoutformula(enum bailouts test) {
3001
3002 switch(test) {
3003 case Mod:
3004 default:{
3005 if (fpu >= 287 && debugflag != 72) /* Fast 287 math */
3006 floatbailout = (int (near *)(void))asmfpMODbailout;
3007 else
3008 floatbailout = (int (near *)(void))fpMODbailout;
3009 if (cpu >=386 && debugflag != 8088) /* Fast 386 math */
3010 longbailout = (int (near *)(void))asm386lMODbailout;
3011 else
3012 longbailout = (int (near *)(void))asmlMODbailout;
3013 bignumbailout = (int (near *)(void))bnMODbailout;
3014 bigfltbailout = (int (near *)(void))bfMODbailout;
3015 break;}
3016 case Real: {
3017 if (fpu >= 287 && debugflag != 72) /* Fast 287 math */
3018 floatbailout = (int (near *)(void))asmfpREALbailout;
3019 else
3020 floatbailout = (int (near *)(void))fpREALbailout;
3021 if (cpu >=386 && debugflag != 8088) /* Fast 386 math */
3022 longbailout = (int (near *)(void))asm386lREALbailout;
3023 else
3024 longbailout = (int (near *)(void))asmlREALbailout;
3025 bignumbailout = (int (near *)(void))bnREALbailout;
3026 bigfltbailout = (int (near *)(void))bfREALbailout;
3027 break;}
3028 case Imag:{
3029 if (fpu >= 287 && debugflag != 72) /* Fast 287 math */
3030 floatbailout = (int (near *)(void))asmfpIMAGbailout;
3031 else
3032 floatbailout = (int (near *)(void))fpIMAGbailout;
3033 if (cpu >=386 && debugflag != 8088) /* Fast 386 math */
3034 longbailout = (int (near *)(void))asm386lIMAGbailout;
3035 else
3036 longbailout = (int (near *)(void))asmlIMAGbailout;
3037 bignumbailout = (int (near *)(void))bnIMAGbailout;
3038 bigfltbailout = (int (near *)(void))bfIMAGbailout;
3039 break;}
3040 case Or:{
3041 if (fpu >= 287 && debugflag != 72) /* Fast 287 math */
3042 floatbailout = (int (near *)(void))asmfpORbailout;
3043 else
3044 floatbailout = (int (near *)(void))fpORbailout;
3045 if (cpu >=386 && debugflag != 8088) /* Fast 386 math */
3046 longbailout = (int (near *)(void))asm386lORbailout;
3047 else
3048 longbailout = (int (near *)(void))asmlORbailout;
3049 bignumbailout = (int (near *)(void))bnORbailout;
3050 bigfltbailout = (int (near *)(void))bfORbailout;
3051 break;}
3052 case And:{
3053 if (fpu >= 287 && debugflag != 72) /* Fast 287 math */
3054 floatbailout = (int (near *)(void))asmfpANDbailout;
3055 else
3056 floatbailout = (int (near *)(void))fpANDbailout;
3057 if (cpu >=386 && debugflag != 8088) /* Fast 386 math */
3058 longbailout = (int (near *)(void))asm386lANDbailout;
3059 else
3060 longbailout = (int (near *)(void))asmlANDbailout;
3061 bignumbailout = (int (near *)(void))bnANDbailout;
3062 bigfltbailout = (int (near *)(void))bfANDbailout;
3063 break;}
3064 case Manh:{
3065 if (fpu >= 287 && debugflag != 72) /* Fast 287 math */
3066 floatbailout = (int (near *)(void))asmfpMANHbailout;
3067 else
3068 floatbailout = (int (near *)(void))fpMANHbailout;
3069 if (cpu >=386 && debugflag != 8088) /* Fast 386 math */
3070 longbailout = (int (near *)(void))asm386lMANHbailout;
3071 else
3072 longbailout = (int (near *)(void))asmlMANHbailout;
3073 bignumbailout = (int (near *)(void))bnMANHbailout;
3074 bigfltbailout = (int (near *)(void))bfMANHbailout;
3075 break;}
3076 case Manr:{
3077 if (fpu >= 287 && debugflag != 72) /* Fast 287 math */
3078 floatbailout = (int (near *)(void))asmfpMANRbailout;
3079 else
3080 floatbailout = (int (near *)(void))fpMANRbailout;
3081 if (cpu >=386 && debugflag != 8088) /* Fast 386 math */
3082 longbailout = (int (near *)(void))asm386lMANRbailout;
3083 else
3084 longbailout = (int (near *)(void))asmlMANRbailout;
3085 bignumbailout = (int (near *)(void))bnMANRbailout;
3086 bigfltbailout = (int (near *)(void))bfMANRbailout;
3087 break;}
3088 }
3089 }
3090