CnC_Red_Alert/WWFLAT32/WINDOWS/WINDOWS.CPP.BAK

974 lines
36 KiB
Plaintext
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
** Command & Conquer Red Alert(tm)
** Copyright 2025 Electronic Arts Inc.
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/* $Header: g:/library/source/rcs/./windows.c 1.12 1994/05/20 15:35:25 joe_bostic Exp $ */
/***************************************************************************
** 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 **
***************************************************************************
* *
* Project Name : LIBRARY *
* *
* File Name : WINDOWS.C *
* *
* Programmer : Everyone *
* *
* Last Update : February 3, 1992 [DRD] *
* *
*-------------------------------------------------------------------------*
* Functions: *
* Change_New_Window -- Combined Change_Window and New_Window. *
* Change_Window -- Changes the 'current' window in the system. *
* Fetch_Char -- Gets one undipthonged char from input. *
* Flush_Line -- Outputs the accumulate text line to screen. *
* In_Char -- Stores (un-dipped) character(s) from input to buffer. *
* New_Window -- Clears the current window to the background color. *
* Set_More_Off -- Turns the 'more' prompting off. *
* Set_More_On -- Turns the 'more' prompting on. *
* Set_More_Prompt -- Adjusts the more prompt text for default routine *
* Standard_More_Prompt -- Default more prompt code for Window_Print *
* Window_Int_Print -- Prints an integer to the window. *
* Window_Print -- Displays and wraps text into a window. *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <stdarg.h>
#include <wwstd.h>
#include "windows.h"
#include <keyboard.h>
#include <font.h>
#include <dipthong.h>
PRIVATE void Scroll_Window(void);
PRIVATE void Flush_Line(void);
PRIVATE void In_Char(char *str);
PRIVATE char Fetch_Char(void);
PRIVATE int ScrollCounter = 0; // Count of the lines displayed before a pause.
PRIVATE char Line[84]; // Staging line buffer.
PRIVATE int Pos; // Char Position of next free character.
PRIVATE int PPos; // Pixel position of next free character.
PRIVATE int WPos; // Char position in window.
PRIVATE char *MainSource;
PRIVATE char *AltSource;
PRIVATE char Char[2];
PRIVATE char Stack;
PRIVATE char WordWrapFlag = FALSE; // flag for a word wrap.
PRIVATE int MoreSpace = 7;
PRIVATE int MoreFColor = 0;
PRIVATE int MoreBColor = 0;
int WindowColumns=40;
int WindowLines=25;
int WindowWidth=40;
unsigned int WinB=0;
unsigned int WinC=1;
unsigned int WinX=0;
unsigned int WinY=0;
unsigned int WinCx=0;
unsigned int WinCy=0;
unsigned int WinH=25;
unsigned int WinW=40;
unsigned int Window=0;
int MoreOn = TRUE;
char *TXT_MoreText = "--More--";
void (*Window_More_Ptr)(BYTE const *,int,int,int) = Standard_More_Prompt;
extern GraphicBufferClass *LogicPage;
/***************************************************************************
* STANDARD_MORE_PROMPT -- Default more prompt code for Window_Print *
* *
* This is the standard "<more>" prompting code that is used by *
* Window_Print when a page is full of text and a pause is desired *
* before the next page of text is printed. This function is called *
* through the Window_More_Ptr global. *
* *
* INPUT: prompt -- Pointer to ASCII text that will be window printed *
* at the right margin. *
* *
* space -- The number of spaces to allow for the 'more' text. *
* *
* fcolor -- The foreground color to use for the 'more' text. *
* *
* bcolor -- The background oclor to use for the 'more' text. *
* *
* OUTPUT: none *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 07/29/1991 JLB : Created. *
*=========================================================================*/
void Standard_More_Prompt(char const *prompt, int space, int fcolor, int bcolor)
{
int x, y, moresize;
moresize = (space - 1) * (FontWidth+FontXSpacing);
x = ((WinX+WinW) << 3) - moresize;
//y = WinY + ((WinH/FontHeight)-1)*FontHeight;
y = WinY + (WinCy-1) * (FontHeight+FontYSpacing);
// Default "more" prompter.
LogicPage->Print(prompt, x, y, fcolor ? fcolor : WindowList[Window][WINDOWBCOL], bcolor ? bcolor : WindowList[Window][WINDOWFCOL]);
//BG if (LogicPage == SEENPAGE) {
//BG Window_Show_Mouse();
//BG }
Clear_KeyBuffer();
Get_Key();
//BG if (LogicPage == SEENPAGE) {
//BG Window_Hide_Mouse(Window);
//BG }
// Erase the more prompt prompt.
// Text_Print(prompt, x, y, WinB, WinB);
LogicPage->Fill_Rect(x, y, x + moresize - 1, y + (FontHeight+FontYSpacing) - 1, WinB);
}
/***************************************************************************
* SET_MORE_PROMPT -- Adjusts the more prompt text for default routine *
* *
* Use this routine to control the text of the "<MORE>" prompt that *
* the default more prompt routine uses. This can be useful for *
* foreign language translations. *
* *
* INPUT: prompt -- Pointer to ASCII text that will be window printed *
* at the right margin. *
* *
* space -- The number of spaces to allow for the 'more' text. *
* *
* fcolor -- The foreground color to use for the 'more' text. *
* *
* bcolor -- The background color to use for the 'more' text. *
* *
* OUTPUT: none *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 07/29/1991 JLB : Created. *
*=========================================================================*/
void Set_More_Prompt(char const *prompt, int space, int fcolor, int bcolor)
{
if (prompt) {
TXT_MoreText = (char*)prompt;
MoreSpace = space;
MoreFColor = fcolor;
MoreBColor = bcolor;
}
else {
TXT_MoreText = "<MORE>";
MoreSpace = 7;
MoreFColor = MoreBColor = 0;
}
}
/***************************************************************************
* SET_MORE_ON -- Turns the 'more' prompting on. *
* *
* Use this routine to turn on the 'more' prompting that Window_Print *
* does. If you have a custom more function pointer, then that *
* routine will be called, otherwise the library default 'more' prompt *
* will be utilized. *
* *
* INPUT: none *
* *
* OUTPUT: none *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 07/25/1991 JLB : Created. *
*=========================================================================*/
void Set_More_On(void)
{
MoreOn = TRUE;
ScrollCounter = 0;
}
/***************************************************************************
* SET_MORE_OFF -- Turns the 'more' prompting off. *
* *
* This routine will turn the 'more' prompting that Window_Print does *
* off. *
* *
* INPUT: none *
* *
* OUTPUT: none *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 07/25/1991 JLB : Created. *
*=========================================================================*/
void Set_More_Off(void)
{
MoreOn = FALSE;
}
/***************************************************************************
* CHANGE_WINDOW -- Changes the 'current' window in the system. *
* *
* Use this routine to change the 'current' window. The current window *
* is used in Window_Print and some other graphic output routines. *
* *
* INPUT: windnum -- The window number to change to. *
* *
* OUTPUT: Returns with the previously current window. *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 07/25/1991 JLB : Created. *
*=========================================================================*/
int Change_Window(int windnum)
{
int oldwindow;
int *data;
oldwindow = Window;
Window = windnum;
data = &WindowList[windnum][0];
WinX = *data++;
WinY = *data++;
WinW = *data++;
WinH = *data++;
WinC = *data++;
WinB = *data++;
WinCx = *data++;
WinCy = *data++;
ScrollCounter = 0;
WPos = WinCx / (FontWidth+FontXSpacing);
WindowLines = (WinH-FontYSpacing) / (FontHeight+FontYSpacing);
WindowWidth = WinW << 3;
WindowColumns = WindowWidth / (FontWidth+FontXSpacing);
return (oldwindow);
}
/***************************************************************************
* CHANGE_NEW_WINDOW -- Combined Change_Window and New_Window. *
* *
* This is a combo-routine. It merely combines the Change_Window *
* with the New_Window routines. It will save some (small) code if *
* you use this routine instead of the two function calls. *
* *
* INPUT: window -- Window number to change to and clear. *
* *
* OUTPUT: Returns with the previously current window. *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 07/25/1991 JLB : Created. *
*=========================================================================*/
int Change_New_Window(int windnum)
{
int oldwindow;
oldwindow = Change_Window(windnum);
New_Window();
return(oldwindow);
}
/***************************************************************************
* NEW_WINDOW -- Clears the current window to the background color. *
* *
* This routine clears the current window to the background color. It *
* is used in preparation to Window_Print because it ensures a clean *
* 'slate' for the text. *
* *
* INPUT: none *
* *
* OUTPUT: none *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 07/25/1991 JLB : Created. *
*=========================================================================*/
void New_Window(void)
{
int x,y,w,h;
x = WinX << 3;
y = WinY;
w = (WinX + WinW) << 3;
h = WinY + WinH;
LogicPage->Fill_Rect(x, y, w - 1, h - 1, WinB);
WinCx = WPos = 0;
WinCy = 0;
ScrollCounter = 0;
}
/***************************************************************************
* WINDOW_INT_PRINT -- Prints an integer to the window. *
* *
* Use this routine to print an integer to the window. This routine *
* as all other Window printing routines will handle word wrap. *
* *
* INPUT: num -- The integer to convert to ASCII and print. *
* *
* OUTPUT: none *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 07/25/1991 JLB : Created. *
*=========================================================================*/
void Window_Int_Print(int num)
{
Window_Print("%d", num);
}
/***************************************************************************
* WINDOW_PRINT -- Displays and wraps text into a window. *
* *
* This is the general purpos text output routine that will handle *
* word wrap within a window. It is useful for displaying arbitrary *
* text. This routine will handle dipthonged text and as such it *
* can be quite useful in saving memory. *
* *
* INPUT: string -- String to print. This can be of ANY length and *
* can even contain some formatting codes. The *
* codes supported are: *
* *
* KA_SETX Forces the cursor X position to the value *
* specified. *
* *
* KA_SETY Forces the cursor Y position to the value *
* specified. *
* *
* KA_MORE Causes an immediate "<MORE>" prompt *
* regardless of the scroll situation. *
* *
* KA_RETURN Breaks line and continues output at the *
* left edge of following line. *
* *
* *
* KA_FORMFEED Clears the window and continues printing at *
* the upper left corner. *
* *
* KA_SETBKGDCOL Set the background color with the color *
* specified by the following byte. *
* *
* *
* KA_SETFORECOL Set the foreground color with the color *
* specified by the following byte. *
* *
* KA_TAB Move the cursor over to the next tabstop. *
* Tabstops are set every 8 columns. *
* *
* KA_SPCTAB Insert spaces until the cursor is positioned *
* at the next tabstop. *
* *
* %s Replace the "%s" with the text pointed to *
* by the pointer argument passed to the *
* routine (follows same method a printf). *
* *
* %d Replace the "%d" with an integer ASCII *
* number of the int passed to the routine. *
* *
* OUTPUT: none *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 07/25/1991 JLB : Created. *
* 07/29/1991 JLB : Added MORE, SETX, and SETY *
*=========================================================================*/
void Window_Print(char const string[], ...)
{
int oldcx, x, y; // Scratch variables.
char c; // Current character.
char buffer[10]; // Working %d buffer.
int old_c, old_b; // Original window colors.
va_list arg; // Argument list var.
va_start(arg, string);
WordWrapFlag = FALSE; // initialize word wrap flag.
Pos = PPos = 0;
Line[0] = '\0';
Char[0] = Char[1] = 0;
MainSource = (char*)&string[0];
AltSource = NULL;
old_c = WinC;
old_b = WinB;
//BG if (LogicPage == SEENPAGE) {
//BG Window_Hide_Mouse(Window);
//BG }
while (TRUE) {
c = Fetch_Char();
if (!c) break; // Exit on NULL character.
/*
** Substitution commands only work if not already expanding a
** string.
*/
if (!AltSource) {
if (c == '%') {
switch(tolower(Char[0])) {
case 's':
AltSource = va_arg(arg, char*);
if (AltSource) {
Stack = Char[1];
Char[0] = Char[1] = '\0';
c = Fetch_Char();
}
break;
case 'd':
AltSource = buffer;
sprintf(buffer, "%d", va_arg(arg, int));
Stack = Char[1];
Char[0] = Char[1] = '\0';
c = Fetch_Char();
break;
default:
break;
}
}
}
switch(c) {
#if(FALSE)
// these are the positions of foreign language characters
/*
** These are characters that shouldn't be window printed because
** they are currently reserved.
*/
case KA_CTRL_C:
case KA_CTRL_D:
case KA_CTRL_E:
case KA_CTRL_G:
case KA_CTRL_J:
case KA_CTRL_K:
case KA_CTRL_N:
case KA_CTRL_O:
case KA_CTRL_P:
case KA_CTRL_Q:
case KA_CTRL_R:
case KA_CTRL_T:
case KA_CTRL_U:
case KA_CTRL_V:
case KA_CTRL_W:
case KA_CTRL_Z:
case KA_CTRL_BACKSLASH:
case KA_CTRL_CARROT:
case KA_CTRL_UNDERLINE:
break;
#endif
/*
** Force cursor column to specified X value.
*/
case KA_SETX:
Flush_Line();
WPos = Fetch_Char();
WPos = MAX(0, WPos);
// WPos is max width char position
WPos = MIN(WindowColumns-1, WPos);
WinCx = WPos * (FontWidth+FontXSpacing);
break;
/*
** Force the cursor to specified Y value.
*/
case KA_SETY:
Flush_Line();
WinCy = Fetch_Char();
//WinCy = MAX(0, WinCy);
WinCy = MIN((long)WindowLines-1, (long)WinCy);
break;
/*
** Force a "<MORE>" prompt.
*/
case KA_MORE:
Flush_Line();
if (Window_More_Ptr) {
//BG if (LogicPage == SEENPAGE) Window_Show_Mouse();
Window_More_Ptr(TXT_MoreText, MoreSpace, MoreFColor, MoreBColor);
//BG if (LogicPage == SEENPAGE) Window_Hide_Mouse(Window);
}
break;
/*
** Clear and home the window cursor. This is the same
** as New_Window().
*/
case KA_FORMFEED:
New_Window();
break;
/*
** Move cursor to start of next line.
*/
case KA_RETURN:
Flush_Line();
ScrollCounter++;
WinCx = 0;
#if(FALSE)
if (WinCy >= WindowLines-1) {
Scroll_Window();
}
else {
WinCy++;
}
#else
WinCy++;
#endif
break;
/*
** Set the background color.
*/
case KA_SETBKGDCOL:
Flush_Line();
WinB = Fetch_Char();
break;
/*
** Set the foreground color.
*/
case KA_SETFORECOL:
Flush_Line();
WinC = Fetch_Char();
break;
/*
** Move cursor to next column.
*/
case KA_TAB:
Flush_Line();
WPos = ((WPos + 8) & 0xFFF8) - 1;
if (WPos >= WindowColumns) {
WPos = 0;
}
WinCx = WPos * (FontWidth+FontXSpacing);
break;
/*
** Tab to specified column but add spaces.
*/
case KA_SPCTAB:
Flush_Line();
oldcx = WinCx;
x = WinX << 3;
y = WinY + (WinCy * (FontHeight+FontYSpacing));
WPos = ((WPos + 8) & 0xFFF8) - 1;
if (WPos >= WindowColumns) {
WinCx = WPos = 0;
// Fill_Rect instead of printing spaces
LogicPage->Fill_Rect(x + oldcx, y,
x + WindowWidth - 1, y + (FontHeight+FontYSpacing) - 1, WinB);
ScrollCounter++;
WinCy++;
}
else {
WinCx = WPos * (FontWidth+FontXSpacing);
// Fill_Rect instead of printing spaces
LogicPage->Fill_Rect(x + oldcx, y,
x + WinCx - 1, y + (FontHeight+FontYSpacing) - 1, WinB);
}
break;
/*
** next character is a extended value 1-127, but 128 is added
** for a value 129-255
*/
case KA_EXTEND:
c = 127;
// NOTE: this falls thru to the default case DO NOT MOVE!!!!!
/*
** next character is a literal value 1-127, except 13
*/
case KA_LITERAL:
if (c != (char) 127) { // check if fell thru from extend case
c = 0; // set to zero for literal case
}
c += Fetch_Char();
// NOTE: this falls thru to the default case DO NOT MOVE!!!!!
/*
** Normal character output.
*/
default:
PPos += Char_Pixel_Width(c); // get pixel location of next char
Line[Pos++] = c;
Line[Pos] = '\0';
if (WinCx + PPos > WindowWidth) {
Flush_Line();
}
break;
}
}
/*
** If there is text still pending, then display it before exiting.
*/
if (Pos) Flush_Line();
/*
** Record changes in the cursor position.
*/
WindowList[Window][WINDOWCURSORX] = WinCx;
WindowList[Window][WINDOWCURSORY] = WinCy;
/*
** Restore the window colors to their original values.
*/
WindowList[Window][WINDOWFCOL] = WinC = old_c;
WindowList[Window][WINDOWBCOL] = WinB = old_b;
//BG if (LogicPage == SEENPAGE) {
//BG Window_Show_Mouse();
//BG }
va_end(arg);
}
/***************************************************************************
* SCROLL_WINDOW -- Scrolls the text window up one line. *
* *
* This will scroll the text window up one line. It will handle any *
* pausing for "more" if the MoreOn flag is set. *
* *
* INPUT: none *
* *
* OUTPUT: none *
* *
* WARNINGS: This routine assumes that the LogicPage is the SEENPAGE. *
* If this is not the case, the program may appear to hang *
* if a "more" prompt is generated. *
* *
* HISTORY: *
* 07/25/1991 JLB : Created. *
*=========================================================================*/
PRIVATE void Scroll_Window(void)
{
int y; // Top pixel row of bottom line of window.
/*
** Possibly prompt for more text.
*/
if (ScrollCounter >= WindowLines-1 && MoreOn) {
ScrollCounter = 0;
if (Window_More_Ptr) {
//BG if (LogicPage == SEENPAGE) Window_Show_Mouse();
Window_More_Ptr(TXT_MoreText, MoreSpace, MoreFColor, MoreBColor);
//BG if (LogicPage == SEENPAGE) Window_Hide_Mouse(Window);
}
}
/*
** Scroll the window up one line.
*/
y = ((WinH / (FontHeight+FontYSpacing)) - 1) * (FontHeight+FontYSpacing);
LogicPage->Blit(*LogicPage,WinX<<3, WinY + (FontHeight+FontYSpacing), WinX<<3, WinY, WinW<<3, WinH - (FontHeight+FontYSpacing) );
LogicPage->Fill_Rect(WinX<<3,
WinY + y,
((WinX+WinW)<<3) - 1,
WinY + WinH - 1,
WinB);
}
/***************************************************************************
* FLUSH_LINE -- Outputs the accumulate text line to screen. *
* *
* This will display the accumlated text line to the screen. It will *
* handle breaking the text line at an appropriate position. *
* *
* INPUT: none *
* *
* OUTPUT: none *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 07/25/1991 JLB : Created. *
*=========================================================================*/
PRIVATE void Flush_Line(void)
{
int breakit, breaksize, breakwidth;
int x, y; // Coordinates of text print.
int breakpoint; // Point to break the line (if possible).
char breakchar; // Break replace character.
int index; // Backward moving index var.
/*
** There could be a held <CR> and this is implied by the cursor Y position
** beyond the bottom of the window. If this is the case, then scroll the
** window and proceed with the line flush.
*/
while (WinCy >= WindowLines /*&& Pos > 0*/) {
Scroll_Window();
if (WinCy >= WindowLines) WinCy--;
}
//if (WinCy >= WindowLines) WinCy = WindowLines-1;
x = (WinX<<3) + WinCx;
y = WinY + (WinCy*(FontHeight+FontYSpacing));
breakwidth = WindowWidth;
// if (ScrollCounter >= WindowLines - 1 && MoreOn) {
// breakwidth -= (MoreSpace * (FontWidth+FontXSpacing)); // use maximum font width
// }
/*
** Try to break the line at the last space IF the line has reached the edge
** of the window.
*/
breakpoint = Pos;
breaksize = PPos;
if (WinCx + breaksize > breakwidth) {
/*
** Since the text WILL spill past the edge of the window, determine the
** point where the break should occur. If this line is ready for the <MORE>
** prompt, then breaking must account for the <MORE> text.
*/
if (ScrollCounter >= WindowLines - 1 && MoreOn) {
breakwidth -= (MoreSpace * (FontWidth+FontXSpacing)); // use maximum font width
}
breakwidth -= WinCx;
breakit = 0;
for (index = breakpoint - 1; index > 0; index--) {
breakchar = Line[index];
breaksize -= Char_Pixel_Width(breakchar);
// only once, find largest text that can fit on the line
if (!breakit) {
// was this the char that went past the right edge
if (breaksize <= breakwidth) {
breakit = index; // save this position if there is no spaces
}
}
// after largest text is found then look for a space to break on
if (breakit && breakchar == KA_SPACE) {
breakpoint = index;
WordWrapFlag = FALSE; // word will start at beginning of next line
break;
}
}
/*
** Exception: When the current text buffer cannot be broken at a logical
** place AND the text is starting past the left margin, THEN there is
** an implied break between the previous text output and this one.
** Output the current text on the next line left margin.
*/
if (!index) {
if (WinCx && !WordWrapFlag) {
breakpoint = breaksize = 0; // Continue text on next line.
WordWrapFlag = TRUE; // indicate a word continuation.
}
else {
breakpoint = breakit; // Just print as much as possible.
}
}
}
breakchar = Line[breakpoint];
Line[breakpoint] = '\0';
LogicPage->Print(Line, x, y, WinC, WinB);
WinCx += breaksize; // add size of text string printed.
Line[breakpoint] = breakchar;
if (breakchar == KA_SPACE) { // take out a space between words.
breakpoint++;
}
// take out another space for double spacing after end of sentence.
if (Line[breakpoint] == KA_SPACE) {
breakpoint++;
}
strcpy(Line, &Line[breakpoint]);
Pos = strlen(Line);
PPos = String_Pixel_Width(Line);
/*
** If at this point there is still text in the buffer, then flushing has
** not been completed. Scroll to next line and repeat the text flushing
** process.
*/
if (Pos || WinCx >= WindowWidth) {
WinCx = WPos = 0;
#if(FALSE)
if (WinCy >= WindowLines-1) {
Scroll_Window();
} else {
WinCy++;
}
#else
WinCy++;
#endif
Flush_Line();
ScrollCounter++; // must be done after flush line for correct counting
}
}
/***************************************************************************
* IN_CHAR -- Stores (un-dipped) character(s) from input to buffer. *
* *
* Use this routine to fetch the next character from the input stream. *
* If the character was dipthonged, then it will be broken into its *
* component ASCII characters and stored in the specified location. *
* This is the core character stream reading code. *
* *
* INPUT: str -- char pointer to the position to store the character(s)*
* fetched from the input stream. *
* *
* OUTPUT: none *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 07/25/1991 JLB : Created. *
*=========================================================================*/
PRIVATE void In_Char(char *str)
{
char c; // Character to return.
char next; // Following character (if any).
c = next = '\0';
/*
** Fetch a raw byte from the input stream.
*/
if (AltSource) {
if (*AltSource == '\0') {
AltSource = NULL;
c = Stack;
} else {
c = *AltSource++;
}
}
if (!c && MainSource) {
if (*MainSource == '\0') {
MainSource = NULL;
} else {
c = *MainSource++;
}
}
/*
** Convert a dipthong character into it's component
** ASCII characters.
*/
if (c & 0x80) {
c &= 0x7F;
next = c & 0x07;
c = (c & 0x78) >> 3;
next = Dipthong[c][next]; // Dipthong character.
c = Common[c]; // Common character.
}
*str++ = c;
*str = next;
}
/***************************************************************************
* FETCH_CHAR -- Gets one undipthonged char from input. *
* *
* This routine will fetch one character from the input stream. The *
* character has already been un-dipthonged. It is a straight ASCII *
* character. This routine ensures that if the next character in the *
* input stream needs to be examined, it is available in Char[0]. *
* *
* INPUT: none *
* *
* OUTPUT: Returns next character in the input stream (ASCII). If NULL *
* is returned, then this indicates the end of the input stream. *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 07/25/1991 JLB : Created. *
*=========================================================================*/
PRIVATE char Fetch_Char(void)
{
char c; // Character to return.
if (!Char[0]) {
In_Char(&Char[0]);
}
c = Char[0];
Char[0] = Char[1];
Char[1] = '\0';
if (!Char[0]) {
In_Char(&Char[0]);
}
return (c);
}