WL_TEXT.C (13613B)
1 // WL_TEXT.C 2 3 #include "WL_DEF.H" 4 #pragma hdrstop 5 6 /* 7 ============================================================================= 8 9 TEXT FORMATTING COMMANDS 10 ------------------------ 11 ^C<hex digit> Change text color 12 ^E[enter] End of layout (all pages) 13 ^G<y>,<x>,<pic>[enter] Draw a graphic and push margins 14 ^P[enter] start new page, must be the first chars in a layout 15 ^L<x>,<y>[ENTER] Locate to a specific spot, x in pixels, y in lines 16 17 ============================================================================= 18 */ 19 20 /* 21 ============================================================================= 22 23 LOCAL CONSTANTS 24 25 ============================================================================= 26 */ 27 28 #define BACKCOLOR 0x11 29 30 31 #define WORDLIMIT 80 32 #define FONTHEIGHT 10 33 #define TOPMARGIN 16 34 #define BOTTOMMARGIN 32 35 #define LEFTMARGIN 16 36 #define RIGHTMARGIN 16 37 #define PICMARGIN 8 38 #define TEXTROWS ((200-TOPMARGIN-BOTTOMMARGIN)/FONTHEIGHT) 39 #define SPACEWIDTH 7 40 #define SCREENPIXWIDTH 320 41 #define SCREENMID (SCREENPIXWIDTH/2) 42 43 /* 44 ============================================================================= 45 46 LOCAL VARIABLES 47 48 ============================================================================= 49 */ 50 51 int pagenum,numpages; 52 53 unsigned leftmargin[TEXTROWS],rightmargin[TEXTROWS]; 54 char far *text; 55 unsigned rowon; 56 57 int picx,picy,picnum,picdelay; 58 boolean layoutdone; 59 60 //=========================================================================== 61 62 #ifndef JAPAN 63 /* 64 ===================== 65 = 66 = RipToEOL 67 = 68 ===================== 69 */ 70 71 void RipToEOL (void) 72 { 73 while (*text++ != '\n') // scan to end of line 74 ; 75 } 76 77 78 /* 79 ===================== 80 = 81 = ParseNumber 82 = 83 ===================== 84 */ 85 86 int ParseNumber (void) 87 { 88 char ch; 89 char num[80],*numptr; 90 91 // 92 // scan until a number is found 93 // 94 ch = *text; 95 while (ch < '0' || ch >'9') 96 ch = *++text; 97 98 // 99 // copy the number out 100 // 101 numptr = num; 102 do 103 { 104 *numptr++ = ch; 105 ch = *++text; 106 } while (ch >= '0' && ch <= '9'); 107 *numptr = 0; 108 109 return atoi (num); 110 } 111 112 113 114 /* 115 ===================== 116 = 117 = ParsePicCommand 118 = 119 = Call with text pointing just after a ^P 120 = Upon exit text points to the start of next line 121 = 122 ===================== 123 */ 124 125 void ParsePicCommand (void) 126 { 127 picy=ParseNumber(); 128 picx=ParseNumber(); 129 picnum=ParseNumber(); 130 RipToEOL (); 131 } 132 133 134 void ParseTimedCommand (void) 135 { 136 picy=ParseNumber(); 137 picx=ParseNumber(); 138 picnum=ParseNumber(); 139 picdelay=ParseNumber(); 140 RipToEOL (); 141 } 142 143 144 /* 145 ===================== 146 = 147 = TimedPicCommand 148 = 149 = Call with text pointing just after a ^P 150 = Upon exit text points to the start of next line 151 = 152 ===================== 153 */ 154 155 void TimedPicCommand (void) 156 { 157 ParseTimedCommand (); 158 159 // 160 // update the screen, and wait for time delay 161 // 162 VW_UpdateScreen (); 163 164 // 165 // wait for time 166 // 167 TimeCount = 0; 168 while (TimeCount < picdelay) 169 ; 170 171 // 172 // draw pic 173 // 174 VWB_DrawPic (picx&~7,picy,picnum); 175 } 176 177 178 /* 179 ===================== 180 = 181 = HandleCommand 182 = 183 ===================== 184 */ 185 186 void HandleCommand (void) 187 { 188 int i,margin,top,bottom; 189 int picwidth,picheight,picmid; 190 191 switch (toupper(*++text)) 192 { 193 case 'B': 194 picy=ParseNumber(); 195 picx=ParseNumber(); 196 picwidth=ParseNumber(); 197 picheight=ParseNumber(); 198 VWB_Bar(picx,picy,picwidth,picheight,BACKCOLOR); 199 RipToEOL(); 200 break; 201 case ';': // comment 202 RipToEOL(); 203 break; 204 case 'P': // ^P is start of next page, ^E is end of file 205 case 'E': 206 layoutdone = true; 207 text--; // back up to the '^' 208 break; 209 210 case 'C': // ^c<hex digit> changes text color 211 i = toupper(*++text); 212 if (i>='0' && i<='9') 213 fontcolor = i-'0'; 214 else if (i>='A' && i<='F') 215 fontcolor = i-'A'+10; 216 217 fontcolor *= 16; 218 i = toupper(*++text); 219 if (i>='0' && i<='9') 220 fontcolor += i-'0'; 221 else if (i>='A' && i<='F') 222 fontcolor += i-'A'+10; 223 text++; 224 break; 225 226 case '>': 227 px = 160; 228 text++; 229 break; 230 231 case 'L': 232 py=ParseNumber(); 233 rowon = (py-TOPMARGIN)/FONTHEIGHT; 234 py = TOPMARGIN+rowon*FONTHEIGHT; 235 px=ParseNumber(); 236 while (*text++ != '\n') // scan to end of line 237 ; 238 break; 239 240 case 'T': // ^Tyyy,xxx,ppp,ttt waits ttt tics, then draws pic 241 TimedPicCommand (); 242 break; 243 244 case 'G': // ^Gyyy,xxx,ppp draws graphic 245 ParsePicCommand (); 246 VWB_DrawPic (picx&~7,picy,picnum); 247 picwidth = pictable[picnum-STARTPICS].width; 248 picheight = pictable[picnum-STARTPICS].height; 249 // 250 // adjust margins 251 // 252 picmid = picx + picwidth/2; 253 if (picmid > SCREENMID) 254 margin = picx-PICMARGIN; // new right margin 255 else 256 margin = picx+picwidth+PICMARGIN; // new left margin 257 258 top = (picy-TOPMARGIN)/FONTHEIGHT; 259 if (top<0) 260 top = 0; 261 bottom = (picy+picheight-TOPMARGIN)/FONTHEIGHT; 262 if (bottom>=TEXTROWS) 263 bottom = TEXTROWS-1; 264 265 for (i=top;i<=bottom;i++) 266 if (picmid > SCREENMID) 267 rightmargin[i] = margin; 268 else 269 leftmargin[i] = margin; 270 271 // 272 // adjust this line if needed 273 // 274 if (px < leftmargin[rowon]) 275 px = leftmargin[rowon]; 276 break; 277 } 278 } 279 280 281 /* 282 ===================== 283 = 284 = NewLine 285 = 286 ===================== 287 */ 288 289 void NewLine (void) 290 { 291 char ch; 292 293 if (++rowon == TEXTROWS) 294 { 295 // 296 // overflowed the page, so skip until next page break 297 // 298 layoutdone = true; 299 do 300 { 301 if (*text == '^') 302 { 303 ch = toupper(*(text+1)); 304 if (ch == 'E' || ch == 'P') 305 { 306 layoutdone = true; 307 return; 308 } 309 } 310 text++; 311 312 } while (1); 313 314 } 315 px = leftmargin[rowon]; 316 py+= FONTHEIGHT; 317 } 318 319 320 321 /* 322 ===================== 323 = 324 = HandleCtrls 325 = 326 ===================== 327 */ 328 329 void HandleCtrls (void) 330 { 331 char ch; 332 333 ch = *text++; // get the character and advance 334 335 if (ch == '\n') 336 { 337 NewLine (); 338 return; 339 } 340 341 } 342 343 344 /* 345 ===================== 346 = 347 = HandleWord 348 = 349 ===================== 350 */ 351 352 void HandleWord (void) 353 { 354 char word[WORDLIMIT]; 355 int i,wordindex; 356 unsigned wwidth,wheight,newpos; 357 358 359 // 360 // copy the next word into [word] 361 // 362 word[0] = *text++; 363 wordindex = 1; 364 while (*text>32) 365 { 366 word[wordindex] = *text++; 367 if (++wordindex == WORDLIMIT) 368 Quit ("PageLayout: Word limit exceeded"); 369 } 370 word[wordindex] = 0; // stick a null at end for C 371 372 // 373 // see if it fits on this line 374 // 375 VW_MeasurePropString (word,&wwidth,&wheight); 376 377 while (px+wwidth > rightmargin[rowon]) 378 { 379 NewLine (); 380 if (layoutdone) 381 return; // overflowed page 382 } 383 384 // 385 // print it 386 // 387 newpos = px+wwidth; 388 VWB_DrawPropString (word); 389 px = newpos; 390 391 // 392 // suck up any extra spaces 393 // 394 while (*text == ' ') 395 { 396 px += SPACEWIDTH; 397 text++; 398 } 399 } 400 401 /* 402 ===================== 403 = 404 = PageLayout 405 = 406 = Clears the screen, draws the pics on the page, and word wraps the text. 407 = Returns a pointer to the terminating command 408 = 409 ===================== 410 */ 411 412 void PageLayout (boolean shownumber) 413 { 414 int i,oldfontcolor; 415 char ch; 416 417 oldfontcolor = fontcolor; 418 419 fontcolor = 0; 420 421 // 422 // clear the screen 423 // 424 VWB_Bar (0,0,320,200,BACKCOLOR); 425 VWB_DrawPic (0,0,H_TOPWINDOWPIC); 426 VWB_DrawPic (0,8,H_LEFTWINDOWPIC); 427 VWB_DrawPic (312,8,H_RIGHTWINDOWPIC); 428 VWB_DrawPic (8,176,H_BOTTOMINFOPIC); 429 430 431 for (i=0;i<TEXTROWS;i++) 432 { 433 leftmargin[i] = LEFTMARGIN; 434 rightmargin[i] = SCREENPIXWIDTH-RIGHTMARGIN; 435 } 436 437 px = LEFTMARGIN; 438 py = TOPMARGIN; 439 rowon = 0; 440 layoutdone = false; 441 442 // 443 // make sure we are starting layout text (^P first command) 444 // 445 while (*text <= 32) 446 text++; 447 448 if (*text != '^' || toupper(*++text) != 'P') 449 Quit ("PageLayout: Text not headed with ^P"); 450 451 while (*text++ != '\n') 452 ; 453 454 455 // 456 // process text stream 457 // 458 do 459 { 460 ch = *text; 461 462 if (ch == '^') 463 HandleCommand (); 464 else 465 if (ch == 9) 466 { 467 px = (px+8)&0xf8; 468 text++; 469 } 470 else if (ch <= 32) 471 HandleCtrls (); 472 else 473 HandleWord (); 474 475 } while (!layoutdone); 476 477 pagenum++; 478 479 if (shownumber) 480 { 481 #ifdef SPANISH 482 strcpy (str,"Hoja "); 483 itoa (pagenum,str2,10); 484 strcat (str,str2); 485 strcat (str," de "); 486 py = 183; 487 px = 208; 488 #else 489 strcpy (str,"pg "); 490 itoa (pagenum,str2,10); 491 strcat (str,str2); 492 strcat (str," of "); 493 py = 183; 494 px = 213; 495 #endif 496 itoa (numpages,str2,10); 497 strcat (str,str2); 498 fontcolor = 0x4f; //12^BACKCOLOR; 499 500 VWB_DrawPropString (str); 501 } 502 503 fontcolor = oldfontcolor; 504 } 505 506 //=========================================================================== 507 508 /* 509 ===================== 510 = 511 = BackPage 512 = 513 = Scans for a previous ^P 514 = 515 ===================== 516 */ 517 518 void BackPage (void) 519 { 520 pagenum--; 521 do 522 { 523 text--; 524 if (*text == '^' && toupper(*(text+1)) == 'P') 525 return; 526 } while (1); 527 } 528 529 530 //=========================================================================== 531 532 533 /* 534 ===================== 535 = 536 = CacheLayoutGraphics 537 = 538 = Scans an entire layout file (until a ^E) marking all graphics used, and 539 = counting pages, then caches the graphics in 540 = 541 ===================== 542 */ 543 void CacheLayoutGraphics (void) 544 { 545 char far *bombpoint, far *textstart; 546 char ch; 547 548 textstart = text; 549 bombpoint = text+30000; 550 numpages = pagenum = 0; 551 552 do 553 { 554 if (*text == '^') 555 { 556 ch = toupper(*++text); 557 if (ch == 'P') // start of a page 558 numpages++; 559 if (ch == 'E') // end of file, so load graphics and return 560 { 561 CA_MarkGrChunk(H_TOPWINDOWPIC); 562 CA_MarkGrChunk(H_LEFTWINDOWPIC); 563 CA_MarkGrChunk(H_RIGHTWINDOWPIC); 564 CA_MarkGrChunk(H_BOTTOMINFOPIC); 565 CA_CacheMarks (); 566 text = textstart; 567 return; 568 } 569 if (ch == 'G') // draw graphic command, so mark graphics 570 { 571 ParsePicCommand (); 572 CA_MarkGrChunk (picnum); 573 } 574 if (ch == 'T') // timed draw graphic command, so mark graphics 575 { 576 ParseTimedCommand (); 577 CA_MarkGrChunk (picnum); 578 } 579 } 580 else 581 text++; 582 583 } while (text<bombpoint); 584 585 Quit ("CacheLayoutGraphics: No ^E to terminate file!"); 586 } 587 #endif 588 589 590 /* 591 ===================== 592 = 593 = ShowArticle 594 = 595 ===================== 596 */ 597 598 #ifdef JAPAN 599 void ShowArticle (int which) 600 #else 601 void ShowArticle (char far *article) 602 #endif 603 { 604 #ifdef JAPAN 605 int snames[10] = { H_HELP1PIC, 606 H_HELP2PIC, 607 H_HELP3PIC, 608 H_HELP4PIC, 609 H_HELP5PIC, 610 H_HELP6PIC, 611 H_HELP7PIC, 612 H_HELP8PIC, 613 H_HELP9PIC, 614 H_HELP10PIC}; 615 int enames[14] = { 616 0,0, 617 #ifndef JAPDEMO 618 C_ENDGAME1APIC, 619 C_ENDGAME1BPIC, 620 C_ENDGAME2APIC, 621 C_ENDGAME2BPIC, 622 C_ENDGAME3APIC, 623 C_ENDGAME3BPIC, 624 C_ENDGAME4APIC, 625 C_ENDGAME4BPIC, 626 C_ENDGAME5APIC, 627 C_ENDGAME5BPIC, 628 C_ENDGAME6APIC, 629 C_ENDGAME6BPIC 630 #endif 631 }; 632 #endif 633 unsigned oldfontnumber; 634 unsigned temp; 635 boolean newpage,firstpage; 636 637 #ifdef JAPAN 638 pagenum = 1; 639 if (!which) 640 numpages = 10; 641 else 642 numpages = 2; 643 644 #else 645 646 text = article; 647 oldfontnumber = fontnumber; 648 fontnumber = 0; 649 CA_MarkGrChunk(STARTFONT); 650 VWB_Bar (0,0,320,200,BACKCOLOR); 651 CacheLayoutGraphics (); 652 #endif 653 654 newpage = true; 655 firstpage = true; 656 657 do 658 { 659 if (newpage) 660 { 661 newpage = false; 662 #ifdef JAPAN 663 if (!which) 664 CA_CacheScreen(snames[pagenum - 1]); 665 else 666 CA_CacheScreen(enames[which*2 + pagenum - 1]); 667 #else 668 PageLayout (true); 669 #endif 670 VW_UpdateScreen (); 671 if (firstpage) 672 { 673 VL_FadeIn(0,255,&gamepal,10); 674 // VW_FadeIn () 675 firstpage = false; 676 } 677 } 678 679 LastScan = 0; 680 while (!LastScan) 681 ; 682 683 switch (LastScan) 684 { 685 case sc_UpArrow: 686 case sc_PgUp: 687 case sc_LeftArrow: 688 if (pagenum>1) 689 { 690 #ifndef JAPAN 691 BackPage (); 692 BackPage (); 693 #else 694 pagenum--; 695 #endif 696 newpage = true; 697 } 698 break; 699 700 case sc_Enter: 701 case sc_DownArrow: 702 case sc_PgDn: 703 case sc_RightArrow: // the text allready points at next page 704 if (pagenum<numpages) 705 { 706 newpage = true; 707 #ifdef JAPAN 708 pagenum++; 709 #endif 710 } 711 break; 712 } 713 714 #ifndef SPEAR 715 if (Keyboard[sc_Tab] && Keyboard[sc_P] && MS_CheckParm("goobers")) 716 PicturePause(); 717 #endif 718 719 } while (LastScan != sc_Escape); 720 721 IN_ClearKeysDown (); 722 fontnumber = oldfontnumber; 723 } 724 725 726 //=========================================================================== 727 728 #ifndef JAPAN 729 #ifdef ARTSEXTERN 730 int endextern = T_ENDART1; 731 #ifndef SPEAR 732 int helpextern = T_HELPART; 733 #endif 734 #endif 735 char helpfilename[13] = "HELPART.", 736 endfilename[13] = "ENDART1."; 737 #endif 738 739 /* 740 ================= 741 = 742 = HelpScreens 743 = 744 ================= 745 */ 746 #ifndef SPEAR 747 void HelpScreens (void) 748 { 749 int artnum; 750 char far *text; 751 memptr layout; 752 753 754 CA_UpLevel (); 755 MM_SortMem (); 756 #ifdef JAPAN 757 ShowArticle (0); 758 VW_FadeOut(); 759 FreeMusic (); 760 CA_DownLevel (); 761 MM_SortMem (); 762 #else 763 764 765 766 767 #ifdef ARTSEXTERN 768 artnum = helpextern; 769 CA_CacheGrChunk (artnum); 770 text = (char _seg *)grsegs[artnum]; 771 MM_SetLock (&grsegs[artnum], true); 772 #else 773 CA_LoadFile (helpfilename,&layout); 774 text = (char _seg *)layout; 775 MM_SetLock (&layout, true); 776 #endif 777 778 ShowArticle (text); 779 780 #ifdef ARTSEXTERN 781 MM_FreePtr (&grsegs[artnum]); 782 #else 783 MM_FreePtr (&layout); 784 #endif 785 786 787 788 VW_FadeOut(); 789 790 FreeMusic (); 791 CA_DownLevel (); 792 MM_SortMem (); 793 #endif 794 } 795 #endif 796 797 // 798 // END ARTICLES 799 // 800 void EndText (void) 801 { 802 int artnum; 803 char far *text; 804 memptr layout; 805 806 807 ClearMemory (); 808 809 CA_UpLevel (); 810 MM_SortMem (); 811 #ifdef JAPAN 812 ShowArticle(gamestate.episode + 1); 813 814 VW_FadeOut(); 815 816 SETFONTCOLOR(0,15); 817 IN_ClearKeysDown(); 818 if (MousePresent) 819 Mouse(MDelta); // Clear accumulated mouse movement 820 821 FreeMusic (); 822 CA_DownLevel (); 823 MM_SortMem (); 824 #else 825 826 827 828 #ifdef ARTSEXTERN 829 artnum = endextern+gamestate.episode; 830 CA_CacheGrChunk (artnum); 831 text = (char _seg *)grsegs[artnum]; 832 MM_SetLock (&grsegs[artnum], true); 833 #else 834 endfilename[6] = '1'+gamestate.episode; 835 CA_LoadFile (endfilename,&layout); 836 text = (char _seg *)layout; 837 MM_SetLock (&layout, true); 838 #endif 839 840 ShowArticle (text); 841 842 #ifdef ARTSEXTERN 843 MM_FreePtr (&grsegs[artnum]); 844 #else 845 MM_FreePtr (&layout); 846 #endif 847 848 849 VW_FadeOut(); 850 SETFONTCOLOR(0,15); 851 IN_ClearKeysDown(); 852 if (MousePresent) 853 Mouse(MDelta); // Clear accumulated mouse movement 854 855 FreeMusic (); 856 CA_DownLevel (); 857 MM_SortMem (); 858 #endif 859 }