/* ** 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 . */ /*************************************************************************** ** 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 : VQAVIEW * * * * File Name : MONOCHRM.CPP * * * * Programmer : Michael Legg * * * * Start Date : May 10, 1995 * * * * Last Update : May 30, 1995 [ML] * * * *-------------------------------------------------------------------------* * Functions: * * * * These are not our functions, but Microsoft's from DBWIN.EXE * * * * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ #include #include #include #include #include #include typedef struct { char ch; char attr; } CA; #define CCOLMAX 80 #define CROWMAX 25 #define ESC 27 #define BELL 7 #define DEFATTR 0x07 #define CA_SPACE ((DEFATTR << 8) | ' ') // row+1 = DBWIN #define PCA(row, col) (0xB0000 + ( (((row+0)*CCOLMAX)+col) * sizeof(CA))) static void Monochrome_Output( char *string ); static void CACopy( CA *pcaDst, CA *pcaSrc, int cca ); static void CAFill( CA *pcaDst, int cca, int ca ); int rowCur = 0; int colCur = 0; /*************************************************************************** * DEBUG_PRINTF - works like printf, with limit of 10 variable args * * * * INPUT: same as printf * * * * OUTPUT: a message on the monochrome monitor display * * * * WARNINGS: try to end messages with \r\n! * * * * HISTORY: see PVCS log * *=========================================================================*/ void Debug_Printf( char *format_string, ... ) { va_list ap; int arg[ 10 ]; char output_string[ 255 ]; va_start( ap, format_string ); arg[ 0 ] = va_arg( ap, int ); arg[ 1 ] = va_arg( ap, int ); arg[ 2 ] = va_arg( ap, int ); arg[ 3 ] = va_arg( ap, int ); arg[ 4 ] = va_arg( ap, int ); arg[ 5 ] = va_arg( ap, int ); arg[ 6 ] = va_arg( ap, int ); arg[ 7 ] = va_arg( ap, int ); arg[ 8 ] = va_arg( ap, int ); arg[ 9 ] = va_arg( ap, int ); va_end( ap ); sprintf( (char *) output_string, (char *) format_string, arg[ 0 ], arg[ 1 ], arg[ 2 ], arg[ 3 ], arg[ 4 ], arg[ 5 ], arg[ 6 ], arg[ 7 ], arg[ 8 ], arg[ 9 ] ); Debug_Mono_Message( (char *) output_string ); } /*************************************************************************** * DEBUG_MONO_MESSAGE -- Post a line to the monochrome monitor * * * * INPUT: the message to print * * * * OUTPUT: a message on the monochrome monitor display * * * * WARNINGS: try to end messages with \r\n! * * * * HISTORY: see PVCS log * *=========================================================================*/ void Debug_Mono_Message( char *message ) { char *temp_string; char *temp_null_position; char temp_char; int length_left; length_left = strlen( message ); temp_null_position = message; while ( length_left > CCOLMAX ) { temp_string = temp_null_position; temp_null_position += CCOLMAX; temp_char = *temp_null_position; temp_null_position[ 0 ] = '\0'; Monochrome_Output( temp_string ); *temp_null_position = temp_char; length_left -= CCOLMAX; } temp_string = temp_null_position; Monochrome_Output( temp_string ); } static void Monochrome_Output( char *string ) { CA *pca; char ch; static int _initialized = FALSE; pca = (CA *) PCA(rowCur, colCur); if ( ! _initialized ) { CAFill( (CA *) PCA(0, 0), (CCOLMAX * CROWMAX), CA_SPACE ); colCur = 0; rowCur = 0; _initialized = TRUE; } while ( TRUE ) { ch = *string++; if ( ! ch ) { break; } switch (ch) { case '\b': if (colCur > 0) { colCur--; pca--; pca->ch = ' '; pca->attr = DEFATTR; } break; case BELL: // MessageBeep(0); break; case '\t': pca += 8 - colCur % 8; colCur += 8 - colCur % 8; break; case '\r': colCur = 0; pca = (CA *) PCA(rowCur, colCur); break; default: pca->ch = ch; pca->attr = DEFATTR; pca++; colCur++; if (colCur < CCOLMAX) break; // fall through to handle LF case '\n': colCur = 0; rowCur++; if (rowCur >= CROWMAX) { CACopy( (CA *) PCA(0, 0), (CA *) PCA(1, 0), CCOLMAX * (CROWMAX - 1)); CAFill( (CA *) PCA(CROWMAX - 1, 0), CCOLMAX, CA_SPACE); rowCur = CROWMAX - 1; } pca = (CA *) PCA(rowCur, colCur); break; case ESC: // // ANSI clear screen escape // if (string[1] == '[' && string[2] == '2' && string[3] == 'J') { CAFill( (CA *)PCA(0,0), CCOLMAX * CROWMAX, CA_SPACE); rowCur = colCur = 0; string += 3; } } } } static void CACopy( CA *pcaDst, CA *pcaSrc, int cca ) { int i; for ( i = 0; i < cca; i ++ ) { *pcaDst = *pcaSrc; pcaDst ++; pcaSrc ++; } } static void CAFill( CA *pcaDst, int cca, int ca ) { int i; for ( i = 0; i < cca; i ++ ) { memcpy( pcaDst, &ca, sizeof( int ) ); pcaDst ++; } }