File: common\realdos.c

    1 /*
    2         Miscellaneous C routines used only in DOS Fractint.
    3 */
    4 
    5 #include <string.h>
    6 #ifndef XFRACT
    7 #include <io.h>
    8 #include <process.h>
    9 #endif
   10 #include <sys/types.h>
   11 #include <sys/stat.h>
   12 #include <fcntl.h>
   13 #include <ctype.h>
   14 
   15   /* see Fractint.c for a description of the "include"  hierarchy */
   16 #include "port.h"
   17 #include "prototyp.h"
   18 #include "fractype.h"
   19 #include "helpdefs.h"
   20 
   21 static int menu_checkkey(int curkey,int choice);
   22 
   23 /* uncomment following for production version */
   24 /*
   25 #define PRODUCTION
   26 */
   27 int release=2004;  /* this has 2 implied decimals; increment it every synch */
   28 int patchlevel=4; /* patchlevel for DOS version */
   29 
   30 /* fullscreen_choice options */
   31 #define CHOICERETURNKEY 1
   32 #define CHOICEMENU      2
   33 #define CHOICEHELP      4
   34 #define CHOICESCRUNCH   16
   35 #define CHOICESNOTSORTED 32
   36 
   37 /* int stopmsg(flags,message) displays message and waits for a key:
   38      message should be a max of 9 lines with \n's separating them;
   39        no leading or trailing \n's in message;
   40        no line longer than 76 chars for best appearance;
   41      flag options:
   42        &1 if already in text display mode, stackscreen is not called
   43           and message is displayed at (12,0) instead of (4,0)
   44        &2 if continue/cancel indication is to be returned;
   45           when not set, "Any key to continue..." is displayed
   46           when set, "Escape to cancel, any other key to continue..."
   47           -1 is returned for cancel, 0 for continue
   48        &4 set to suppress buzzer
   49        &8 for Fractint for Windows & parser - use a fixed pitch font
   50       &16 for info only message (green box instead of red in DOS vsn)
   51    */
   52 #ifdef XFRACT
