/* ** Command & Conquer Renegade(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 . */ /*********************************************************************************************** *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** *********************************************************************************************** * * * Project Name : Command & Conquer * * * * $Archive:: /G/wwlib/mono.cpp $* * * * $Author:: Neal_k $* * * * $Modtime:: 10/04/99 10:25a $* * * * $Revision:: 3 $* * * *---------------------------------------------------------------------------------------------* * Functions: * * MonoClass::Clear -- Clears the monochrome screen object. * * MonoClass::Draw_Box -- Draws a box using the IBM linedraw characters. * * MonoClass::Fill_Attrib -- Fill a block with specified attribute. * * MonoClass::MonoClass -- The default constructor for monochrome screen object. * * MonoClass::Pan -- Scroll the window right or left. * * MonoClass::Print -- Prints the text string at the current cursor coordinates. * * MonoClass::Print -- Simple print of text number. * * MonoClass::Printf -- Prints a formatted string to the monochrome screen. * * MonoClass::Printf -- Prints formatted text using text string number. * * MonoClass::Scroll -- Scroll the monochrome screen up by the specified lines. * * MonoClass::Set_Cursor -- Sets the monochrome cursor to the coordinates specified. * * MonoClass::Sub_Window -- Partitions the mono screen into a sub-window. * * MonoClass::Text_Print -- Prints text to the monochrome object at coordinates indicated. * * MonoClass::Text_Print -- Simple text printing from text number. * * MonoClass::View -- Brings the mono object to the main display. * * MonoClass::operator = -- Handles making one mono object have the same imagery as another. * * MonoClass::~MonoClass -- The default destructor for a monochrome screen object. * * Mono_Clear_Screen -- Clear the currently visible monochrome page. * * Mono_Draw_Rect -- Draws rectangle to monochrome screen. * * Mono_Print -- Prints simple text to monochrome screen. * * Mono_Printf -- Prints formatted text to visible page. * * Mono_Text_Print -- Prints text to location specified. * * Mono_X -- Fetches the X cursor position for current visible mono page. * * Mono_Y -- Fetches the Y cursor position for current mono page. * * MonoClass::Set_Default_Attribute -- Set the default attribute for this window. * * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ #include "always.h" #include "data.h" #include "mono.h" #include "monodrvr.h" #include /* ** Global flag to indicate whether mono output is enabled. If it is not enabled, ** then no mono output will occur. */ bool MonoClass::Enabled = false; /* ** This points to the current mono displayed screen. */ MonoClass * MonoClass::Current; /*********************************************************************************************** * MonoClass::MonoClass -- The default constructor for monochrome screen object. * * * * This is the constructor for monochrome screen objects. It handles allocating a free * * monochrome page. If there are no more pages available, then this is a big error. The * * page allocated may not be the visible one. Call the View function in order to bring * * it to the displayed page. * * * * INPUT: none * * * * OUTPUT: none * * * * WARNINGS: none * * * * HISTORY: * * 10/17/1994 JLB : Created. * * 01/06/1997 JLB : Updated to WindowsNT style of mono output. * *=============================================================================================*/ MonoClass::MonoClass(void) : Handle(INVALID_HANDLE_VALUE) { #ifdef _WINDOWS Handle = CreateFile("\\\\.\\MONO", GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (Current == NULL) { Current = this; } #endif } /*********************************************************************************************** * MonoClass::~MonoClass -- The default destructor for a monochrome screen object. * * * * This is the default destructor for a monochrome screen object. * * * * INPUT: none * * * * OUTPUT: none * * * * WARNINGS: none * * * * HISTORY: * * 10/17/1994 JLB : Created. * * 01/06/1997 JLB : Updated to WindowsNT style of mono output. * *=============================================================================================*/ MonoClass::~MonoClass(void) { #ifdef _WINDOWS if (Handle != INVALID_HANDLE_VALUE) { CloseHandle(Handle); Handle = INVALID_HANDLE_VALUE; } if (Current == this) { Current = NULL; } #endif } /*********************************************************************************************** * MonoClass::Pan -- Scroll the window right or left. * * * * This routine will scroll the window to the right or left as indicated by the number of * * rows. * * * * INPUT: cols -- The number of columns to pan the window. Positive numbers pan to the left * * while negative numbers pan to the right. * * * * OUTPUT: none * * * * WARNINGS: none * * * * HISTORY: * * 06/05/1996 JLB : Created. * * 01/06/1997 JLB : Updated to WindowsNT style of mono output. * *=============================================================================================*/ void MonoClass::Pan(int ) { #ifdef _WINDOWS if ( Enabled && (Handle != INVALID_HANDLE_VALUE) ) { unsigned long retval; DeviceIoControl(Handle, (DWORD)IOCTL_MONO_PAN, NULL, 0, NULL, 0, &retval, 0); } #endif } /*********************************************************************************************** * MonoClass::Sub_Window -- Partitions the mono screen into a sub-window. * * * * This routine is used to partition the monochrome screen so that only a sub-window will * * be processed. By using this, a separate rectangle of the screen can be cleared, * * scrolled, panned, or printed into. * * * * INPUT: x,y -- The upper left corner of the new sub-window. * * * * w,h -- Dimensions of the sub-window specified in characters. * * * * OUTPUT: none * * * * WARNINGS: The parameters are clipped as necessary. * * * * HISTORY: * * 06/05/1996 JLB : Created. * * 01/06/1997 JLB : Updated to WindowsNT style of mono output. * *=============================================================================================*/ void MonoClass::Sub_Window(int x, int y, int w, int h) { #ifdef _WINDOWS if ( Enabled && (Handle != INVALID_HANDLE_VALUE) ) { struct subwindow { int X,Y,W,H; } subwindow; unsigned long retval; subwindow.X = x; subwindow.Y = y; subwindow.W = w; subwindow.H = h; DeviceIoControl(Handle, (DWORD)IOCTL_MONO_SET_WINDOW, &subwindow, sizeof(subwindow), NULL, 0, &retval, 0); } #endif } /*********************************************************************************************** * MonoClass::Set_Cursor -- Sets the monochrome cursor to the coordinates specified. * * * * Use this routine to set the monochrome's cursor position to the coordinates specified. * * This is the normal way of controlling where the next Print or Printf will output the * * text to. * * * * INPUT: x,y -- The coordinate to position the monochrome cursor. 0,0 is the upper left * * corner. * * * * OUTPUT: none * * * * WARNINGS: none * * * * HISTORY: * * 10/17/1994 JLB : Created. * * 01/06/1997 JLB : Updated to WindowsNT style of mono output. * *=============================================================================================*/ void MonoClass::Set_Cursor(int x, int y) { #ifdef _WINDOWS if ( Enabled && (Handle != INVALID_HANDLE_VALUE) ) { struct { int X,Y; } cursor; unsigned long retval; cursor.X = x; cursor.Y = y; DeviceIoControl(Handle, (DWORD)IOCTL_MONO_SET_CURSOR, &cursor, sizeof(cursor), NULL, 0, &retval, 0); } #endif } /*********************************************************************************************** * MonoClass::Clear -- Clears the monochrome screen object. * * * * This routine will fill the monochrome screen object with spaces. It is clearing the * * screen of data, making it free for output. The cursor is positioned at the upper left * * corner of the screen by this routine. * * * * INPUT: none * * * * OUTPUT: none * * * * WARNINGS: none * * * * HISTORY: * * 10/17/1994 JLB : Created. * * 01/06/1997 JLB : Updated to WindowsNT style of mono output. * *=============================================================================================*/ void MonoClass::Clear(void) { #ifdef _WINDOWS if ( Enabled && (Handle != INVALID_HANDLE_VALUE) ) { unsigned long retval; DeviceIoControl(Handle, (DWORD)IOCTL_MONO_CLEAR_SCREEN, NULL, 0, NULL, 0, &retval, 0); } #endif } /*********************************************************************************************** * MonoClass::Fill_Attrib -- Fill a block with specified attribute. * * * * This routine will give the specified attribute to the characters within the block * * but will not change the characters themselves. You can use this routine to change the * * underline, blink, or inverse characteristics of text. * * * * INPUT: x,y -- The upper left coordinate of the region to change. * * * * w,h -- The dimensions of the region to change (in characters). * * * * attrib -- The attribute to fill into the region specified. * * * * OUTPUT: none * * * * WARNINGS: none * * * * HISTORY: * * 06/04/1996 JLB : Created. * * 01/06/1997 JLB : Updated to WindowsNT style of mono output. * *=============================================================================================*/ void MonoClass::Fill_Attrib(int x, int y, int w, int h, MonoAttribute attrib) { #ifdef _WINDOWS if ( Enabled && (Handle != INVALID_HANDLE_VALUE) ) { unsigned long retval; struct fillcontrol { int X,Y,W,H,A; } fillcontrol; fillcontrol.X = x; fillcontrol.Y = y; fillcontrol.W = w; fillcontrol.H = h; fillcontrol.A = attrib; DeviceIoControl(Handle, (DWORD)IOCTL_MONO_FILL_ATTRIB, &fillcontrol, sizeof(fillcontrol), NULL, 0, &retval, 0); } #endif } /*********************************************************************************************** * MonoClass::Scroll -- Scroll the monochrome screen up by the specified lines. * * * * Use this routine to scroll the monochrome screen up by the number of lines specified. * * This routine is typically called by the printing functions so that the monochrome screen * * behaves in the expected manner -- printing at the bottom of the screen scrolls it up * * to make room for new text. * * * * INPUT: lines -- The number of lines to scroll the monochrome screen. * * * * OUTPUT: none * * * * WARNINGS: none * * * * HISTORY: * * 10/17/1994 JLB : Created. * * 01/06/1997 JLB : Updated to WindowsNT style of mono output. * *=============================================================================================*/ void MonoClass::Scroll(int ) { #ifdef _WINDOWS if ( Enabled && (Handle != INVALID_HANDLE_VALUE) ) { unsigned long retval; DeviceIoControl(Handle, (DWORD)IOCTL_MONO_SCROLL, NULL, 0, NULL, 0, &retval, 0); } #endif } /*********************************************************************************************** * MonoClass::Printf -- Prints a formatted string to the monochrome screen. * * * * Use this routine to output a formatted string, using the standard formatting options, * * to the monochrome screen object's current cursor position. * * * * INPUT: text -- Pointer to the text to print. * * * * ... -- Any optional parameters to supply in formatting the text. * * * * OUTPUT: none * * * * WARNINGS: The total formatted text length must not exceed 255 characters. * * * * HISTORY: * * 10/17/1994 JLB : Created. * *=============================================================================================*/ void MonoClass::Printf(char const *text, ...) { #ifdef _WINDOWS va_list va; /* ** The buffer object is placed at the end of the local variable list ** so that if the sprintf happens to spill past the end, it isn't likely ** to trash anything (important). The buffer is then manually truncated ** to maximum allowed size before being printed. */ char buffer[256]; if ( !Enabled || (Handle == INVALID_HANDLE_VALUE) ) return; va_start(va, text); vsprintf(buffer, text, va); buffer[sizeof(buffer)-1] = '\0'; Print(buffer); va_end(va); #endif } /*********************************************************************************************** * MonoClass::Printf -- Prints formatted text using text string number. * * * * This routine will take the given text string number and print the formatted text to * * the monochrome screen. * * * * INPUT: text -- The text number to convert into real text (by way of external function). * * * * ... -- Additional parameters as needed. * * * * OUTPUT: none * * * * WARNINGS: none * * * * HISTORY: * * 06/04/1996 JLB : Created. * *=============================================================================================*/ void MonoClass::Printf(int text, ...) { #ifdef _WINDOWS va_list va; /* ** The buffer object is placed at the end of the local variable list ** so that if the sprintf happens to spill past the end, it isn't likely ** to trash anything (important). The buffer is then manually truncated ** to maximum allowed size before being printed. */ char buffer[256]; if ( !Enabled || (Handle == INVALID_HANDLE_VALUE) ) return; va_start(va, text); vsprintf(buffer, Fetch_String(text), va); buffer[sizeof(buffer)-1] = '\0'; Print(buffer); va_end(va); #endif } /*********************************************************************************************** * MonoClass::Print -- Prints the text string at the current cursor coordinates. * * * * Use this routine to output the specified text string at the monochrome object's current * * text coordinate position. * * * * INPUT: ptr -- Pointer to the string to print. * * * * OUTPUT: none * * * * WARNINGS: none * * * * HISTORY: * * 10/17/1994 JLB : Created. * * 01/06/1997 JLB : Updated to WindowsNT style of mono output. * *=============================================================================================*/ void MonoClass::Print(char const * ptr) { #ifdef _WINDOWS if ( Enabled && (Handle != INVALID_HANDLE_VALUE) ) { unsigned long retval; WriteFile(Handle, ptr, strlen(ptr), &retval, NULL); } #endif } /*********************************************************************************************** * MonoClass::Set_Default_Attribute -- Set the default attribute for this window. * * * * This will change the default attribute to that specified. All future text will use * * this new attribute. * * * * INPUT: attrib -- The attribute to make the current default. * * * * OUTPUT: none * * * * WARNINGS: none * * * * HISTORY: * * 01/06/1997 JLB : Created. * *=============================================================================================*/ void MonoClass::Set_Default_Attribute(MonoAttribute attrib) { #ifdef _WINDOWS if ( Enabled && (Handle != INVALID_HANDLE_VALUE) ) { unsigned long retval; DeviceIoControl(Handle, (DWORD)IOCTL_MONO_SET_ATTRIBUTE, &attrib, 1, NULL, 0, &retval, 0); } #endif } /*********************************************************************************************** * MonoClass::Text_Print -- Prints text to the monochrome object at coordinates indicated. * * * * Use this routine to output text to the monochrome object at the X and Y coordinates * * specified. * * * * INPUT: text -- Pointer to the text string to display. * * * * x,y -- The X and Y character coordinates to start the printing at. * * * * attrib-- Optional parameter that specifies what text attribute code to use. * * * * OUTPUT: none * * * * WARNINGS: none * * * * HISTORY: * * 10/17/1994 JLB : Created. * * 01/06/1997 JLB : Updated to WindowsNT style of mono output. * *=============================================================================================*/ void MonoClass::Text_Print(char const *text, int x, int y, MonoAttribute attrib) { #ifdef _WINDOWS if ( Enabled && (Handle != INVALID_HANDLE_VALUE) ) { unsigned long retval; Set_Cursor(x, y); DeviceIoControl(Handle, (DWORD)IOCTL_MONO_SET_ATTRIBUTE, &attrib, 1, NULL, 0, &retval, 0); Print(text); } #endif } /*********************************************************************************************** * MonoClass::Text_Print -- Simple text printing from text number. * * * * This will print the text (represented by the text number) to the location on the * * monochrome screen specified. * * * * INPUT: text -- The text number to print (converted to real text by external routine). * * * * x,y -- The coordinates to begin the printing at. * * * * attrib-- The character attribute to use while printing. * * * * OUTPUT: none * * * * WARNINGS: none * * * * HISTORY: * * 06/04/1996 JLB : Created. * *=============================================================================================*/ void MonoClass::Text_Print(int text, int x, int y, MonoAttribute attrib) { Text_Print(Fetch_String(text), x, y, attrib); } /*********************************************************************************************** * MonoClass::Print -- Simple print of text number. * * * * Prints text represented by the text number specified. * * * * INPUT: text -- The text number to print (converted to real text by external routine). * * * * OUTPUT: none * * * * WARNINGS: none * * * * HISTORY: * * 06/04/1996 JLB : Created. * *=============================================================================================*/ void MonoClass::Print(int text) { Print(Fetch_String(text)); } /*********************************************************************************************** * MonoClass::View -- Brings the mono object to the main display. * * * * Use this routine to display the mono object on the monochrome screen. It is possible * * that the mono object exists on some background screen memory. Calling this routine will * * perform the necessary memory swapping to bring the data to the front. The mono object * * that was currently being viewed is not destroyed by this function. It is merely moved * * off to some background page. It can be treated normally, except that is just isn't * * visible. * * * * INPUT: none * * * * OUTPUT: none * * * * WARNINGS: none * * * * HISTORY: * * 10/17/1994 JLB : Created. * * 01/06/1997 JLB : Updated to WindowsNT style of mono output. * *=============================================================================================*/ void MonoClass::View(void) { #ifdef _WINDOWS if ( Enabled && (Handle != INVALID_HANDLE_VALUE) ) { unsigned long retval; DeviceIoControl(Handle, (DWORD)IOCTL_MONO_BRING_TO_TOP, NULL, 0, NULL, 0, &retval, 0); Current = this; } #endif }