WINDOWS.CPP (37752B)
1 // 2 // Copyright 2020 Electronic Arts Inc. 3 // 4 // TiberianDawn.DLL and RedAlert.dll and corresponding source code is free 5 // software: you can redistribute it and/or modify it under the terms of 6 // the GNU General Public License as published by the Free Software Foundation, 7 // either version 3 of the License, or (at your option) any later version. 8 9 // TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed 10 // in the hope that it will be useful, but with permitted additional restrictions 11 // under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT 12 // distributed with this program. You should have received a copy of the 13 // GNU General Public License along with permitted additional restrictions 14 // with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection 15 16 /* $Header: g:/library/source/rcs/./windows.c 1.12 1994/05/20 15:35:25 joe_bostic Exp $ */ 17 /*************************************************************************** 18 ** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S ** 19 *************************************************************************** 20 * * 21 * Project Name : LIBRARY * 22 * * 23 * File Name : WINDOWS.C * 24 * * 25 * Programmer : Everyone * 26 * * 27 * Last Update : February 3, 1992 [DRD] * 28 * * 29 *-------------------------------------------------------------------------* 30 * Functions: * 31 * Change_New_Window -- Combined Change_Window and New_Window. * 32 * Change_Window -- Changes the 'current' window in the system. * 33 * Fetch_Char -- Gets one undipthonged char from input. * 34 * Flush_Line -- Outputs the accumulate text line to screen. * 35 * In_Char -- Stores (un-dipped) character(s) from input to buffer. * 36 * New_Window -- Clears the current window to the background color. * 37 * Set_More_Off -- Turns the 'more' prompting off. * 38 * Set_More_On -- Turns the 'more' prompting on. * 39 * Set_More_Prompt -- Adjusts the more prompt text for default routine * 40 * Standard_More_Prompt -- Default more prompt code for Window_Print * 41 * Window_Int_Print -- Prints an integer to the window. * 42 * Window_Print -- Displays and wraps text into a window. * 43 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 44 45 #include <ctype.h> 46 #include <stdlib.h> 47 #include <string.h> 48 #include <stdio.h> 49 #include <stdarg.h> 50 #include <wwstd.h> 51 #include "ww_win.h" 52 #include <keyboard.h> 53 #include <font.h> 54 #include <dipthong.h> 55 56 PRIVATE void Scroll_Window(void); 57 PRIVATE void Flush_Line(void); 58 PRIVATE void In_Char(char *str); 59 PRIVATE char Fetch_Char(void); 60 61 62 PRIVATE int ScrollCounter = 0; // Count of the lines displayed before a pause. 63 PRIVATE char Line[84]; // Staging line buffer. 64 PRIVATE int Pos; // Char Position of next free character. 65 PRIVATE int PPos; // Pixel position of next free character. 66 PRIVATE int WPos; // Char position in window. 67 PRIVATE char *MainSource; 68 PRIVATE char *AltSource; 69 PRIVATE char Char[2]; 70 PRIVATE char Stack; 71 PRIVATE char WordWrapFlag = FALSE; // flag for a word wrap. 72 73 PRIVATE int MoreSpace = 7; 74 PRIVATE int MoreFColor = 0; 75 PRIVATE int MoreBColor = 0; 76 77 78 int WindowColumns=40; 79 int WindowLines=25; 80 int WindowWidth=40; 81 unsigned int WinB=0; 82 unsigned int WinC=1; 83 unsigned int WinX=0; 84 unsigned int WinY=0; 85 unsigned int WinCx=0; 86 unsigned int WinCy=0; 87 unsigned int WinH=25; 88 unsigned int WinW=40; 89 unsigned int Window=0; 90 91 int MoreOn = TRUE; 92 char *TXT_MoreText = "--More--"; 93 void (*Window_More_Ptr)(char const *,int,int,int) = Standard_More_Prompt; 94 95 extern GraphicViewPortClass *LogicPage; 96 /*************************************************************************** 97 * STANDARD_MORE_PROMPT -- Default more prompt code for Window_Print * 98 * * 99 * This is the standard "<more>" prompting code that is used by * 100 * Window_Print when a page is full of text and a pause is desired * 101 * before the next page of text is printed. This function is called * 102 * through the Window_More_Ptr global. * 103 * * 104 * INPUT: prompt -- Pointer to ASCII text that will be window printed * 105 * at the right margin. * 106 * * 107 * space -- The number of spaces to allow for the 'more' text. * 108 * * 109 * fcolor -- The foreground color to use for the 'more' text. * 110 * * 111 * bcolor -- The background oclor to use for the 'more' text. * 112 * * 113 * OUTPUT: none * 114 * * 115 * WARNINGS: none * 116 * * 117 * HISTORY: * 118 * 07/29/1991 JLB : Created. * 119 *=========================================================================*/ 120 void Standard_More_Prompt(char const *prompt, int space, int fcolor, int bcolor) 121 { 122 int x, y, moresize; 123 124 moresize = (space - 1) * (FontWidth+FontXSpacing); 125 x = ((WinX+WinW) << 3) - moresize; 126 //y = WinY + ((WinH/FontHeight)-1)*FontHeight; 127 y = WinY + (WinCy-1) * (FontHeight+FontYSpacing); 128 129 // Default "more" prompter. 130 LogicPage->Print(prompt, x, y, fcolor ? fcolor : WindowList[Window][WINDOWBCOL], bcolor ? bcolor : WindowList[Window][WINDOWFCOL]); 131 //BG if (LogicPage == SEENPAGE) { 132 //BG Window_Show_Mouse(); 133 //BG } 134 135 // PWG - have to figure out how to do this in windows library 136 137 // Clear_KeyBuffer(); 138 // Get_Key(); 139 140 //BG if (LogicPage == SEENPAGE) { 141 //BG Window_Hide_Mouse(Window); 142 //BG } 143 144 // Erase the more prompt prompt. 145 // Text_Print(prompt, x, y, WinB, WinB); 146 LogicPage->Fill_Rect(x, y, x + moresize - 1, y + (FontHeight+FontYSpacing) - 1, (unsigned char)WinB); 147 } 148 149 150 /*************************************************************************** 151 * SET_MORE_PROMPT -- Adjusts the more prompt text for default routine * 152 * * 153 * Use this routine to control the text of the "<MORE>" prompt that * 154 * the default more prompt routine uses. This can be useful for * 155 * foreign language translations. * 156 * * 157 * INPUT: prompt -- Pointer to ASCII text that will be window printed * 158 * at the right margin. * 159 * * 160 * space -- The number of spaces to allow for the 'more' text. * 161 * * 162 * fcolor -- The foreground color to use for the 'more' text. * 163 * * 164 * bcolor -- The background color to use for the 'more' text. * 165 * * 166 * OUTPUT: none * 167 * * 168 * WARNINGS: none * 169 * * 170 * HISTORY: * 171 * 07/29/1991 JLB : Created. * 172 *=========================================================================*/ 173 void Set_More_Prompt(char const *prompt, int space, int fcolor, int bcolor) 174 { 175 if (prompt) { 176 TXT_MoreText = (char*)prompt; 177 MoreSpace = space; 178 MoreFColor = fcolor; 179 MoreBColor = bcolor; 180 } 181 else { 182 TXT_MoreText = "<MORE>"; 183 MoreSpace = 7; 184 MoreFColor = MoreBColor = 0; 185 } 186 } 187 188 189 /*************************************************************************** 190 * SET_MORE_ON -- Turns the 'more' prompting on. * 191 * * 192 * Use this routine to turn on the 'more' prompting that Window_Print * 193 * does. If you have a custom more function pointer, then that * 194 * routine will be called, otherwise the library default 'more' prompt * 195 * will be utilized. * 196 * * 197 * INPUT: none * 198 * * 199 * OUTPUT: none * 200 * * 201 * WARNINGS: none * 202 * * 203 * HISTORY: * 204 * 07/25/1991 JLB : Created. * 205 *=========================================================================*/ 206 void Set_More_On(void) 207 { 208 MoreOn = TRUE; 209 ScrollCounter = 0; 210 } 211 212 213 /*************************************************************************** 214 * SET_MORE_OFF -- Turns the 'more' prompting off. * 215 * * 216 * This routine will turn the 'more' prompting that Window_Print does * 217 * off. * 218 * * 219 * INPUT: none * 220 * * 221 * OUTPUT: none * 222 * * 223 * WARNINGS: none * 224 * * 225 * HISTORY: * 226 * 07/25/1991 JLB : Created. * 227 *=========================================================================*/ 228 void Set_More_Off(void) 229 { 230 MoreOn = FALSE; 231 } 232 233 234 /*************************************************************************** 235 * CHANGE_WINDOW -- Changes the 'current' window in the system. * 236 * * 237 * Use this routine to change the 'current' window. The current window * 238 * is used in Window_Print and some other graphic output routines. * 239 * * 240 * INPUT: windnum -- The window number to change to. * 241 * * 242 * OUTPUT: Returns with the previously current window. * 243 * * 244 * WARNINGS: none * 245 * * 246 * HISTORY: * 247 * 07/25/1991 JLB : Created. * 248 *=========================================================================*/ 249 int Change_Window(int windnum) 250 { 251 int oldwindow; 252 int *data; 253 254 oldwindow = Window; 255 Window = windnum; 256 data = &WindowList[windnum][0]; 257 258 WinX = *data++; 259 WinY = *data++; 260 WinW = *data++; 261 WinH = *data++; 262 WinC = *data++; 263 WinB = *data++; 264 WinCx = *data++; 265 WinCy = *data++; 266 ScrollCounter = 0; 267 WPos = WinCx / (FontWidth+FontXSpacing); 268 WindowLines = (WinH-FontYSpacing) / (FontHeight+FontYSpacing); 269 WindowWidth = WinW << 3; 270 WindowColumns = WindowWidth / (FontWidth+FontXSpacing); 271 return (oldwindow); 272 } 273 274 275 /*************************************************************************** 276 * CHANGE_NEW_WINDOW -- Combined Change_Window and New_Window. * 277 * * 278 * This is a combo-routine. It merely combines the Change_Window * 279 * with the New_Window routines. It will save some (small) code if * 280 * you use this routine instead of the two function calls. * 281 * * 282 * INPUT: window -- Window number to change to and clear. * 283 * * 284 * OUTPUT: Returns with the previously current window. * 285 * * 286 * WARNINGS: none * 287 * * 288 * HISTORY: * 289 * 07/25/1991 JLB : Created. * 290 *=========================================================================*/ 291 int Change_New_Window(int windnum) 292 { 293 int oldwindow; 294 295 oldwindow = Change_Window(windnum); 296 New_Window(); 297 return(oldwindow); 298 } 299 300 301 /*************************************************************************** 302 * NEW_WINDOW -- Clears the current window to the background color. * 303 * * 304 * This routine clears the current window to the background color. It * 305 * is used in preparation to Window_Print because it ensures a clean * 306 * 'slate' for the text. * 307 * * 308 * INPUT: none * 309 * * 310 * OUTPUT: none * 311 * * 312 * WARNINGS: none * 313 * * 314 * HISTORY: * 315 * 07/25/1991 JLB : Created. * 316 *=========================================================================*/ 317 void New_Window(void) 318 { 319 int x,y,w,h; 320 321 x = WinX << 3; 322 y = WinY; 323 w = (WinX + WinW) << 3; 324 h = WinY + WinH; 325 326 LogicPage->Fill_Rect(x, y, w - 1, h - 1, (unsigned char)WinB); 327 328 WinCx = WPos = 0; 329 WinCy = 0; 330 ScrollCounter = 0; 331 } 332 333 334 /*************************************************************************** 335 * WINDOW_INT_PRINT -- Prints an integer to the window. * 336 * * 337 * Use this routine to print an integer to the window. This routine * 338 * as all other Window printing routines will handle word wrap. * 339 * * 340 * INPUT: num -- The integer to convert to ASCII and print. * 341 * * 342 * OUTPUT: none * 343 * * 344 * WARNINGS: none * 345 * * 346 * HISTORY: * 347 * 07/25/1991 JLB : Created. * 348 *=========================================================================*/ 349 void Window_Int_Print(int num) 350 { 351 Window_Print("%d", num); 352 } 353 354 355 /*************************************************************************** 356 * WINDOW_PRINT -- Displays and wraps text into a window. * 357 * * 358 * This is the general purpos text output routine that will handle * 359 * word wrap within a window. It is useful for displaying arbitrary * 360 * text. This routine will handle dipthonged text and as such it * 361 * can be quite useful in saving memory. * 362 * * 363 * INPUT: string -- String to print. This can be of ANY length and * 364 * can even contain some formatting codes. The * 365 * codes supported are: * 366 * * 367 * KA_SETX Forces the cursor X position to the value * 368 * specified. * 369 * * 370 * KA_SETY Forces the cursor Y position to the value * 371 * specified. * 372 * * 373 * KA_MORE Causes an immediate "<MORE>" prompt * 374 * regardless of the scroll situation. * 375 * * 376 * KA_RETURN Breaks line and continues output at the * 377 * left edge of following line. * 378 * * 379 * * 380 * KA_FORMFEED Clears the window and continues printing at * 381 * the upper left corner. * 382 * * 383 * KA_SETBKGDCOL Set the background color with the color * 384 * specified by the following byte. * 385 * * 386 * * 387 * KA_SETFORECOL Set the foreground color with the color * 388 * specified by the following byte. * 389 * * 390 * KA_TAB Move the cursor over to the next tabstop. * 391 * Tabstops are set every 8 columns. * 392 * * 393 * KA_SPCTAB Insert spaces until the cursor is positioned * 394 * at the next tabstop. * 395 * * 396 * %s Replace the "%s" with the text pointed to * 397 * by the pointer argument passed to the * 398 * routine (follows same method a printf). * 399 * * 400 * %d Replace the "%d" with an integer ASCII * 401 * number of the int passed to the routine. * 402 * * 403 * OUTPUT: none * 404 * * 405 * WARNINGS: none * 406 * * 407 * HISTORY: * 408 * 07/25/1991 JLB : Created. * 409 * 07/29/1991 JLB : Added MORE, SETX, and SETY * 410 *=========================================================================*/ 411 void Window_Print(char const string[], ...) 412 { 413 int oldcx, x, y; // Scratch variables. 414 char c; // Current character. 415 char buffer[10]; // Working %d buffer. 416 int old_c, old_b; // Original window colors. 417 va_list arg; // Argument list var. 418 419 420 va_start(arg, string); 421 422 WordWrapFlag = FALSE; // initialize word wrap flag. 423 Pos = PPos = 0; 424 Line[0] = '\0'; 425 Char[0] = Char[1] = 0; 426 MainSource = (char*)&string[0]; 427 AltSource = NULL; 428 old_c = WinC; 429 old_b = WinB; 430 431 //BG if (LogicPage == SEENPAGE) { 432 //BG Window_Hide_Mouse(Window); 433 //BG } 434 435 while (TRUE) { 436 437 c = Fetch_Char(); 438 439 if (!c) break; // Exit on NULL character. 440 441 /* 442 ** Substitution commands only work if not already expanding a 443 ** string. 444 */ 445 if (!AltSource) { 446 if (c == '%') { 447 switch(tolower(Char[0])) { 448 case 's': 449 AltSource = va_arg(arg, char*); 450 if (AltSource) { 451 Stack = Char[1]; 452 Char[0] = Char[1] = '\0'; 453 c = Fetch_Char(); 454 } 455 break; 456 457 case 'd': 458 AltSource = buffer; 459 sprintf(buffer, "%d", va_arg(arg, int)); 460 Stack = Char[1]; 461 Char[0] = Char[1] = '\0'; 462 c = Fetch_Char(); 463 break; 464 465 default: 466 break; 467 } 468 } 469 } 470 471 switch(c) { 472 473 #if(FALSE) 474 // these are the positions of foreign language characters 475 /* 476 ** These are characters that shouldn't be window printed because 477 ** they are currently reserved. 478 */ 479 case KA_CTRL_C: 480 case KA_CTRL_D: 481 case KA_CTRL_E: 482 case KA_CTRL_G: 483 case KA_CTRL_J: 484 case KA_CTRL_K: 485 case KA_CTRL_N: 486 case KA_CTRL_O: 487 case KA_CTRL_P: 488 case KA_CTRL_Q: 489 case KA_CTRL_R: 490 case KA_CTRL_T: 491 case KA_CTRL_U: 492 case KA_CTRL_V: 493 case KA_CTRL_W: 494 case KA_CTRL_Z: 495 case KA_CTRL_BACKSLASH: 496 case KA_CTRL_CARROT: 497 case KA_CTRL_UNDERLINE: 498 break; 499 #endif 500 /* 501 ** Force cursor column to specified X value. 502 */ 503 case KA_SETX: 504 Flush_Line(); 505 WPos = Fetch_Char(); 506 WPos = MAX(0, WPos); 507 508 // WPos is max width char position 509 510 WPos = MIN(WindowColumns-1, WPos); 511 WinCx = WPos * (FontWidth+FontXSpacing); 512 break; 513 514 /* 515 ** Force the cursor to specified Y value. 516 */ 517 case KA_SETY: 518 Flush_Line(); 519 WinCy = Fetch_Char(); 520 //WinCy = MAX(0, WinCy); 521 WinCy = MIN((long)WindowLines-1, (long)WinCy); 522 break; 523 524 /* 525 ** Force a "<MORE>" prompt. 526 */ 527 case KA_MORE: 528 Flush_Line(); 529 if (Window_More_Ptr) { 530 //BG if (LogicPage == SEENPAGE) Window_Show_Mouse(); 531 Window_More_Ptr(TXT_MoreText, MoreSpace, MoreFColor, MoreBColor); 532 //BG if (LogicPage == SEENPAGE) Window_Hide_Mouse(Window); 533 } 534 break; 535 536 /* 537 ** Clear and home the window cursor. This is the same 538 ** as New_Window(). 539 */ 540 case KA_FORMFEED: 541 New_Window(); 542 break; 543 544 /* 545 ** Move cursor to start of next line. 546 */ 547 case KA_RETURN: 548 Flush_Line(); 549 ScrollCounter++; 550 WinCx = 0; 551 552 #if(FALSE) 553 if (WinCy >= WindowLines-1) { 554 Scroll_Window(); 555 } 556 else { 557 WinCy++; 558 } 559 #else 560 WinCy++; 561 #endif 562 563 break; 564 565 /* 566 ** Set the background color. 567 */ 568 case KA_SETBKGDCOL: 569 Flush_Line(); 570 WinB = Fetch_Char(); 571 break; 572 573 /* 574 ** Set the foreground color. 575 */ 576 case KA_SETFORECOL: 577 Flush_Line(); 578 WinC = Fetch_Char(); 579 break; 580 581 /* 582 ** Move cursor to next column. 583 */ 584 case KA_TAB: 585 Flush_Line(); 586 WPos = ((WPos + 8) & 0xFFF8) - 1; 587 if (WPos >= WindowColumns) { 588 WPos = 0; 589 } 590 WinCx = WPos * (FontWidth+FontXSpacing); 591 break; 592 593 /* 594 ** Tab to specified column but add spaces. 595 */ 596 case KA_SPCTAB: 597 Flush_Line(); 598 oldcx = WinCx; 599 x = WinX << 3; 600 y = WinY + (WinCy * (FontHeight+FontYSpacing)); 601 WPos = ((WPos + 8) & 0xFFF8) - 1; 602 603 if (WPos >= WindowColumns) { 604 WinCx = WPos = 0; 605 606 // Fill_Rect instead of printing spaces 607 608 LogicPage->Fill_Rect(x + oldcx, y, 609 x + WindowWidth - 1, y + (FontHeight+FontYSpacing) - 1, (unsigned char)WinB); 610 611 ScrollCounter++; 612 WinCy++; 613 } 614 else { 615 WinCx = WPos * (FontWidth+FontXSpacing); 616 617 // Fill_Rect instead of printing spaces 618 619 LogicPage->Fill_Rect(x + oldcx, y, 620 x + WinCx - 1, y + (FontHeight+FontYSpacing) - 1, (unsigned char)WinB); 621 } 622 break; 623 624 /* 625 ** next character is a extended value 1-127, but 128 is added 626 ** for a value 129-255 627 */ 628 case KA_EXTEND: 629 c = 127; 630 631 // NOTE: this falls thru to the default case DO NOT MOVE!!!!! 632 633 634 /* 635 ** next character is a literal value 1-127, except 13 636 */ 637 // case KA_LITERAL: 638 // if (c != (char) 127) { // check if fell thru from extend case 639 // c = 0; // set to zero for literal case 640 // } 641 // c += Fetch_Char(); 642 643 // NOTE: this falls thru to the default case DO NOT MOVE!!!!! 644 645 646 /* 647 ** Normal character output. 648 */ 649 default: 650 PPos += Char_Pixel_Width(c); // get pixel location of next char 651 Line[Pos++] = c; 652 Line[Pos] = '\0'; 653 654 if (WinCx + PPos > (unsigned)WindowWidth) { 655 Flush_Line(); 656 } 657 break; 658 } 659 } 660 661 /* 662 ** If there is text still pending, then display it before exiting. 663 */ 664 if (Pos) Flush_Line(); 665 666 /* 667 ** Record changes in the cursor position. 668 */ 669 WindowList[Window][WINDOWCURSORX] = WinCx; 670 WindowList[Window][WINDOWCURSORY] = WinCy; 671 672 /* 673 ** Restore the window colors to their original values. 674 */ 675 WindowList[Window][WINDOWFCOL] = WinC = old_c; 676 WindowList[Window][WINDOWBCOL] = WinB = old_b; 677 678 //BG if (LogicPage == SEENPAGE) { 679 //BG Window_Show_Mouse(); 680 //BG } 681 682 va_end(arg); 683 } 684 685 686 /*************************************************************************** 687 * SCROLL_WINDOW -- Scrolls the text window up one line. * 688 * * 689 * This will scroll the text window up one line. It will handle any * 690 * pausing for "more" if the MoreOn flag is set. * 691 * * 692 * INPUT: none * 693 * * 694 * OUTPUT: none * 695 * * 696 * WARNINGS: This routine assumes that the LogicPage is the SEENPAGE. * 697 * If this is not the case, the program may appear to hang * 698 * if a "more" prompt is generated. * 699 * * 700 * HISTORY: * 701 * 07/25/1991 JLB : Created. * 702 *=========================================================================*/ 703 PRIVATE void Scroll_Window(void) 704 { 705 int y; // Top pixel row of bottom line of window. 706 707 /* 708 ** Possibly prompt for more text. 709 */ 710 if (ScrollCounter >= WindowLines-1 && MoreOn) { 711 ScrollCounter = 0; 712 713 if (Window_More_Ptr) { 714 //BG if (LogicPage == SEENPAGE) Window_Show_Mouse(); 715 Window_More_Ptr(TXT_MoreText, MoreSpace, MoreFColor, MoreBColor); 716 //BG if (LogicPage == SEENPAGE) Window_Hide_Mouse(Window); 717 } 718 } 719 720 /* 721 ** Scroll the window up one line. 722 */ 723 y = ((WinH / (FontHeight+FontYSpacing)) - 1) * (FontHeight+FontYSpacing); 724 LogicPage->Blit(*LogicPage,WinX<<3, WinY + (FontHeight+FontYSpacing), WinX<<3, WinY, WinW<<3, WinH - (FontHeight+FontYSpacing) ); 725 LogicPage->Fill_Rect(WinX<<3, 726 WinY + y, 727 ((WinX+WinW)<<3) - 1, 728 WinY + WinH - 1, 729 (unsigned char)WinB); 730 } 731 732 733 /*************************************************************************** 734 * FLUSH_LINE -- Outputs the accumulate text line to screen. * 735 * * 736 * This will display the accumlated text line to the screen. It will * 737 * handle breaking the text line at an appropriate position. * 738 * * 739 * INPUT: none * 740 * * 741 * OUTPUT: none * 742 * * 743 * WARNINGS: none * 744 * * 745 * HISTORY: * 746 * 07/25/1991 JLB : Created. * 747 *=========================================================================*/ 748 PRIVATE void Flush_Line(void) 749 { 750 int breakit, breaksize, breakwidth; 751 int x, y; // Coordinates of text print. 752 int breakpoint; // Point to break the line (if possible). 753 char breakchar; // Break replace character. 754 int index; // Backward moving index var. 755 756 /* 757 ** There could be a held <CR> and this is implied by the cursor Y position 758 ** beyond the bottom of the window. If this is the case, then scroll the 759 ** window and proceed with the line flush. 760 */ 761 while (WinCy >= (unsigned)WindowLines /*&& Pos > 0*/) { 762 Scroll_Window(); 763 if (WinCy >= (unsigned)WindowLines) WinCy--; 764 } 765 //if (WinCy >= WindowLines) WinCy = WindowLines-1; 766 767 x = (WinX<<3) + WinCx; 768 y = WinY + (WinCy*(FontHeight+FontYSpacing)); 769 770 breakwidth = WindowWidth; 771 // if (ScrollCounter >= WindowLines - 1 && MoreOn) { 772 // breakwidth -= (MoreSpace * (FontWidth+FontXSpacing)); // use maximum font width 773 // } 774 775 /* 776 ** Try to break the line at the last space IF the line has reached the edge 777 ** of the window. 778 */ 779 breakpoint = Pos; 780 breaksize = PPos; 781 if (WinCx + breaksize > (unsigned)breakwidth) { 782 783 /* 784 ** Since the text WILL spill past the edge of the window, determine the 785 ** point where the break should occur. If this line is ready for the <MORE> 786 ** prompt, then breaking must account for the <MORE> text. 787 */ 788 if (ScrollCounter >= WindowLines - 1 && MoreOn) { 789 breakwidth -= (MoreSpace * (FontWidth+FontXSpacing)); // use maximum font width 790 } 791 breakwidth -= WinCx; 792 793 breakit = 0; 794 for (index = breakpoint - 1; index > 0; index--) { 795 breakchar = Line[index]; 796 breaksize -= Char_Pixel_Width(breakchar); 797 798 // only once, find largest text that can fit on the line 799 if (!breakit) { 800 // was this the char that went past the right edge 801 if (breaksize <= breakwidth) { 802 breakit = index; // save this position if there is no spaces 803 } 804 } 805 806 // after largest text is found then look for a space to break on 807 if (breakit && breakchar == KA_SPACE) { 808 breakpoint = index; 809 WordWrapFlag = FALSE; // word will start at beginning of next line 810 break; 811 } 812 } 813 814 /* 815 ** Exception: When the current text buffer cannot be broken at a logical 816 ** place AND the text is starting past the left margin, THEN there is 817 ** an implied break between the previous text output and this one. 818 ** Output the current text on the next line left margin. 819 */ 820 if (!index) { 821 if (WinCx && !WordWrapFlag) { 822 breakpoint = breaksize = 0; // Continue text on next line. 823 WordWrapFlag = TRUE; // indicate a word continuation. 824 } 825 else { 826 breakpoint = breakit; // Just print as much as possible. 827 } 828 } 829 } 830 831 breakchar = Line[breakpoint]; 832 Line[breakpoint] = '\0'; 833 834 LogicPage->Print(Line, x, y, WinC, WinB); 835 WinCx += breaksize; // add size of text string printed. 836 837 Line[breakpoint] = breakchar; 838 if (breakchar == KA_SPACE) { // take out a space between words. 839 breakpoint++; 840 } 841 842 // take out another space for double spacing after end of sentence. 843 if (Line[breakpoint] == KA_SPACE) { 844 breakpoint++; 845 } 846 847 strcpy(Line, &Line[breakpoint]); 848 Pos = strlen(Line); 849 PPos = String_Pixel_Width(Line); 850 851 /* 852 ** If at this point there is still text in the buffer, then flushing has 853 ** not been completed. Scroll to next line and repeat the text flushing 854 ** process. 855 */ 856 if (Pos || WinCx >= (unsigned)WindowWidth) { 857 WinCx = WPos = 0; 858 #if(FALSE) 859 if (WinCy >= WindowLines-1) { 860 Scroll_Window(); 861 } else { 862 WinCy++; 863 } 864 #else 865 WinCy++; 866 #endif 867 Flush_Line(); 868 ScrollCounter++; // must be done after flush line for correct counting 869 } 870 } 871 872 873 /*************************************************************************** 874 * IN_CHAR -- Stores (un-dipped) character(s) from input to buffer. * 875 * * 876 * Use this routine to fetch the next character from the input stream. * 877 * If the character was dipthonged, then it will be broken into its * 878 * component ASCII characters and stored in the specified location. * 879 * This is the core character stream reading code. * 880 * * 881 * INPUT: str -- char pointer to the position to store the character(s)* 882 * fetched from the input stream. * 883 * * 884 * OUTPUT: none * 885 * * 886 * WARNINGS: none * 887 * * 888 * HISTORY: * 889 * 07/25/1991 JLB : Created. * 890 *=========================================================================*/ 891 PRIVATE void In_Char(char *str) 892 { 893 char c; // Character to return. 894 char next; // Following character (if any). 895 896 c = next = '\0'; 897 898 /* 899 ** Fetch a raw byte from the input stream. 900 */ 901 if (AltSource) { 902 if (*AltSource == '\0') { 903 AltSource = NULL; 904 c = Stack; 905 } else { 906 c = *AltSource++; 907 } 908 } 909 910 if (!c && MainSource) { 911 if (*MainSource == '\0') { 912 MainSource = NULL; 913 } else { 914 c = *MainSource++; 915 } 916 } 917 918 /* 919 ** Convert a dipthong character into it's component 920 ** ASCII characters. 921 */ 922 if (c & 0x80) { 923 c &= 0x7F; 924 next = c & (char)0x07; 925 c = (char)((c & (char)0x78) >> 3); 926 927 next = Dipthong[c][next]; // Dipthong character. 928 c = Common[c]; // Common character. 929 } 930 931 *str++ = c; 932 *str = next; 933 } 934 935 936 /*************************************************************************** 937 * FETCH_CHAR -- Gets one undipthonged char from input. * 938 * * 939 * This routine will fetch one character from the input stream. The * 940 * character has already been un-dipthonged. It is a straight ASCII * 941 * character. This routine ensures that if the next character in the * 942 * input stream needs to be examined, it is available in Char[0]. * 943 * * 944 * INPUT: none * 945 * * 946 * OUTPUT: Returns next character in the input stream (ASCII). If NULL * 947 * is returned, then this indicates the end of the input stream. * 948 * * 949 * WARNINGS: none * 950 * * 951 * HISTORY: * 952 * 07/25/1991 JLB : Created. * 953 *=========================================================================*/ 954 PRIVATE char Fetch_Char(void) 955 { 956 char c; // Character to return. 957 958 if (!Char[0]) { 959 In_Char(&Char[0]); 960 } 961 962 c = Char[0]; 963 Char[0] = Char[1]; 964 Char[1] = '\0'; 965 966 if (!Char[0]) { 967 In_Char(&Char[0]); 968 } 969 970 return (c); 971 } 972 973