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