973 lines
37 KiB
C++
973 lines
37 KiB
C++
//
|
||
// Copyright 2020 Electronic Arts Inc.
|
||
//
|
||
// TiberianDawn.DLL and RedAlert.dll and corresponding source code 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.
|
||
|
||
// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed
|
||
// in the hope that it will be useful, but with permitted additional restrictions
|
||
// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT
|
||
// distributed with this program. You should have received a copy of the
|
||
// GNU General Public License along with permitted additional restrictions
|
||
// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection
|
||
|
||
/* $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 "ww_win.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)(char const *,int,int,int) = Standard_More_Prompt;
|
||
|
||
extern GraphicViewPortClass *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 }
|
||
|
||
// PWG - have to figure out how to do this in windows library
|
||
|
||
// 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, (unsigned char)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, (unsigned char)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, (unsigned char)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, (unsigned char)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 > (unsigned)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,
|
||
(unsigned char)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 >= (unsigned)WindowLines /*&& Pos > 0*/) {
|
||
Scroll_Window();
|
||
if (WinCy >= (unsigned)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 > (unsigned)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 >= (unsigned)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 & (char)0x07;
|
||
c = (char)((c & (char)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);
|
||
}
|
||
|
||
|