53 static char far s_errorstart[] = {"*** Error during startup:"};
54 #endif 55 static char far s_escape_cancel[] = {"Escape to cancel, any other key to continue..."}; 56 static char far s_anykey[] = {"Any key to continue..."}; 57 #if !defined(PRODUCTION) && !defined(XFRACT) 58 static char far s_custom[] = {"Customized Version"}; 59 static char far s_incremental[] = {"Incremental release"}; 60 #endif 61 int stopmsg (int flags, char far *msg) 62 { 63 int ret,toprow,color,savelookatmouse; 64 static unsigned char batchmode = 0; 65 if(debugflag != 0 || initbatch >= 1) 66 { 67 static FILE *fp = NULL; 68 if(fp==NULL && initbatch == 0) 69 fp=dir_fopen(workdir,"stopmsg.txt","w"); 70 else 71 fp=dir_fopen(workdir,"stopmsg.txt","a"); 72 if(fp != NULL) 73 #ifndef XFRACT 74 fprintf(fp,"%Fs\n",msg);
75 #else 76 fprintf(fp,"%s\n",msg);
77 #endif 78 fclose(fp); 79 } 80 if (active_system == 0 /* DOS */ 81 && first_init) { /* & cmdfiles hasn't finished 1st try */ 82 #ifdef XFRACT
83 setvideotext(); 84 buzzer(2); 85 putstring(0,0,15,s_errorstart); 86 putstring(2,0,15,msg); 87 movecursor(8,0); 88 sleep(1); 89 UnixDone(); 90 exit(1);
91 #else 92 printf("%Fs\n",msg); 93 dopause(1); /* pause deferred until after cmdfiles */ 94 return(0); 95 #endif 96 } 97 if (initbatch >= 1 || batchmode) { /* in batch mode */ 98 initbatch = 4; /* used to set errorlevel */ 99 batchmode = 1; /* fixes *second* stopmsg in batch mode bug */ 100 return (-1); 101 } 102 ret = 0; 103 savelookatmouse = lookatmouse; 104 lookatmouse = -13; 105 if ((flags & 1)) 106 blankrows(toprow=12,10,7); 107 else { 108 stackscreen(); 109 toprow = 4; 110 movecursor(4,0); 111 } 112 textcbase = 2; /* left margin is 2 */ 113 putstring(toprow,0,7,msg); 114 if (flags & 2) 115 putstring(textrow+2,0,7,s_escape_cancel); 116 else 117 putstring(textrow+2,0,7,s_anykey); 118 textcbase = 0; /* back to full line */ 119 color = (flags & 16) ? C_STOP_INFO : C_STOP_ERR; 120 setattr(toprow,0,color,(textrow+1-toprow)*80); 121 movecursor(25,80); /* cursor off */ 122 if ((flags & 4) == 0) 123 buzzer((flags & 16) ? 0 : 2); 124 while (keypressed()) /* flush any keyahead */ 125 getakey(); 126 if(debugflag != 324) 127 if (getakeynohelp() == ESC) 128 ret = -1; 129 if ((flags & 1)) 130 blankrows(toprow,10,7); 131 else 132 unstackscreen(); 133 lookatmouse = savelookatmouse; 134 return ret; 135 } 136 137 138 static U16 temptextsave = 0; 139 static int textxdots,textydots; 140 141 /* texttempmsg(msg) displays a text message of up to 40 characters, waits 142 for a key press, restores the prior display, and returns (without 143 eating the key). 144 It works in almost any video mode - does nothing in some very odd cases 145 (HCGA hi-res with old bios), or when there isn't 10k of temp mem free. */ 146 int texttempmsg(char far *msgparm) 147 { 148 if (showtempmsg(msgparm)) 149 return(-1); 150 #ifndef XFRACT 151 while (!keypressed()) ; /* wait for a keystroke but don't eat it */
152 #else 153 waitkeypressed(0); /* wait for a keystroke but don't eat it */
154 #endif 155 cleartempmsg(); 156 return(0); 157 } 158 159 void freetempmsg() 160 { 161 if(temptextsave != 0) 162 MemoryRelease(temptextsave); 163 temptextsave = 0; 164 } 165 166 int showtempmsg(char far *msgparm) 167 { 168 static long size = 0; 169 char msg[41]; 170 BYTE buffer[640]; 171 BYTE far *fontptr; 172 BYTE *bufptr; 173 int i,j,k,fontchar,charnum; 174 int xrepeat = 0; 175 int yrepeat = 0; 176 int save_sxoffs,save_syoffs; 177 far_strncpy(msg,msgparm,40); 178 msg[40] = 0; /* ensure max message len of 40 chars */ 179 if (dotmode == 11) { /* disk video, screen in text mode, easy */ 180 dvid_status(0,msg); 181 return(0); 182 } 183 if (active_system == 0 /* DOS */ 184 && first_init) { /* & cmdfiles hasn't finished 1st try */ 185 printf("%s\n",msg); 186 return(0); 187 } 188 189 if ((fontptr = findfont(0)) == NULL) { /* old bios, no font table? */ 190 if (oktoprint == 0 /* can't printf */ 191 || sxdots > 640 || sydots > 200) /* not willing to trust char cell size */ 192 return(-1); /* sorry, message not displayed */ 193 textydots = 8; 194 textxdots = sxdots; 195 } 196 else { 197 xrepeat = (sxdots >= 640) ? 2 : 1; 198 yrepeat = (sydots >= 300) ? 2 : 1; 199 textxdots = strlen(msg) * xrepeat * 8; 200 textydots = yrepeat * 8; 201 } 202 /* worst case needs 10k */ 203 if(temptextsave != 0) 204 if(size != (long)textxdots * (long)textydots) 205 freetempmsg(); 206 size = (long)textxdots * (long)textydots; 207 save_sxoffs = sxoffs; 208 save_syoffs = syoffs; 209 if (video_scroll) { 210 sxoffs = video_startx; 211 syoffs = video_starty; 212 } 213 else 214 sxoffs = syoffs = 0; 215 if(temptextsave == 0) /* only save screen first time called */ 216 { 217 if ((temptextsave = MemoryAlloc((U16)textxdots,(long)textydots,FARMEM)) == 0) 218 return(-1); /* sorry, message not displayed */ 219 for (i = 0; i < textydots; ++i) { 220 get_line(i,0,textxdots-1,buffer); 221 MoveToMemory(buffer,(U16)textxdots,1L,(long)i,temptextsave); 222 } 223 } 224 if (fontptr == NULL) { /* bios must do it for us */ 225 home(); 226 printf(msg); 227 } 228 else { /* generate the characters */ 229 find_special_colors(); /* get color_dark & color_medium set */ 230 for (i = 0; i < 8; ++i) { 231 memset(buffer,color_dark,640); 232 bufptr = buffer; 233 charnum = -1; 234 while (msg[++charnum] != 0) { 235 fontchar = *(fontptr + msg[charnum]*8 + i); 236 for (j = 0; j < 8; ++j) { 237 for (k = 0; k < xrepeat; ++k) { 238 if ((fontchar & 0x80) != 0) 239 *bufptr = (BYTE)color_medium; 240 ++bufptr; 241 } 242 fontchar <<= 1; 243 } 244 } 245 for (j = 0; j < yrepeat; ++j) 246 put_line(i*yrepeat+j,0,textxdots-1,buffer); 247 } 248 } 249 sxoffs = save_sxoffs; 250 syoffs = save_syoffs; 251 return(0); 252 } 253 254 void cleartempmsg() 255 { 256 BYTE buffer[640]; 257 int i; 258 int save_sxoffs,save_syoffs; 259 if (dotmode == 11) /* disk video, easy */ 260 dvid_status(0,""); 261 else if (temptextsave != 0) { 262 save_sxoffs = sxoffs; 263 save_syoffs = syoffs; 264 if (video_scroll) { 265 sxoffs = video_startx; 266 syoffs = video_starty; 267 } 268 else 269 sxoffs = syoffs = 0; 270 for (i = 0; i < textydots; ++i) { 271 MoveFromMemory(buffer,(U16)textxdots,1L,(long)i,temptextsave); 272 put_line(i,0,textxdots-1,buffer); 273 } 274 if(using_jiim == 0) /* jiim frees memory with freetempmsg() */ 275 { 276 MemoryRelease(temptextsave); 277 temptextsave = 0; 278 } 279 sxoffs = save_sxoffs; 280 syoffs = save_syoffs; 281 } 282 } 283 284 285 void blankrows(int row,int rows,int attr) 286 { 287 char buf[81]; 288 memset(buf,' ',80); 289 buf[80] = 0; 290 while (--rows >= 0) 291 putstring(row++,0,attr,buf); 292 } 293 294 #if (_MSC_VER >= 700) 295 #pragma code_seg ("realdos1_text") /* place following in an overlay */ 296 #endif 297 298 void helptitle() 299 { 300 char msg[MSGLEN],buf[MSGLEN]; 301 setclear(); /* clear the screen */ 302 #ifdef XFRACT
303 strcpy(msg,"X");
304 #else 305 *msg=0; 306 #endif 307 sprintf(buf,"FRACTINT Version %d.%01d",release/100,(release%100)/10); 308 strcat(msg,buf); 309 if (release%10) { 310 sprintf(buf,"%01d",release%10); 311 strcat(msg,buf); 312 } 313 if (patchlevel) { 314 sprintf(buf,".%d",patchlevel); 315 strcat(msg,buf); 316 } 317 putstringcenter(0,0,80,C_TITLE,msg); 318 319 /* uncomment next for production executable: */ 320 #if defined(PRODUCTION) || defined(XFRACT)
321 return; 322 /*NOTREACHED*/
323 #else 324 if (debugflag == 3002) return; 325 #define DEVELOPMENT 326 #ifdef DEVELOPMENT 327 putstring(0,2,C_TITLE_DEV,"Development Version");
328 #else 329 putstring(0,3,C_TITLE_DEV, s_custom);
330 #endif 331 putstring(0,55,C_TITLE_DEV,s_incremental); 332 #endif 333 } 334 335 336 void footer_msg(int *i, int options, char *speedstring) 337 { 338 static FCODE choiceinstr1a[]="Use the cursor keys to highlight your selection"; 339 static FCODE choiceinstr1b[]="Use the cursor keys or type a value to make a selection"; 340 static FCODE choiceinstr2a[]="Press ENTER for highlighted choice, or ESCAPE to back out"; 341 static FCODE choiceinstr2b[]="Press ENTER for highlighted choice, ESCAPE to back out, or F1 for help"; 342 static FCODE choiceinstr2c[]="Press ENTER for highlighted choice, or "FK_F1" for help"; 343 putstringcenter((*i)++,0,80,C_PROMPT_BKGRD, 344 (speedstring) ? choiceinstr1b : choiceinstr1a); 345 putstringcenter(*(i++),0,80,C_PROMPT_BKGRD, 346 (options&CHOICEMENU) ? choiceinstr2c 347 : ((options&CHOICEHELP) ? choiceinstr2b : choiceinstr2a)); 348 } 349 350 #if (_MSC_VER >= 700) 351 #pragma code_seg () /* back to normal segment */ 352 #endif 353 354 int putstringcenter(int row, int col, int width, int attr, char far *msg) 355 { 356 char buf[81]; 357 int i,j,k; 358 i = 0; 359 #ifdef XFRACT
360 if (width>=80) width=79; /* Some systems choke in column 80 */
361 #endif 362 while (msg[i]) ++i; /* strlen for a far */ 363 if (i == 0) return(-1); 364 if (i >= width) i = width - 1; /* sanity check */ 365 j = (width - i) / 2; 366 j -= (width + 10 - i) / 20; /* when wide a bit left of center looks better */ 367 memset(buf,' ',width); 368 buf[width] = 0; 369 i = 0; 370 k = j; 371 while (msg[i]) buf[k++] = msg[i++]; /* strcpy for a far */ 372 putstring(row,col,attr,buf); 373 return j; 374 } 375 376 /* 377 * The stackscreen()/unstackscreen() functions for XFRACT have been 378 * moved to unix/video.c to more cleanly separate the XFRACT code. 379 */ 380 381 #ifndef XFRACT 382 static int screenctr = -1; 383 384 #define MAXSCREENS 3 385 386 static U16 savescreen[MAXSCREENS]; 387 static int saverc[MAXSCREENS+1]; 388 389 void stackscreen() 390 { 391 BYTE far *vidmem; 392 int savebytes; 393 int i; 394 if (video_scroll) { 395 scroll_state(0); /* save position */ 396 scroll_center(0,0); 397 } 398 if(*s_makepar == 0) 399 return; 400 saverc[screenctr+1] = textrow*80 + textcol; 401 if (++screenctr) { /* already have some stacked */ 402 static char far msg[]={"stackscreen overflow"}; 403 if ((i = screenctr - 1) >= MAXSCREENS) { /* bug, missing unstack? */ 404 stopmsg(1,msg); 405 exit(1); 406 } 407 vidmem = MK_FP(textaddr,0); 408 savebytes = (text_type == 0) ? 4000 : 16384; 409 savescreen[i] = MemoryAlloc((U16)savebytes,1L,FARMEM); 410 if (savescreen[i] != 0) 411 MoveToMemory(vidmem,(U16)savebytes,1L,0L,savescreen[i]); 412 else { 413 static char far msg[]={"insufficient memory, aborting"}; 414 stopmsg(1,msg); 415 exit(1); 416 } 417 setclear(); 418 } 419 else 420 setfortext(); 421 if (video_scroll) { 422 if (boxcount) 423 moveboxf(0.0,0.0); 424 } 425 } 426 427 void unstackscreen() 428 { 429 BYTE far *vidmem; 430 int savebytes; 431 if(*s_makepar == 0) 432 return; 433 textrow = saverc[screenctr] / 80; 434 textcol = saverc[screenctr] % 80; 435 if (--screenctr >= 0) { /* unstack */ 436 vidmem = MK_FP(textaddr,0); 437 savebytes = (text_type == 0) ? 4000 : 16384; 438 if (savescreen[screenctr] != 0) { 439 MoveFromMemory(vidmem,(U16)savebytes,1L,0L,savescreen[screenctr]); 440 MemoryRelease(savescreen[screenctr]); 441 savescreen[screenctr] = 0; 442 } 443 } 444 else 445 setforgraphics(); 446 movecursor(-1,-1); 447 if (video_scroll) { 448 if (boxcount) 449 moveboxf(0.0,0.0); 450 scroll_state(1); /* restore position */ 451 } 452 } 453 454 void discardscreen() 455 { 456 if (--screenctr >= 0) { /* unstack */ 457 if (savescreen[screenctr]) { 458 MemoryRelease(savescreen[screenctr]); 459 savescreen[screenctr] = 0; 460 } 461 } 462 else 463 discardgraphics(); 464 } 465 #endif 466 467 /* ------------------------------------------------------------------------ */ 468 469 char speed_prompt[]="Speed key string"; 470 471 /* For file list purposes only, it's a directory name if first 472 char is a dot or last char is a slash */ 473 static int isadirname(char far *name) 474 { 475 if(*name == '.' || endswithslash(name)) 476 return 1; 477 else 478 return 0; 479 } 480 481 #if (_MSC_VER >= 700) 482 #pragma code_seg ("realdos1_text") /* place following in an overlay */ 483 #endif 484 485 void show_speedstring(int speedrow, 486 char *speedstring, 487 int (*speedprompt)(int,int,int,char *,int)) 488 { 489 int speed_match = 0; 490 int i,j; 491 char buf[81]; 492 memset(buf,' ',80); 493 buf[80] = 0; 494 putstring(speedrow,0,C_PROMPT_BKGRD,buf); 495 if (*speedstring) { /* got a speedstring on the go */ 496 putstring(speedrow,15,C_CHOICE_SP_INSTR," "); 497 if (speedprompt) 498 j = speedprompt(speedrow,16,C_CHOICE_SP_INSTR,speedstring,speed_match); 499 else { 500 putstring(speedrow,16,C_CHOICE_SP_INSTR,speed_prompt); 501 j = sizeof(speed_prompt)-1; 502 } 503 strcpy(buf,speedstring); 504 i = strlen(buf); 505 while (i < 30) 506 buf[i++] = ' '; 507 buf[i] = 0; 508 putstring(speedrow,16+j,C_CHOICE_SP_INSTR," "); 509 putstring(speedrow,17+j,C_CHOICE_SP_KEYIN,buf); 510 movecursor(speedrow,17+j+strlen(speedstring)); 511 } 512 else 513 movecursor(25,80); 514 } 515 516 void process_speedstring(char *speedstring, 517 char far*far*choices, /* array of choice strings */ 518 int curkey, 519 int *pcurrent, 520 int numchoices, 521 int is_unsorted) 522 { 523 int i, comp_result; 524 525 i = strlen(speedstring); 526 if (curkey == 8 && i > 0) /* backspace */ 527 speedstring[--i] = 0; 528 if (33 <= curkey && curkey <= 126 && i < 30) 529 { 530 #ifndef XFRACT 531 curkey = tolower(curkey); 532 #endif 533 speedstring[i] = (char)curkey; 534 speedstring[++i] = 0; 535 } 536 if (i > 0) { /* locate matching type */ 537 *pcurrent = 0; 538 while (*pcurrent < numchoices 539 && (comp_result = strncasecmp(speedstring,choices[*pcurrent],i))!=0) { 540 if (comp_result < 0 && !is_unsorted) { 541 *pcurrent -= *pcurrent ? 1 : 0; 542 break; 543 } 544 else 545 ++*pcurrent; 546 } 547 if (*pcurrent >= numchoices) /* bumped end of list */ 548 *pcurrent = numchoices - 1; 549 /*if the list is unsorted, and the entry found is not the exact 550 entry, then go looking for the exact entry. 551 */ 552 else if (is_unsorted && choices[*pcurrent][i]) { 553 int temp = *pcurrent; 554 while(++temp < numchoices) { 555 if (!choices[temp][i] && !strncasecmp(speedstring, choices[temp], i)) { 556 *pcurrent = temp; 557 break; 558 } 559 } 560 } 561 } 562 } 563 564 565 #if (_MSC_VER >= 700) 566 #pragma code_seg () /* back to normal segment */ 567 #endif 568 569 int fullscreen_choice( 570 int options, /* &2 use menu coloring scheme */ 571 /* &4 include F1 for help in instructions */ 572 /* &8 add caller's instr after normal set */ 573 /* &16 menu items up one line */ 574 char far *hdg, /* heading info, \n delimited */ 575 char far *hdg2, /* column heading or NULL */ 576 char far *instr, /* instructions, \n delimited, or NULL */ 577 int numchoices, /* How many choices in list */ 578 char far*far*choices, /* array of choice strings */ 579 int far *attributes, /* &3: 0 normal color, 1,3 highlight */ 580 /* &256 marks a dummy entry */ 581 int boxwidth, /* box width, 0 for calc (in items) */ 582 int boxdepth, /* box depth, 0 for calc, 99 for max */ 583 int colwidth, /* data width of a column, 0 for calc */ 584 int current, /* start with this item */ 585 void (*formatitem)(int,char*),/* routine to display an item or NULL */ 586 char *speedstring, /* returned speed key value, or NULL */ 587 int (*speedprompt)(int,int,int,char *,int),/* routine to display prompt or NULL */ 588 int (*checkkey)(int,int) /* routine to check keystroke or NULL */ 589 ) 590 /* return is: n>=0 for choice n selected, 591 -1 for escape 592 k for checkkey routine return value k (if not 0 nor -1) 593 speedstring[0] != 0 on return if string is present 594 */ 595 { 596 597 int titlelines,titlewidth; 598 int reqdrows; 599 int topleftrow,topleftcol; 600 int topleftchoice; 601 int speedrow = 0; /* speed key prompt */ 602 int boxitems; /* boxwidth*boxdepth */ 603 int curkey,increment,rev_increment = 0; 604 int redisplay; 605 int i,j,k = 0; 606 char far *charptr; 607 char buf[81]; 608 char curitem[81]; 609 char far *itemptr; 610 int ret,savelookatmouse; 611 int scrunch; /* scrunch up a line */ 612 613 if(options&CHOICESCRUNCH) 614 scrunch = 1; 615 else 616 scrunch = 0; 617 savelookatmouse = lookatmouse; 618 lookatmouse = 0; 619 ret = -1; 620 if (speedstring 621 && (i = strlen(speedstring)) > 0) { /* preset current to passed string */ 622 current = 0; 623 if(options&CHOICESNOTSORTED) 624 { 625 while (current < numchoices 626 && (k = strncasecmp(speedstring,choices[current],i)) != 0) 627 ++current; 628 if(k != 0) 629 current = 0; 630 } 631 else 632 { 633 while (current < numchoices 634 && (k = strncasecmp(speedstring,choices[current],i)) > 0) 635 ++current; 636 if (k < 0 && current > 0) /* oops - overshot */ 637 --current; 638 } 639 if (current >= numchoices) /* bumped end of list */ 640 current = numchoices - 1; 641 } 642 643 for(;;) { 644 if (current >= numchoices) /* no real choice in the list? */ 645 goto fs_choice_end; 646 if ((attributes[current] & 256) == 0) 647 break; 648 ++current; /* scan for a real choice */ 649 } 650 651 titlelines = titlewidth = 0; 652 if (hdg) { 653 charptr = hdg; /* count title lines, find widest */ 654 i = 0; 655 titlelines = 1; 656 while (*charptr) { 657 if (*(charptr++) == '\n') { 658 ++titlelines; 659 i = -1; 660 } 661 if (++i > titlewidth) 662 titlewidth = i; 663 } 664 } 665 666 if (colwidth == 0) /* find widest column */ 667 for (i = 0; i < numchoices; ++i) 668 { 669 int len; 670 if ((len=far_strlen(choices[i])) > colwidth) 671 colwidth = len; 672 } 673 /* title(1), blank(1), hdg(n), blank(1), body(n), blank(1), instr(?) */ 674 reqdrows = 3 - scrunch; /* calc rows available */ 675 if (hdg) 676 reqdrows += titlelines + 1; 677 if (instr) { /* count instructions lines */ 678 charptr = instr; 679 ++reqdrows; 680 while (*charptr) 681 if (*(charptr++) == '\n') 682 ++reqdrows; 683 if ((options & 8)) /* show std instr too */ 684 reqdrows += 2; 685 } 686 else 687 reqdrows += 2; /* standard instructions */ 688 if (speedstring) ++reqdrows; /* a row for speedkey prompt */ 689 if (boxdepth > (i = 25 - reqdrows)) /* limit the depth to max */ 690 boxdepth = i; 691 if (boxwidth == 0) { /* pick box width and depth */ 692 if (numchoices <= i - 2) { /* single column is 1st choice if we can */ 693 boxdepth = numchoices; 694 boxwidth = 1; 695 } 696 else { /* sort-of-wide is 2nd choice */ 697 boxwidth = 60 / (colwidth + 1); 698 if (boxwidth == 0 699 || (boxdepth = (numchoices+boxwidth-1)/boxwidth) > i - 2) { 700 boxwidth = 80 / (colwidth + 1); /* last gasp, full width */ 701 if ((boxdepth = (numchoices+boxwidth-1)/boxwidth) > i) 702 boxdepth = i; 703 } 704 } 705 } 706 #if 0
707 if ((i = 77 / boxwidth - colwidth) > 3) /* spaces to add @ left each choice */ 708 i = 3; 709 if (i == 0) 710 i = 1;
711 #else 712 if ((i = (80 / boxwidth - colwidth) / 2 - 1) == 0) /* to allow wider prompts */ 713 i = 1; 714 if (i < 0) 715 i = 0; 716 if (i > 3) 717 i = 3; 718 #endif 719 j = boxwidth * (colwidth += i) + i; /* overall width of box */ 720 if (j < titlewidth+2) 721 j = titlewidth + 2; 722 if (j > 80) 723 j = 80; 724 if (j <= 70 && boxwidth == 2) { /* special case makes menus nicer */ 725 ++j; 726 ++colwidth; 727 } 728 k = (80 - j) / 2; /* center the box */ 729 k -= (90 - j) / 20; 730 topleftcol = k + i; /* column of topleft choice */ 731 i = (25 - reqdrows - boxdepth) / 2; 732 i -= i / 4; /* higher is better if lots extra */ 733 topleftrow = 3 + titlelines + i; /* row of topleft choice */ 734 735 /* now set up the overall display */ 736 helptitle(); /* clear, display title line */ 737 setattr(1,0,C_PROMPT_BKGRD,24*80); /* init rest to background */ 738 for (i = topleftrow-1-titlelines; i < topleftrow+boxdepth+1; ++i) 739 setattr(i,k,C_PROMPT_LO,j); /* draw empty box */ 740 if (hdg) { 741 textcbase = (80 - titlewidth) / 2; /* set left margin for putstring */ 742 textcbase -= (90 - titlewidth) / 20; /* put heading into box */ 743 putstring(topleftrow-titlelines-1,0,C_PROMPT_HI,hdg); 744 textcbase = 0; 745 } 746 if (hdg2) /* display 2nd heading */ 747 putstring(topleftrow-1,topleftcol,C_PROMPT_MED,hdg2); 748 i = topleftrow + boxdepth + 1; 749 if (instr == NULL || (options & 8)) { /* display default instructions */ 750 if (i < 20) ++i; 751 if (speedstring) { 752 speedrow = i; 753 *speedstring = 0; 754 if (++i < 22) ++i; 755 } 756 i -= scrunch; 757 footer_msg(&i,options,speedstring); 758 } 759 if (instr) { /* display caller's instructions */ 760 charptr = instr; 761 j = -1; 762 while ((buf[++j] = *(charptr++)) != 0) 763 if (buf[j] == '\n') { 764 buf[j] = 0; 765 putstringcenter(i++,0,80,C_PROMPT_BKGRD,buf); 766 j = -1; 767 } 768 putstringcenter(i,0,80,C_PROMPT_BKGRD,buf); 769 } 770 771 boxitems = boxwidth * boxdepth; 772 topleftchoice = 0; /* pick topleft for init display */ 773 while (current - topleftchoice >= boxitems 774 || (current - topleftchoice > boxitems/2 775 && topleftchoice + boxitems < numchoices)) 776 topleftchoice += boxwidth; 777 redisplay = 1; 778 topleftrow -= scrunch; 779 for(;;) { /* main loop */ 780 if (redisplay) { /* display the current choices */ 781 if ((options & CHOICEMENU) == 0) { 782 memset(buf,' ',80); 783 buf[boxwidth*colwidth] = 0; 784 for (i = (hdg2) ? 0 : -1; i <= boxdepth; ++i) /* blank the box */ 785 putstring(topleftrow+i,topleftcol,C_PROMPT_LO,buf); 786 } 787 for (i = 0; i+topleftchoice < numchoices && i < boxitems; ++i) { 788 /* display the choices */ 789 if ((k = attributes[j = i+topleftchoice] & 3) == 1) 790 k = C_PROMPT_LO; 791 else if (k == 3) 792 k = C_PROMPT_HI; 793 else 794 k = C_PROMPT_MED; 795 if (formatitem) 796 { 797 (*formatitem)(j,buf); 798 charptr=buf; 799 } 800 else 801 charptr = choices[j]; 802 putstring(topleftrow+i/boxwidth,topleftcol+(i%boxwidth)*colwidth, 803 k,charptr); 804 } 805 /*** 806 ... format differs for summary/detail, whups, force box width to 807 ... be 72 when detail toggle available? (2 grey margin each 808 ... side, 1 blue margin each side) 809 ***/ 810 if (topleftchoice > 0 && hdg2 == NULL) 811 putstring(topleftrow-1,topleftcol,C_PROMPT_LO,"(more)"); 812 if (topleftchoice + boxitems < numchoices) 813 putstring(topleftrow+boxdepth,topleftcol,C_PROMPT_LO,"(more)"); 814 redisplay = 0; 815 } 816 817 i = current - topleftchoice; /* highlight the current choice */ 818 if (formatitem) 819 { 820 (*formatitem)(current,curitem); 821 itemptr=curitem; 822 } 823 else 824 itemptr = choices[current]; 825 putstring(topleftrow+i/boxwidth,topleftcol+(i%boxwidth)*colwidth, 826 C_CHOICE_CURRENT,itemptr); 827 828 if (speedstring) { /* show speedstring if any */ 829 show_speedstring(speedrow,speedstring,speedprompt); 830 } 831 else 832 movecursor(25,80); 833 834 #ifndef XFRACT 835 while (!keypressed()) { } /* enables help */
836 #else 837 waitkeypressed(0); /* enables help */
838 #endif 839 curkey = getakey(); 840 #ifdef XFRACT
841 if (curkey==F10) curkey=')'; 842 if (curkey==F9) curkey='('; 843 if (curkey==F8) curkey='*';
844 #endif 845 846 i = current - topleftchoice; /* unhighlight current choice */ 847 if ((k = attributes[current] & 3) == 1) 848 k = C_PROMPT_LO; 849 else if (k == 3) 850 k = C_PROMPT_HI; 851 else 852 k = C_PROMPT_MED; 853 putstring(topleftrow+i/boxwidth,topleftcol+(i%boxwidth)*colwidth, 854 k,itemptr); 855 856 increment = 0; 857 switch (curkey) { /* deal with input key */ 858 case ENTER: 859 case ENTER_2: 860 ret = current; 861 goto fs_choice_end; 862 case ESC: 863 goto fs_choice_end; 864 case DOWN_ARROW: 865 rev_increment = 0 - (increment = boxwidth); 866 break; 867 case DOWN_ARROW_2: 868 rev_increment = 0 - (increment = boxwidth); 869 { 870 int newcurrent = current; 871 while((newcurrent+=boxwidth) != current) { 872 if(newcurrent >= numchoices) 873 newcurrent = (newcurrent % boxwidth) - boxwidth; 874 else if(!isadirname(choices[newcurrent])) { 875 if(current != newcurrent) 876 current = newcurrent - boxwidth; 877 break; /* breaks the while loop */ 878 } 879 } 880 } 881 break; 882 case UP_ARROW: 883 increment = 0 - (rev_increment = boxwidth); 884 break; 885 case UP_ARROW_2: 886 increment = 0 - (rev_increment = boxwidth); 887 { 888 int newcurrent = current; 889 while((newcurrent-=boxwidth) != current) { 890 if(newcurrent < 0) { 891 newcurrent = (numchoices - current) % boxwidth; 892 newcurrent = numchoices + (newcurrent ? boxwidth - newcurrent: 0); 893 } 894 else if(!isadirname(choices[newcurrent])) { 895 if(current != newcurrent) 896 current = newcurrent + boxwidth; 897 break; /* breaks the while loop */ 898 } 899 } 900 } 901 break; 902 case RIGHT_ARROW: 903 increment = 1; rev_increment = -1; 904 break; 905 case RIGHT_ARROW_2: /* move to next file; if at last file, go to 906 first file */ 907 increment = 1; rev_increment = -1; 908 { 909 int newcurrent = current; 910 while(++newcurrent != current) { 911 if(newcurrent >= numchoices) 912 newcurrent = -1; 913 else if(!isadirname(choices[newcurrent])) { 914 if(current != newcurrent) 915 current = newcurrent - 1; 916 break; /* breaks the while loop */ 917 } 918 } 919 } 920 break; 921 case LEFT_ARROW: 922 increment = -1; rev_increment = 1; 923 break; 924 case LEFT_ARROW_2: /* move to previous file; if at first file, go to 925 last file */ 926 increment = -1; rev_increment = 1; 927 { 928 int newcurrent = current; 929 while(--newcurrent != current) { 930 if(newcurrent < 0) 931 newcurrent = numchoices; 932 else if(!isadirname(choices[newcurrent])) { 933 if(current != newcurrent) 934 current = newcurrent + 1; 935 break; /* breaks the while loop */ 936 } 937 } 938 } 939 break; 940 case PAGE_UP: 941 if (numchoices > boxitems) { 942 topleftchoice -= boxitems; 943 increment = -boxitems; 944 rev_increment = boxwidth; 945 redisplay = 1; 946 } 947 break; 948 case PAGE_DOWN: 949 if (numchoices > boxitems) { 950 topleftchoice += boxitems; 951 increment = boxitems; 952 rev_increment = -boxwidth; 953 redisplay = 1; 954 } 955 break; 956 case HOME: 957 current = -1; 958 increment = rev_increment = 1; 959 break; 960 case CTL_HOME: 961 current = -1; 962 increment = rev_increment = 1; 963 { 964 int newcurrent; 965 for(newcurrent = 0; newcurrent < numchoices; ++newcurrent) { 966 if(!isadirname(choices[newcurrent])) { 967 current = newcurrent - 1; 968 break; /* breaks the for loop */ 969 } 970 } 971 } 972 break; 973 case END: 974 current = numchoices; 975 increment = rev_increment = -1; 976 break; 977 case CTL_END: 978 current = numchoices; 979 increment = rev_increment = -1; 980 { 981 int newcurrent; 982 for(newcurrent = numchoices - 1; newcurrent >= 0; --newcurrent) { 983 if(!isadirname(choices[newcurrent])) { 984 current = newcurrent + 1; 985 break; /* breaks the for loop */ 986 } 987 } 988 } 989 break; 990 default: 991 if (checkkey) { 992 if ((ret = (*checkkey)(curkey,current)) < -1 || ret > 0) 993 goto fs_choice_end; 994 if (ret == -1) 995 redisplay = -1; 996 } 997 ret = -1; 998 if (speedstring) { 999 process_speedstring(speedstring,choices,curkey,&current, 1000 numchoices,options&CHOICESNOTSORTED); 1001 } 1002 break; 1003 } 1004 if (increment) { /* apply cursor movement */ 1005 current += increment; 1006 if (speedstring) /* zap speedstring */ 1007 speedstring[0] = 0; 1008 } 1009 for(;;) { /* adjust to a non-comment choice */ 1010 if (current < 0 || current >= numchoices) 1011 increment = rev_increment; 1012 else if ((attributes[current] & 256) == 0) 1013 break; 1014 current += increment; 1015 } 1016 if (topleftchoice > numchoices - boxitems) 1017 topleftchoice = ((numchoices+boxwidth-1)/boxwidth)*boxwidth - boxitems; 1018 if (topleftchoice < 0) 1019 topleftchoice = 0; 1020 while (current < topleftchoice) { 1021 topleftchoice -= boxwidth; 1022 redisplay = 1; 1023 } 1024 while (current >= topleftchoice + boxitems) { 1025 topleftchoice += boxwidth; 1026 redisplay = 1; 1027 } 1028 } 1029 1030 fs_choice_end: 1031 lookatmouse = savelookatmouse; 1032 return(ret); 1033 1034 } 1035 1036 #if (_MSC_VER >= 700) 1037 #pragma code_seg ("realdos1_text") /* place following in an overlay */ 1038 #endif 1039 1040 /* squeeze space out of string */ 1041 char *despace(char *str) 1042 { 1043 char *obuf, *nbuf; 1044 1045 for (obuf = str, nbuf = str; *obuf && obuf; ++obuf) 1046 { 1047 if (!isspace(*obuf)) 1048 *nbuf++ = *obuf; 1049 } 1050 *nbuf = 0; 1051 return str; 1052 } 1053 1054 #ifndef XFRACT 1055 /* case independent version of strncmp */ 1056 int strncasecmp(char far *s,char far *t,int ct) 1057 { 1058 for(; (tolower(*s) == tolower(*t)) && --ct ; s++,t++) 1059 if(*s == '\0') 1060 return(0); 1061 return(tolower(*s) - tolower(*t)); 1062 } 1063 #endif 1064 1065 #define LOADPROMPTSCHOICES(X,Y) {\ 1066 static FCODE tmp[] = { Y };\ 1067 choices[X]= (char far *)tmp;\ 1068 } 1069 1070 static int menutype; 1071 #define MENU_HDG 3 1072 #define MENU_ITEM 1 1073 1074 int main_menu(int fullmenu) 1075 { 1076 char far *choices[44]; /* 2 columns * 22 rows */ 1077 int attributes[44]; 1078 int choicekey[44]; 1079 int i; 1080 int nextleft,nextright; 1081 int oldtabmode /* ,oldhelpmode */; 1082 static char far MAIN_MENU[] = {"MAIN MENU"}; 1083 int showjuliatoggle; 1084 oldtabmode = tabmode; 1085 /* oldhelpmode = helpmode; */ 1086 top: 1087 menutype = fullmenu; 1088 tabmode = 0; 1089 showjuliatoggle = 0; 1090 for (i = 0; i < 44; ++i) { 1091 attributes[i] = 256; 1092 choices[i] = ""; 1093 choicekey[i] = -1; 1094 } 1095 nextleft = -2; 1096 nextright = -1; 1097 1098 if (fullmenu) { 1099 LOADPROMPTSCHOICES(nextleft+=2," CURRENT IMAGE "); 1100 attributes[nextleft] = 256+MENU_HDG; 1101 choicekey[nextleft+=2] = 13; /* enter */ 1102 attributes[nextleft] = MENU_ITEM; 1103 if (calc_status == 2) 1104 { 1105 LOADPROMPTSCHOICES(nextleft,"continue calculation "); 1106 } 1107 else 1108 { 1109 LOADPROMPTSCHOICES(nextleft,"return to image "); 1110 } 1111 choicekey[nextleft+=2] = 9; /* tab */ 1112 attributes[nextleft] = MENU_ITEM; 1113 LOADPROMPTSCHOICES(nextleft,"info about image <tab> "); 1114 choicekey[nextleft+=2] = 'o'; 1115 attributes[nextleft] = MENU_ITEM; 1116 LOADPROMPTSCHOICES(nextleft,"orbits window <o> "); 1117 if(!(fractype==JULIA || fractype==JULIAFP || fractype==INVERSEJULIA)) 1118 nextleft+=2; 1119 } 1120 LOADPROMPTSCHOICES(nextleft+=2," NEW IMAGE "); 1121 attributes[nextleft] = 256+MENU_HDG; 1122 #ifdef XFRACT
1123 choicekey[nextleft+=2] = DELETE; 1124 attributes[nextleft] = MENU_ITEM; 1125 LOADPROMPTSCHOICES(nextleft,"draw fractal <D> ");
1126 #else 1127 choicekey[nextleft+=2] = DELETE; 1128 attributes[nextleft] = MENU_ITEM; 1129 LOADPROMPTSCHOICES(nextleft,"select video mode... <del> "); 1130 #endif 1131 choicekey[nextleft+=2] = 't'; 1132 attributes[nextleft] = MENU_ITEM; 1133 LOADPROMPTSCHOICES(nextleft,"select fractal type <t> "); 1134 if (fullmenu) { 1135 if ((curfractalspecific->tojulia != NOFRACTAL 1136 && param[0] == 0.0 && param[1] == 0.0) 1137 || curfractalspecific->tomandel != NOFRACTAL) { 1138 choicekey[nextleft+=2] = ' '; 1139 attributes[nextleft] = MENU_ITEM; 1140 LOADPROMPTSCHOICES(nextleft,"toggle to/from julia <space>"); 1141 showjuliatoggle = 1; 1142 } 1143 if(fractype==JULIA || fractype==JULIAFP || fractype==INVERSEJULIA) { 1144 choicekey[nextleft+=2] = 'j'; 1145 attributes[nextleft] = MENU_ITEM; 1146 LOADPROMPTSCHOICES(nextleft,"toggle to/from inverse <j> "); 1147 showjuliatoggle = 1; 1148 } 1149 choicekey[nextleft+=2] = 'h'; 1150 attributes[nextleft] = MENU_ITEM; 1151 LOADPROMPTSCHOICES(nextleft,"return to prior image <h> "); 1152 1153 choicekey[nextleft+=2] = 8; 1154 attributes[nextleft] = MENU_ITEM; 1155 LOADPROMPTSCHOICES(nextleft,"reverse thru history <ctl-h> "); 1156 } 1157 else 1158 nextleft += 2; 1159 LOADPROMPTSCHOICES(nextleft+=2," OPTIONS "); 1160 attributes[nextleft] = 256+MENU_HDG; 1161 choicekey[nextleft+=2] = 'x'; 1162 attributes[nextleft] = MENU_ITEM; 1163 LOADPROMPTSCHOICES(nextleft,"basic options... <x> "); 1164 choicekey[nextleft+=2] = 'y'; 1165 attributes[nextleft] = MENU_ITEM; 1166 LOADPROMPTSCHOICES(nextleft,"extended options... <y> "); 1167 choicekey[nextleft+=2] = 'z'; 1168 attributes[nextleft] = MENU_ITEM; 1169 LOADPROMPTSCHOICES(nextleft,"type-specific parms... <z> "); 1170 choicekey[nextleft+=2] = 'p'; 1171 attributes[nextleft] = MENU_ITEM; 1172 LOADPROMPTSCHOICES(nextleft,"passes options... <p> "); 1173 choicekey[nextleft+=2] = 'v'; 1174 attributes[nextleft] = MENU_ITEM; 1175 LOADPROMPTSCHOICES(nextleft,"view window options... <v> "); 1176 if(showjuliatoggle == 0) 1177 { 1178 choicekey[nextleft+=2] = 'i'; 1179 attributes[nextleft] = MENU_ITEM; 1180 LOADPROMPTSCHOICES(nextleft,"fractal 3D parms... <i> "); 1181 } 1182 choicekey[nextleft+=2] = 2; 1183 attributes[nextleft] = MENU_ITEM; 1184 LOADPROMPTSCHOICES(nextleft,"browse parms... <ctl-b>"); 1185 1186 if (fullmenu) { 1187 choicekey[nextleft+=2] = 5; 1188 attributes[nextleft] = MENU_ITEM; 1189 LOADPROMPTSCHOICES(nextleft,"evolver parms... <ctl-e>"); 1190 } 1191 #ifndef XFRACT 1192 if (fullmenu) { 1193 choicekey[nextleft+=2] = 6; 1194 attributes[nextleft] = MENU_ITEM; 1195 LOADPROMPTSCHOICES(nextleft,"sound parms... <ctl-f>"); 1196 } 1197 #endif 1198 LOADPROMPTSCHOICES(nextright+=2," FILE "); 1199 attributes[nextright] = 256+MENU_HDG; 1200 choicekey[nextright+=2] = '@'; 1201 attributes[nextright] = MENU_ITEM; 1202 LOADPROMPTSCHOICES(nextright,"run saved command set... <@> "); 1203 if (fullmenu) { 1204 choicekey[nextright+=2] = 's'; 1205 attributes[nextright] = MENU_ITEM; 1206 LOADPROMPTSCHOICES(nextright,"save image to file <s> "); 1207 } 1208 choicekey[nextright+=2] = 'r'; 1209 attributes[nextright] = MENU_ITEM; 1210 LOADPROMPTSCHOICES(nextright,"load image from file... <r> "); 1211 choicekey[nextright+=2] = '3'; 1212 attributes[nextright] = MENU_ITEM; 1213 LOADPROMPTSCHOICES(nextright,"3d transform from file...<3> "); 1214 if (fullmenu) { 1215 choicekey[nextright+=2] = '#'; 1216 attributes[nextright] = MENU_ITEM; 1217 LOADPROMPTSCHOICES(nextright,"3d overlay from file.....<#> "); 1218 choicekey[nextright+=2] = 'b'; 1219 attributes[nextright] = MENU_ITEM; 1220 LOADPROMPTSCHOICES(nextright,"save current parameters..<b> "); 1221 choicekey[nextright+=2] = 16; 1222 attributes[nextright] = MENU_ITEM; 1223 LOADPROMPTSCHOICES(nextright,"print image <ctl-p> "); 1224 } 1225 #ifdef XFRACT
1226 choicekey[nextright+=2] = 'd'; 1227 attributes[nextright] = MENU_ITEM; 1228 LOADPROMPTSCHOICES(nextright,"shell to Linux/Unix <d> ");
1229 #else 1230 choicekey[nextright+=2] = 'd'; 1231 attributes[nextright] = MENU_ITEM; 1232 LOADPROMPTSCHOICES(nextright,"shell to dos <d> "); 1233 #endif 1234 choicekey[nextright+=2] = 'g'; 1235 attributes[nextright] = MENU_ITEM; 1236 LOADPROMPTSCHOICES(nextright,"give command string <g> "); 1237 choicekey[nextright+=2] = ESC; 1238 attributes[nextright] = MENU_ITEM; 1239 LOADPROMPTSCHOICES(nextright,"quit "FRACTINT" <esc> "); 1240 choicekey[nextright+=2] = INSERT; 1241 attributes[nextright] = MENU_ITEM; 1242 LOADPROMPTSCHOICES(nextright,"restart "FRACTINT" <ins> "); 1243 #ifdef XFRACT
1244 if (fullmenu && (gotrealdac || fake_lut) && colors >= 16) {
1245 #else 1246 if (fullmenu && gotrealdac && colors >= 16) { 1247 #endif 1248 /* nextright += 2; */ 1249 LOADPROMPTSCHOICES(nextright+=2," COLORS "); 1250 attributes[nextright] = 256+MENU_HDG; 1251 choicekey[nextright+=2] = 'c'; 1252 attributes[nextright] = MENU_ITEM; 1253 LOADPROMPTSCHOICES(nextright,"color cycling mode <c> "); 1254 choicekey[nextright+=2] = '+'; 1255 attributes[nextright] = MENU_ITEM; 1256 LOADPROMPTSCHOICES(nextright,"rotate palette <+>, <-> "); 1257 if (colors > 16) { 1258 if (!reallyega) { 1259 choicekey[nextright+=2] = 'e'; 1260 attributes[nextright] = MENU_ITEM; 1261 LOADPROMPTSCHOICES(nextright,"palette editing mode <e> "); 1262 } 1263 choicekey[nextright+=2] = 'a'; 1264 attributes[nextright] = MENU_ITEM; 1265 LOADPROMPTSCHOICES(nextright,"make starfield <a> "); 1266 } 1267 } 1268 choicekey[nextright+=2] = 1; 1269 attributes[nextright] = MENU_ITEM; 1270 LOADPROMPTSCHOICES(nextright, "ant automaton <ctl-a>"); 1271 1272 choicekey[nextright+=2] = 19; 1273 attributes[nextright] = MENU_ITEM; 1274 LOADPROMPTSCHOICES(nextright, "stereogram <ctl-s>"); 1275 1276 i = (keypressed()) ? getakey() : 0; 1277 if (menu_checkkey(i,0) == 0) { 1278 helpmode = HELPMAIN; /* switch help modes */ 1279 if ((nextleft += 2) < nextright) 1280 nextleft = nextright + 1; 1281 i = fullscreen_choice(CHOICEMENU+CHOICESCRUNCH, 1282 MAIN_MENU, 1283 NULL,NULL,nextleft,(char far * far *)choices,attributes, 1284 2,nextleft/2,29,0,NULL,NULL,NULL,menu_checkkey); 1285 if (i == -1) /* escape */ 1286 i = ESC; 1287 else if (i < 0) 1288 i = 0 - i; 1289 else { /* user selected a choice */ 1290 i = choicekey[i]; 1291 switch (i) { /* check for special cases */ 1292 case -10: /* zoombox functions */ 1293 helpmode = HELPZOOM; 1294 help(0); 1295 i = 0; 1296 break; 1297 } 1298 } 1299 } 1300 if (i == ESC) { /* escape from menu exits Fractint */ 1301 #ifdef XFRACT
1302 static char far s[] = "Exit from Xfractint (y/n)? y";
1303 #else 1304 static char far s[] = "Exit from Fractint (y/n)? y"; 1305 #endif 1306 helptitle(); 1307 setattr(1,0,C_GENERAL_MED,24*80); 1308 for (i = 9; i <= 11; ++i) 1309 setattr(i,18,C_GENERAL_INPUT,40); 1310 putstringcenter(10,18,40,C_GENERAL_INPUT,s); 1311 movecursor(25,80); 1312 while ((i = getakey()) != 'y' && i != 'Y' && i != 13) { 1313 if (i == 'n' || i == 'N') 1314 goto top; 1315 } 1316 goodbye(); 1317 } 1318 if (i == TAB) { 1319 tab_display(); 1320 i = 0; 1321 } 1322 if (i == ENTER || i == ENTER_2) 1323 i = 0; /* don't trigger new calc */ 1324 tabmode = oldtabmode; 1325 return(i); 1326 } 1327 1328 #if (_MSC_VER >= 700) 1329 #pragma code_seg () /* back to normal segment */ 1330 #endif 1331 1332 static int menu_checkkey(int curkey,int choice) 1333 { /* choice is dummy used by other routines called by fullscreen_choice() */ 1334 int testkey; 1335 testkey = choice; /* for warning only */ 1336 testkey = (curkey>='A' && curkey<='Z') ? curkey+('a'-'A') : curkey; 1337 #ifdef XFRACT
1338 /* We use F2 for shift-@, annoyingly enough */ 1339 if (testkey == F2) return(0-testkey);
1340 #endif 1341 if(testkey == '2') 1342 testkey = '@'; 1343 if (strchr("#@2txyzgvir3dj",testkey) || testkey == INSERT || testkey == 2 1344 || testkey == ESC || testkey == DELETE || testkey == 6) /*RB 6== ctrl-F for sound menu */ 1345 return(0-testkey); 1346 if (menutype) { 1347 if (strchr("\\sobpkrh",testkey) || testkey == TAB 1348 || testkey == 1 || testkey == 5 || testkey == 8 1349 || testkey == 16 1350 || testkey == 19 || testkey == 21) /* ctrl-A, E, H, P, S, U */ 1351 return(0-testkey); 1352 if (testkey == ' ') 1353 if ((curfractalspecific->tojulia != NOFRACTAL 1354 && param[0] == 0.0 && param[1] == 0.0) 1355 || curfractalspecific->tomandel != NOFRACTAL) 1356 return(0-testkey); 1357 if (gotrealdac && colors >= 16) { 1358 if (strchr("c+-",testkey)) 1359 return(0-testkey); 1360 if (colors > 16 1361 && (testkey == 'a' || (!reallyega && testkey == 'e'))) 1362 return(0-testkey); 1363 } 1364 /* Alt-A and Alt-S */ 1365 if (testkey == 1030 || testkey == 1031 ) 1366 return(0-testkey); 1367 } 1368 if (check_vidmode_key(0,testkey) >= 0) 1369 return(0-testkey); 1370 return(0); 1371 } 1372 1373 1374 int input_field( 1375 int options, /* &1 numeric, &2 integer, &4 double */ 1376 int attr, /* display attribute */ 1377 char *fld, /* the field itself */ 1378 int len, /* field length (declare as 1 larger for \0) */ 1379 int row, /* display row */ 1380 int col, /* display column */ 1381 int (*checkkey)(int) /* routine to check non data keys, or NULL */ 1382 ) 1383 { 1384 char savefld[81]; 1385 char buf[81]; 1386 int insert, started, offset, curkey, display; 1387 int i, j; 1388 int ret,savelookatmouse; 1389 savelookatmouse = lookatmouse; 1390 lookatmouse = 0; 1391 ret = -1; 1392 strcpy(savefld,fld); 1393 insert = started = offset = 0; 1394 display = 1; 1395 for(;;) { 1396 strcpy(buf,fld); 1397 i = strlen(buf); 1398 while (i < len) 1399 buf[i++] = ' '; 1400 buf[len] = 0; 1401 if (display) { /* display current value */ 1402 putstring(row,col,attr,buf); 1403 display = 0; 1404 } 1405 curkey = keycursor(row+insert,col+offset); /* get a keystroke */ 1406 if(curkey == 1047) curkey = 47; /* numeric slash */ 1407 switch (curkey) { 1408 case ENTER: 1409 case ENTER_2: 1410 ret = 0; 1411 goto inpfld_end; 1412 case ESC: 1413 goto inpfld_end; 1414 case RIGHT_ARROW: 1415 if (offset < len-1) ++offset; 1416 started = 1; 1417 break; 1418 case LEFT_ARROW: 1419 if (offset > 0) --offset; 1420 started = 1; 1421 break; 1422 case HOME: 1423 offset = 0; 1424 started = 1; 1425 break; 1426 case END: 1427 offset = strlen(fld); 1428 started = 1; 1429 break; 1430 case 8: 1431 case 127: /* backspace */ 1432 if (offset > 0) { 1433 j = strlen(fld); 1434 for (i = offset-1; i < j; ++i) 1435 fld[i] = fld[i+1]; 1436 --offset; 1437 } 1438 started = display = 1; 1439 break; 1440 case DELETE: /* delete */ 1441 j = strlen(fld); 1442 for (i = offset; i < j; ++i) 1443 fld[i] = fld[i+1]; 1444 started = display = 1; 1445 break; 1446 case INSERT: /* insert */ 1447 insert ^= 0x8000; 1448 started = 1; 1449 break; 1450 case F5: 1451 strcpy(fld,savefld); 1452 insert = started = offset = 0; 1453 display = 1; 1454 break; 1455 default: 1456 if (nonalpha(curkey)) { 1457 if (checkkey && (ret = (*checkkey)(curkey)) != 0) 1458 goto inpfld_end; 1459 break; /* non alphanum char */ 1460 } 1461 if (offset >= len) break; /* at end of field */ 1462 if (insert && started && strlen(fld) >= (size_t)len) 1463 break; /* insert & full */ 1464 if ((options & 1) 1465 && (curkey < '0' || curkey > '9') 1466 && curkey != '+' && curkey != '-') { 1467 if ((options & 2)) 1468 break; 1469 /* allow scientific notation, and specials "e" and "p" */ 1470 if ( ((curkey != 'e' && curkey != 'E') || offset >= 18) 1471 && ((curkey != 'p' && curkey != 'P') || offset != 0 ) 1472 && curkey != '.') 1473 break; 1474 } 1475 if (started == 0) /* first char is data, zap field */ 1476 fld[0] = 0; 1477 if (insert) { 1478 j = strlen(fld); 1479 while (j >= offset) { 1480 fld[j+1] = fld[j]; 1481 --j; 1482 } 1483 } 1484 if ((size_t)offset >= strlen(fld)) 1485 fld[offset+1] = 0; 1486 fld[offset++] = (char)curkey; 1487 /* if "e" or "p" in first col make number e or pi */ 1488 if ((options & 3) == 1) { /* floating point */ 1489 double tmpd; 1490 int specialv; 1491 char tmpfld[30]; 1492 specialv = 0; 1493 if (*fld == 'e' || *fld == 'E') { 1494 tmpd = exp(1.0); 1495 specialv = 1; 1496 } 1497 if (*fld == 'p' || *fld == 'P') { 1498 tmpd = atan(1.0) * 4; 1499 specialv = 1; 1500 } 1501 if (specialv) { 1502 if ((options & 4) == 0) 1503 roundfloatd(&tmpd); 1504 sprintf(tmpfld,"%.15g",tmpd); 1505 tmpfld[len-1] = 0; /* safety, field should be long enough */ 1506 strcpy(fld,tmpfld); 1507 offset = 0; 1508 } 1509 } 1510 started = display = 1; 1511 } 1512 } 1513 inpfld_end: 1514 lookatmouse = savelookatmouse; 1515 return(ret); 1516 } 1517 1518 int field_prompt( 1519 int options, /* &1 numeric value, &2 integer */ 1520 char far *hdg, /* heading, \n delimited lines */ 1521 char far *instr, /* additional instructions or NULL */ 1522 char *fld, /* the field itself */ 1523 int len, /* field length (declare as 1 larger for \0) */ 1524 int (*checkkey)(int) /* routine to check non data keys, or NULL */ 1525 ) 1526 { 1527 char far *charptr; 1528 int boxwidth,titlelines,titlecol,titlerow; 1529 int promptcol; 1530 int i,j; 1531 char buf[81]; 1532 static char far DEFLT_INST[] = {"Press ENTER when finished (or ESCAPE to back out)"}; 1533 helptitle(); /* clear screen, display title */ 1534 setattr(1,0,C_PROMPT_BKGRD,24*80); /* init rest to background */ 1535 charptr = hdg; /* count title lines, find widest */ 1536 i = boxwidth = 0; 1537 titlelines = 1; 1538 while (*charptr) { 1539 if (*(charptr++) == '\n') { 1540 ++titlelines; 1541 i = -1; 1542 } 1543 if (++i > boxwidth) 1544 boxwidth = i; 1545 } 1546 if (len > boxwidth) 1547 boxwidth = len; 1548 i = titlelines + 4; /* total rows in box */ 1549 titlerow = (25 - i) / 2; /* top row of it all when centered */ 1550 titlerow -= titlerow / 4; /* higher is better if lots extra */ 1551 titlecol = (80 - boxwidth) / 2; /* center the box */ 1552 titlecol -= (90 - boxwidth) / 20; 1553 promptcol = titlecol - (boxwidth-len)/2; 1554 j = titlecol; /* add margin at each side of box */ 1555 if ((i = (82-boxwidth)/4) > 3) 1556 i = 3; 1557 j -= i; 1558 boxwidth += i * 2; 1559 for (i = -1; i < titlelines+3; ++i) /* draw empty box */ 1560 setattr(titlerow+i,j,C_PROMPT_LO,boxwidth); 1561 textcbase = titlecol; /* set left margin for putstring */ 1562 putstring(titlerow,0,C_PROMPT_HI,hdg); /* display heading */ 1563 textcbase = 0; 1564 i = titlerow + titlelines + 4; 1565 if (instr) { /* display caller's instructions */ 1566 charptr = instr; 1567 j = -1; 1568 while ((buf[++j] = *(charptr++)) != 0) 1569 if (buf[j] == '\n') { 1570 buf[j] = 0; 1571 putstringcenter(i++,0,80,C_PROMPT_BKGRD,buf); 1572 j = -1; 1573 } 1574 putstringcenter(i,0,80,C_PROMPT_BKGRD,buf); 1575 } 1576 else /* default instructions */ 1577 putstringcenter(i,0,80,C_PROMPT_BKGRD,DEFLT_INST); 1578 return(input_field(options,C_PROMPT_INPUT,fld,len, 1579 titlerow+titlelines+1,promptcol,checkkey)); 1580 } 1581 1582 1583 /* thinking(1,message): 1584 if thinking message not yet on display, it is displayed; 1585 otherwise the wheel is updated 1586 returns 0 to keep going, -1 if keystroke pending 1587 thinking(0,NULL): 1588 call this when thinking phase is done 1589 */ 1590 1591 int thinking(int options,char far *msg) 1592 { 1593 static int thinkstate = -1; 1594 char *wheel[] = {"-","\\","|","/"}; 1595 static int thinkcol; 1596 static int count = 0; 1597 char buf[81]; 1598 if (options == 0) { 1599 if (thinkstate >= 0) { 1600 thinkstate = -1; 1601 unstackscreen(); 1602 } 1603 return(0); 1604 } 1605 if (thinkstate < 0) { 1606 stackscreen(); 1607 thinkstate = 0; 1608 helptitle(); 1609 strcpy(buf," "); 1610 far_strcat(buf,msg); 1611 strcat(buf," "); 1612 putstring(4,10,C_GENERAL_HI,buf); 1613 thinkcol = textcol - 3; 1614 count = 0; 1615 } 1616 if ((count++)<100) { 1617 return 0; 1618 } 1619 count = 0; 1620 putstring(4,thinkcol,C_GENERAL_HI,wheel[thinkstate]); 1621 movecursor(25,80); /* turn off cursor */ 1622 thinkstate = (thinkstate + 1) & 3; 1623 return (keypressed()); 1624 } 1625 1626 1627 void clear_screen(int dummy) /* a stub for a windows only subroutine */ 1628 { 1629 dummy=0; /* quite the warning */ 1630 } 1631 1632 1633 /* savegraphics/restoregraphics: video.asm subroutines */ 1634 1635 unsigned long swaptotlen; 1636 unsigned long swapoffset; 1637 BYTE far *swapvidbuf; 1638 int swaplength; 1639 1640 #define SWAPBLKLEN 4096 /* must be a power of 2 */ 1641 U16 memhandle = 0; 1642 1643 #ifdef XFRACT
1644 BYTE suffix[10000];
1645 #endif 1646 1647 #ifndef XFRACT 1648 1649 int savegraphics() 1650 { 1651 int i; 1652 long count; 1653 unsigned long swaptmpoff; 1654 1655 swaptotlen = (long)(vxdots > sxdots ? vxdots : sxdots) * (long)sydots; 1656 i = colors; 1657 while (i <= 16) { 1658 swaptotlen >>= 1; 1659 i = i * i; 1660 } 1661 count = (long)((swaptotlen / SWAPBLKLEN) + 1); 1662 swapoffset = 0; 1663 if (memhandle != 0) 1664 discardgraphics(); /* if any emm/xmm in use from prior call, release it */ 1665 memhandle = MemoryAlloc((U16)SWAPBLKLEN, count, EXPANDED); 1666 1667 while (swapoffset < swaptotlen) { 1668 swaplength = SWAPBLKLEN; 1669 if ((swapoffset & (SWAPBLKLEN-1)) != 0) 1670 swaplength = (int)(SWAPBLKLEN - (swapoffset & (SWAPBLKLEN-1))); 1671 if ((unsigned long)swaplength > (swaptotlen - swapoffset)) 1672 swaplength = (int)(swaptotlen - swapoffset); 1673 if (swapoffset == 0) 1674 swaptmpoff = 0; 1675 else 1676 swaptmpoff = swapoffset/swaplength; 1677 (*swapsetup)(); /* swapoffset,swaplength -> sets swapvidbuf,swaplength */ 1678 1679 MoveToMemory(swapvidbuf,(U16)swaplength,1L,swaptmpoff,memhandle); 1680 1681 swapoffset += swaplength; 1682 } 1683 return 0; 1684 } 1685 1686 int restoregraphics() 1687 { 1688 unsigned long swaptmpoff; 1689 1690 swapoffset = 0; 1691 swapvidbuf = MK_FP(extraseg+0x1000,0); /* for swapnormwrite case */ 1692 1693 while (swapoffset < swaptotlen) { 1694 swaplength = SWAPBLKLEN; 1695 if ((swapoffset & (SWAPBLKLEN-1)) != 0) 1696 swaplength = (int)(SWAPBLKLEN - (swapoffset & (SWAPBLKLEN-1))); 1697 if ((unsigned long)swaplength > (swaptotlen - swapoffset)) 1698 swaplength = (int)(swaptotlen - swapoffset); 1699 if (swapoffset == 0) 1700 swaptmpoff = 0; 1701 else 1702 swaptmpoff = swapoffset/swaplength; 1703 if (swapsetup != swapnormread) 1704 (*swapsetup)(); /* swapoffset,swaplength -> sets swapvidbuf,swaplength */ 1705 1706 MoveFromMemory(swapvidbuf,(U16)swaplength,1L,swaptmpoff,memhandle); 1707 1708 if (swapsetup == swapnormread) 1709 swapnormwrite(); 1710 swapoffset += swaplength; 1711 } 1712 1713 discardgraphics(); 1714 return(0); 1715 } 1716
1717 #else 1718 int savegraphics() {return 0;} 1719 int restoregraphics() {return 0;}
1720 #endif 1721 1722 void discardgraphics() /* release expanded/extended memory if any in use */ 1723 { 1724 #ifndef XFRACT 1725 MemoryRelease(memhandle); 1726 memhandle = 0; 1727 #endif 1728 } 1729 1730 #if (_MSC_VER >= 700) 1731 #pragma code_seg ("realdos1_text") /* place following in an overlay */ 1732 #endif 1733 1734 VIDEOINFO *vidtbl; /* temporarily loaded fractint.cfg info */ 1735 int vidtbllen; /* number of entries in above */ 1736 1737 int showvidlength() 1738 { 1739 int sz; 1740 sz = (sizeof(VIDEOINFO)+sizeof(int))*MAXVIDEOMODES; 1741 return(sz); 1742 } 1743 1744 1745 int load_fractint_cfg(int options) 1746 { 1747 /* Reads fractint.cfg, loading videoinfo entries into extraseg. */ 1748 /* Sets vidtbl pointing to the loaded table, and returns the */ 1749 /* number of entries (also sets vidtbllen to this). */ 1750 /* Past vidtbl, cfglinenums are stored for update_fractint_cfg. */ 1751 /* If fractint.cfg is not found or invalid, issues a message */ 1752 /* (first time the problem occurs only, and only if options is */ 1753 /* zero) and uses the hard-coded table. */ 1754 1755 FILE *cfgfile; 1756 VIDEOINFO *vident; 1757 int far *cfglinenums; 1758 int linenum; 1759 long xdots, ydots; 1760 int i, j, keynum, ax, bx, cx, dx, dotmode, colors; 1761 int commas[10]; 1762 int textsafe2; 1763 char tempstring[150]; 1764 int truecolorbits; 1765 1766 vidtbl = MK_FP(extraseg,0); 1767 cfglinenums = (int far *)(&vidtbl[MAXVIDEOMODES]); 1768 1769 #ifdef XFRACT
1770 badconfig = -1;
1771 #endif 1772 1773 if (badconfig) /* fractint.cfg already known to be missing or bad */ 1774 goto use_resident_table; 1775 1776 findpath("fractint.cfg",tempstring); 1777 if (tempstring[0] == 0 /* can't find the file */ 1778 || (cfgfile = fopen(tempstring,"r")) == NULL) /* can't open it */ 1779 goto bad_fractint_cfg; 1780 1781 vidtbllen = 0; 1782 linenum = 0; 1783 vident = vidtbl; 1784 while (vidtbllen < MAXVIDEOMODES 1785 && fgets(tempstring, 120, cfgfile)) { 1786 if(strchr(tempstring,'\n') == NULL) 1787 /* finish reading the line */ 1788 while(fgetc(cfgfile) != '\n' && !feof(cfgfile)); 1789 ++linenum; 1790 if (tempstring[0] == ';') continue; /* comment line */ 1791 tempstring[120] = 0; 1792 tempstring[strlen(tempstring)-1] = 0; /* zap trailing \n */ 1793 memset(commas,0,20); 1794 i = j = -1; 1795 for(;;) { 1796 if (tempstring[++i] < ' ') { 1797 if (tempstring[i] == 0) break; 1798 tempstring[i] = ' '; /* convert tab (or whatever) to blank */ 1799 } 1800 else if (tempstring[i] == ',' && ++j < 10) { 1801 commas[j] = i + 1; /* remember start of next field */ 1802 tempstring[i] = 0; /* make field a separate string */ 1803 } 1804 } 1805 keynum = check_vidmode_keyname(tempstring); 1806 sscanf(&tempstring[commas[1]],"%x",&ax); 1807 sscanf(&tempstring[commas[2]],"%x",&bx); 1808 sscanf(&tempstring[commas[3]],"%x",&cx); 1809 sscanf(&tempstring[commas[4]],"%x",&dx); 1810 dotmode = atoi(&tempstring[commas[5]]); 1811 xdots = atol(&tempstring[commas[6]]); 1812 ydots = atol(&tempstring[commas[7]]); 1813 colors = atoi(&tempstring[commas[8]]); 1814 if(colors == 4 && strchr(strlwr(&tempstring[commas[8]]),'g')) 1815 { 1816 colors = 256; 1817 truecolorbits = 4; /* 32 bits */ 1818 } 1819 else if(colors == 16 && strchr(&tempstring[commas[8]],'m')) 1820 { 1821 colors = 256; 1822 truecolorbits = 3; /* 24 bits */ 1823 } 1824 else if(colors == 64 && strchr(&tempstring[commas[8]],'k')) 1825 { 1826 colors = 256; 1827 truecolorbits = 2; /* 16 bits */ 1828 } 1829 else if(colors == 32 && strchr(&tempstring[commas[8]],'k')) 1830 { 1831 colors = 256; 1832 truecolorbits = 1; /* 15 bits */ 1833 } 1834 else 1835 truecolorbits = 0; 1836 1837 textsafe2 = dotmode / 100; 1838 dotmode %= 100; 1839 if (j < 9 || 1840 keynum < 0 || 1841 dotmode < 0 || dotmode > 30 || 1842 textsafe2 < 0 || textsafe2 > 4 || 1843 xdots < MINPIXELS || xdots > MAXPIXELS || 1844 ydots < MINPIXELS || ydots > MAXPIXELS || 1845 (colors != 0 && colors != 2 && colors != 4 && colors != 16 && 1846 colors != 256) 1847 ) 1848 goto bad_fractint_cfg; 1849 cfglinenums[vidtbllen] = linenum; /* for update_fractint_cfg */ 1850 far_memcpy(vident->name, (char far *)&tempstring[commas[0]],25); 1851 far_memcpy(vident->comment,(char far *)&tempstring[commas[9]],25); 1852 vident->name[25] = vident->comment[25] = 0; 1853 vident->keynum = keynum; 1854 vident->videomodeax = ax; 1855 vident->videomodebx = bx; 1856 vident->videomodecx = cx; 1857 vident->videomodedx = dx; 1858 vident->dotmode = truecolorbits * 1000 + textsafe2 * 100 + dotmode; 1859 vident->xdots = (short)xdots; 1860 vident->ydots = (short)ydots; 1861 vident->colors = colors; 1862 ++vident; 1863 ++vidtbllen; 1864 } 1865 fclose(cfgfile); 1866 return (vidtbllen); 1867 1868 bad_fractint_cfg: 1869 badconfig = -1; /* bad, no message issued yet */ 1870 if (options == 0) 1871 bad_fractint_cfg_msg(); 1872 1873 use_resident_table: 1874 vidtbllen = 0; 1875 vident = vidtbl; 1876 for (i = 0; i < MAXVIDEOTABLE; ++i) { 1877 if (videotable[i].xdots) { 1878 far_memcpy((char far *)vident,(char far *)&videotable[i], 1879 sizeof(*vident)); 1880 ++vident; 1881 ++vidtbllen; 1882 } 1883 } 1884 return (vidtbllen); 1885 1886 } 1887 1888 void bad_fractint_cfg_msg() 1889 { 1890 static char far badcfgmsg[]={"\ 1891 File FRACTINT.CFG is missing or invalid.\n\ 1892 See Hardware Support and Video Modes in the full documentation for help.\n\ 1893 I will continue with only the built-in video modes available."}; 1894 stopmsg(0,badcfgmsg); 1895 badconfig = 1; /* bad, message issued */ 1896 } 1897 1898 void load_videotable(int options) 1899 { 1900 /* Loads fractint.cfg and copies the video modes which are */ 1901 /* assigned to function keys into videotable. */ 1902 int keyents,i; 1903 load_fractint_cfg(options); /* load fractint.cfg to extraseg */ 1904 keyents = 0; 1905 far_memset((char far *)videotable,0,sizeof(*vidtbl)*MAXVIDEOTABLE); 1906 for (i = 0; i < vidtbllen; ++i) { 1907 if (vidtbl[i].keynum > 0) { 1908 far_memcpy((char far *)&videotable[keyents],(char far *)&vidtbl[i], 1909 sizeof(*vidtbl)); 1910 if (++keyents >= MAXVIDEOTABLE) 1911 break; 1912 } 1913 } 1914 } 1915 1916 int check_vidmode_key(int option,int k) 1917 { 1918 int i; 1919 /* returns videotable entry number if the passed keystroke is a */ 1920 /* function key currently assigned to a video mode, -1 otherwise */ 1921 if (k == 1400) /* special value from select_vid_mode */ 1922 return(MAXVIDEOTABLE-1); /* for last entry with no key assigned */ 1923 if (k != 0) { 1924 if (option == 0) { /* check resident video mode table */ 1925 for (i = 0; i < MAXVIDEOTABLE; ++i) { 1926 if (videotable[i].keynum == k) 1927 return(i); 1928 } 1929 } 1930 else { /* check full vidtbl */ 1931 for (i = 0; i < vidtbllen; ++i) { 1932 if (vidtbl[i].keynum == k) 1933 return(i); 1934 } 1935 } 1936 } 1937 return(-1); 1938 } 1939 1940 int check_vidmode_keyname(char *kname) 1941 { 1942 /* returns key number for the passed keyname, 0 if not a keyname */ 1943 int i,keyset; 1944 keyset = 1058; 1945 if (*kname == 'S' || *kname == 's') { 1946 keyset = 1083; 1947 ++kname; 1948 } 1949 else if (*kname == 'C' || *kname == 'c') { 1950 keyset = 1093; 1951 ++kname; 1952 } 1953 else if (*kname == 'A' || *kname == 'a') { 1954 keyset = 1103; 1955 ++kname; 1956 } 1957 if (*kname != 'F' && *kname != 'f') 1958 return(0); 1959 if (*++kname < '1' || *kname > '9') 1960 return(0); 1961 i = *kname - '0'; 1962 if (*++kname != 0 && *kname != ' ') { 1963 if (*kname != '0' || i != 1) 1964 return(0); 1965 i = 10; 1966 ++kname; 1967 } 1968 while (*kname) 1969 if (*(kname++) != ' ') 1970 return(0); 1971 if ((i += keyset) < 2) 1972 i = 0; 1973 return(i); 1974 } 1975 1976 void vidmode_keyname(int k,char *buf) 1977 { 1978 /* set buffer to name of passed key number */ 1979 *buf = 0; 1980 if (k > 0) { 1981 if (k > 1103) { 1982 *(buf++) = 'A'; 1983 k -= 1103; 1984 } 1985 else if (k > 1093) { 1986 *(buf++) = 'C'; 1987 k -= 1093; 1988 } 1989 else if (k > 1083) { 1990 *(buf++) = 'S'; 1991 k -= 1083; 1992 } 1993 else 1994 k -= 1058; 1995 sprintf(buf,"F%d",k); 1996 } 1997 } 1998 1999 #if (_MSC_VER >= 700) 2000 #pragma code_seg () /* back to normal segment */ 2001 #endif 2002