CnC_Remastered_Collection

Command and Conquer: Red Alert
Log | Files | Refs | README | LICENSE

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