CnC_Remastered_Collection

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

MSGLIST.CPP (32677B)


      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:   F:\projects\c&c\vcs\code\msglist.cpv   1.4   16 Oct 1995 16:48:20   JOE_BOSTIC  $ */
     17 /***************************************************************************
     18  *                                                                         *
     19  *                 Project Name : Command & Conquer                        *
     20  *                                                                         *
     21  *                    File Name : MSGLIST.CPP                              *
     22  *                                                                         *
     23  *                   Programmer : Bill R. Randolph                         *
     24  *                                                                         *
     25  *                   Start Date : 05/22/95                                 *
     26  *                                                                         *
     27  *                  Last Update : June 26, 1995 [BRR]                      *
     28  *                                                                         *
     29  *-------------------------------------------------------------------------*
     30  * Functions:                                                              *
     31  *   MessageListClass::Add_Edit -- Adds editable string to message list    *
     32  *   MessageListClass::Add_Message -- displays the given message           *
     33  *   MessageListClass::Draw -- Draws the messages                          *
     34  *   MessageListClass::Get_Edit_Buf -- gets edit buffer                    *
     35  *   MessageListClass::Init -- Inits message system, sets options          *
     36  *   MessageListClass::Input -- Handles input for sending messages         *
     37  *   MessageListClass::Manage -- Manages multiplayer messages              *
     38  *   MessageListClass::MessageListClass -- constructor                     *
     39  *   MessageListClass::~MessageListClass -- destructor                     *
     40  *   MessageListClass::Num_Messages -- returns # messages in the list      *
     41  *   MessageListClass::Set_Width -- sets allowable width of messages       *
     42  * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
     43 
     44 #include "function.h"
     45 
     46 // ST = 12/17/2018 5:44PM
     47 #ifndef TickCount
     48 extern TimerClass					TickCount;
     49 #endif
     50 
     51 char MessageListClass::MessageBuffers[MAX_NUM_MESSAGES][MAX_MESSAGE_LENGTH + 30];
     52 char MessageListClass::BufferAvail[MAX_NUM_MESSAGES];
     53 
     54 /***************************************************************************
     55  * MessageListClass::MessageListClass -- constructor                       *
     56  *                                                                         *
     57  * INPUT:                                                                  *
     58  *      x,y         coord of upper-left of top message                     *
     59  *      max_msg      max messages allowed, including edit message          *
     60  *                                                                         *
     61  * OUTPUT:                                                                 *
     62  *      none.                                                              *
     63  *                                                                         *
     64  * WARNINGS:                                                               *
     65  *      none.                                                              *
     66  *                                                                         *
     67  * HISTORY:                                                                *
     68  *   05/21/1995 BRR : Created.                                             *
     69  *=========================================================================*/
     70 MessageListClass::MessageListClass(void)
     71 {
     72 	int i;
     73 
     74 	MessageList = 0;
     75 	MessageX = 0;
     76 	MessageY = 0;
     77 	MaxMessages = 0;
     78 	MaxChars = 0;
     79 	Height = 0;
     80 	EditLabel = 0;
     81 	EditBuf = 0;
     82 	EditCurPos = 0;
     83 	EditInitPos = 0;
     84 
     85 	for (i = 0; i < MAX_NUM_MESSAGES; i++) {
     86 		BufferAvail[i] = 1;
     87 	}
     88 
     89 }
     90 
     91 
     92 /***************************************************************************
     93  * MessageListClass::~MessageListClass -- destructor                       *
     94  *                                                                         *
     95  * INPUT:                                                                  *
     96  *      x,y         coord of upper-left of top message                     *
     97  *      max_msg      max messages allowed, including edit message          *
     98  *                                                                         *
     99  * OUTPUT:                                                                 *
    100  *      none.                                                              *
    101  *                                                                         *
    102  * WARNINGS:                                                               *
    103  *      none.                                                              *
    104  *                                                                         *
    105  * HISTORY:                                                                *
    106  *   05/21/1995 BRR : Created.                                             *
    107  *=========================================================================*/
    108 MessageListClass::~MessageListClass()
    109 {
    110 	Init(0,0,0,0,0);
    111 }
    112 
    113 
    114 /***************************************************************************
    115  * MessageListClass::Init -- Inits message system, sets options            *
    116  *                                                                         *
    117  * INPUT:                                                                  *
    118  *      x,y         coord of upper-left of top message                     *
    119  *      max_msg      max messages allowed, including edit message          *
    120  *      maxchars      max # characters allowed per message                 *
    121  *                                                                         *
    122  * OUTPUT:                                                                 *
    123  *      none.                                                              *
    124  *                                                                         *
    125  * WARNINGS:                                                               *
    126  *      none.                                                              *
    127  *                                                                         *
    128  * HISTORY:                                                                *
    129  *   05/21/1995 BRR : Created.                                             *
    130  *=========================================================================*/
    131 void MessageListClass::Init(int x, int y, int max_msg, int maxchars, int height)
    132 {
    133 	TextLabelClass *txtlabel;
    134 	int i;
    135 
    136 	/*------------------------------------------------------------------------
    137 	Remove every entry in the list
    138 	------------------------------------------------------------------------*/
    139 	txtlabel = MessageList;
    140 	while (txtlabel) {
    141 		MessageList = (TextLabelClass *)txtlabel->Remove();
    142 		delete txtlabel;
    143 		txtlabel = MessageList;
    144 	}
    145 
    146 	/*------------------------------------------------------------------------
    147 	Mark all buffers as available
    148 	------------------------------------------------------------------------*/
    149 	for (i = 0; i < MAX_NUM_MESSAGES; i++) {
    150 		BufferAvail[i] = 1;
    151 	}
    152 
    153 	/*------------------------------------------------------------------------
    154 	Init variables
    155 	------------------------------------------------------------------------*/
    156 	MessageList = 0;
    157 	MessageX = x;
    158 	MessageY = y;
    159 
    160 	MaxMessages = max_msg;
    161 	if (MaxMessages > MAX_NUM_MESSAGES)
    162 		MaxMessages = MAX_NUM_MESSAGES;
    163 
    164 	MaxChars = maxchars;
    165 	if (MaxChars > MAX_MESSAGE_LENGTH)
    166 		MaxChars = MAX_MESSAGE_LENGTH;
    167 
    168 	Height = height;
    169 	EditLabel = 0;
    170 	EditBuf = 0;
    171 	EditCurPos = 0;
    172 	EditInitPos = 0;
    173 }
    174 
    175 
    176 /***************************************************************************
    177  * MessageListClass::Add_Message -- displays the given message             *
    178  *                                                                         *
    179  * INPUT:                                                                  *
    180  *      txt         text to display                                        *
    181  *      color         color to draw text in                                *
    182  *      style         style to use                                         *
    183  *      timeout      # of ticks the thing is supposed to last (-1 = forever)*
    184  *                                                                         *
    185  * OUTPUT:                                                                 *
    186  *      ptr to new TextLabelClass object.                                  *
    187  *                                                                         *
    188  * WARNINGS:                                                               *
    189  * The TextLabelClass's text buffer is free'd when the class is free'd,    *
    190  * so never pass it a static buffer.                                       *
    191  *                                                                         *
    192  * HISTORY:                                                                *
    193  *   05/05/1995 BRR : Created.                                             *
    194  *=========================================================================*/
    195 TextLabelClass * MessageListClass::Add_Message(char *txt, int color,
    196 	TextPrintType style, int timeout, unsigned short magic_number, unsigned short crc)
    197 {
    198 	int num_msg;
    199 	TextLabelClass *txtlabel;
    200 	int x,y;
    201 	GadgetClass *gadg;
    202 	int i,j;
    203 	int found;
    204 	int	position;
    205 	char	*raw_string;
    206 	char	*current_string;
    207 	char	*s1,*s2;
    208 	bool	same;
    209 #if (0)
    210 #if (GERMAN)
    211 			static int from_adjust = -1;
    212 #else
    213 #if (FRENCH)
    214 			static int from_adjust = -2;
    215 #else
    216 			static int from_adjust = 0;
    217 #endif
    218 #endif
    219 #endif	//(0)
    220 
    221 	/*------------------------------------------------------------------------
    222 	Prevent a duplicate message.  (The IPXManager Global Channel cannot detect
    223 	a resend of a packet, so sometimes two identical messages appear in a row.)
    224 	------------------------------------------------------------------------*/
    225 	if (MessageList) {
    226 		txtlabel = MessageList;
    227 		while (txtlabel) {
    228 			/*
    229 			** Dont check for duplicates in multi-segment strings
    230 			*/
    231 			if (!txtlabel->Segments){
    232 				if (!strcmp (txtlabel->Text,txt) && txtlabel->Color == color &&
    233 					txtlabel->Style == style) {
    234 					return(txtlabel);
    235 				}
    236 			}
    237 			txtlabel = (TextLabelClass *)txtlabel->Get_Next();
    238 		}
    239 	}
    240 
    241 
    242 	/*
    243 	** If the magic number is a valid message tail then see if we
    244 	** can add this message to the tail of an existing message (crc's must also match)
    245 	*/
    246 	if (magic_number > MESSAGE_HEAD_MAGIC_NUMBER &&
    247 	    magic_number < MESSAGE_HEAD_MAGIC_NUMBER+MAX_MESSAGE_SEGMENTS){
    248 
    249 		position = magic_number - MESSAGE_HEAD_MAGIC_NUMBER;
    250 		txtlabel = MessageList;
    251 
    252 		while (txtlabel) {
    253 			if (txtlabel->Color == color && txtlabel->Style == style && txtlabel->CRC == crc) {
    254 
    255 				same = true;
    256 
    257 				s1 = strchr(txtlabel->Text, ':');
    258 				s2 = strchr(txt, ':');
    259 
    260 				if (s1 && s2){
    261 					*s1 = 0;
    262 					*s2 = 0;
    263 
    264 					same = !strcmp (txtlabel->Text, txt);
    265 
    266 					*s1 = ':';
    267 					*s2 = ':';
    268 				}
    269 
    270 				if (same){
    271 
    272 					/*
    273 					** If this message segment hasnt already come through then add it to the existing text
    274 					*/
    275 					if (! (txtlabel->Segments & (1 << position)) ) {
    276 						/*
    277 						** Search for the ':' to find the actual message after the players name
    278 						*/
    279 						raw_string = s2;
    280 						current_string = s1;
    281 						if (raw_string++ && current_string++){
    282 							memcpy (current_string + (position*(COMPAT_MESSAGE_LENGTH-5))/*+from_adjust*/, raw_string, COMPAT_MESSAGE_LENGTH-4);
    283 							/*
    284 							** Flag this string segment as complete
    285 							*/
    286 							txtlabel->Segments |= 1<<position;
    287 							return(txtlabel);
    288 						}
    289 					}else{
    290 						/*
    291 						** This segment has already come through for this string so discard it.
    292 						*/
    293 						return (txtlabel);
    294 					}
    295 				}
    296 			}
    297 			txtlabel = (TextLabelClass *)txtlabel->Get_Next();
    298 		}
    299 	}
    300 
    301 
    302 
    303 	/*------------------------------------------------------------------------
    304 	Count the # of messages; if MaxMessages is going to be exceeded, remove
    305 	the top-most message.
    306 	------------------------------------------------------------------------*/
    307 	num_msg = 0;
    308 	if (MessageList) {
    309 		gadg = MessageList;
    310 		while (gadg) {
    311 			num_msg++;
    312 			gadg = gadg->Get_Next();
    313 		}
    314 	}
    315 	/*........................................................................
    316 	Remove the top-most message, but don't remove the edit message.
    317 	........................................................................*/
    318 	if ( (MaxMessages > 0) && ((num_msg + 1) > MaxMessages)) {
    319 		txtlabel = MessageList;
    320 		/*.....................................................................
    321 		If the top label is the edit label, go to the next one; if there is
    322 		no next one, just return.
    323 		.....................................................................*/
    324 		if (txtlabel == EditLabel)
    325 			txtlabel = (TextLabelClass *)txtlabel->Get_Next();
    326 		if (txtlabel==NULL)
    327 			return(NULL);
    328 
    329 		/*.....................................................................
    330 		Remove this message from the list; mark its buffer as being available.
    331 		.....................................................................*/
    332 		MessageList = (TextLabelClass *)txtlabel->Remove();
    333 		for (i = 0; i < MAX_NUM_MESSAGES; i++) {
    334 			if (txtlabel->Text == MessageBuffers[i])
    335 				BufferAvail[i] = 1;
    336 		}
    337 		delete txtlabel;
    338 
    339 		/*.....................................................................
    340 		Recompute everyone's y-coordinate
    341 		.....................................................................*/
    342 		y = MessageY;
    343 		if (MessageList) {
    344 			gadg = MessageList;
    345 			while (gadg) {
    346 				gadg->Y = y;
    347 				gadg = gadg->Get_Next();
    348 				y += Height;
    349 			}
    350 		}
    351 	}
    352 
    353 	/*------------------------------------------------------------------------
    354 	Figure out the message's y-coordinate; put it below the other messages
    355 	------------------------------------------------------------------------*/
    356 	x = MessageX;
    357 	y = MessageY;
    358 	if (MessageList) {
    359 		gadg = MessageList;
    360 		while (gadg) {
    361 			gadg = gadg->Get_Next();
    362 			y += Height;
    363 		}
    364 	}
    365 
    366 	/*------------------------------------------------------------------------
    367 	Create the message
    368 	------------------------------------------------------------------------*/
    369 	txtlabel = new TextLabelClass (txt, x, y, color, style);
    370 	if (timeout==-1) {
    371 		txtlabel->UserData = 0;
    372 	} else {
    373 		txtlabel->UserData = TickCount.Time() + timeout;
    374 	}
    375 
    376 	/*------------------------------------------------------------------------
    377 	Find a buffer to store our message in; if there are none, don't add the
    378 	message.
    379 	------------------------------------------------------------------------*/
    380 	found = 0;
    381 	txtlabel->Segments = 0;
    382 	txtlabel->CRC = crc;
    383 
    384 	for (i = 0; i < MAX_NUM_MESSAGES; i++) {
    385 		if (BufferAvail[i]) {
    386 			BufferAvail[i] = 0;
    387 			memset (MessageBuffers[i],0,MAX_MESSAGE_LENGTH + 30);
    388 			strcpy (MessageBuffers[i],txt);
    389 
    390 			/*
    391 			** If this is a segment from a larger message then put it in the right place
    392 			** in the buffer and clear out the rest with spaces
    393 			*/
    394 			if (magic_number >= MESSAGE_HEAD_MAGIC_NUMBER &&
    395 			    magic_number < MESSAGE_HEAD_MAGIC_NUMBER+MAX_MESSAGE_SEGMENTS){
    396 				raw_string = strchr(txt, ':');
    397 				char *dest_str = strchr(MessageBuffers[i], ':');
    398 				if (dest_str){
    399 					dest_str++;
    400 				}else{
    401 					dest_str = MessageBuffers[i];
    402 				}
    403 
    404 				if (raw_string++){
    405 					for (j=0 ; j<3 ; j++){
    406 						if (! ((magic_number - j) == MESSAGE_HEAD_MAGIC_NUMBER)){
    407 							memset (dest_str + j*(COMPAT_MESSAGE_LENGTH-4)/*+from_adjust*/, 32, COMPAT_MESSAGE_LENGTH-4);
    408 						}else{
    409 							strcpy(dest_str + j*(COMPAT_MESSAGE_LENGTH-4)/*+from_adjust*/, raw_string);
    410 						}
    411 					}
    412 				*(dest_str +((COMPAT_MESSAGE_LENGTH-4)*MAX_MESSAGE_SEGMENTS-1)) = 0;
    413 
    414 				}
    415 				position = magic_number - MESSAGE_HEAD_MAGIC_NUMBER;
    416 				txtlabel->Segments = 1<<position;
    417 			}
    418 
    419 			txtlabel->Text = MessageBuffers[i];
    420 			found = 1;
    421 			break;
    422 		}
    423 	}
    424 	if (!found) {
    425 		delete txtlabel;
    426 		return (NULL);
    427 	}
    428 
    429 	/*------------------------------------------------------------------------
    430 	Attach the message to our list
    431 	------------------------------------------------------------------------*/
    432 	if (MessageList) {
    433 		txtlabel->Add_Tail (*MessageList);
    434 	} else {
    435 		MessageList = txtlabel;
    436 	}
    437 
    438 	return(txtlabel);
    439 }
    440 
    441 
    442 /***************************************************************************
    443  * MessageListClass::Add_Edit -- Adds editable string to message list      *
    444  *                                                                         *
    445  * INPUT:                                                                  *
    446  *      color         color of edit message                                *
    447  *      style         style of edit message                                *
    448  *      to            string: who to send to                               *
    449  *      width			width of editbox in pixels                           *
    450  *                                                                         *
    451  * OUTPUT:                                                                 *
    452  *      ptr to new TextLabelClass                                          *
    453  *                                                                         *
    454  * WARNINGS:                                                               *
    455  *      none.                                                              *
    456  *                                                                         *
    457  * HISTORY:                                                                *
    458  *   05/22/1995 BRR : Created.                                             *
    459  *=========================================================================*/
    460 TextLabelClass * MessageListClass::Add_Edit(int color, TextPrintType style,
    461 	char *to, int width)
    462 {
    463 	/*------------------------------------------------------------------------
    464 	Do nothing if we're already in "edit" mode
    465 	------------------------------------------------------------------------*/
    466 	if (EditLabel)
    467 		return(NULL);
    468 
    469 	/*------------------------------------------------------------------------
    470 	Initialize the buffer positions; add a new label to the label list.
    471 	------------------------------------------------------------------------*/
    472 	EditCurPos = EditInitPos = strlen(to);
    473 	EditLabel = Add_Message (to, color, style, -1, 0, 0);
    474 	Width = width;
    475 
    476 	/*------------------------------------------------------------------------
    477 	Save our edit buffer pointer.
    478 	------------------------------------------------------------------------*/
    479 	if (EditLabel)
    480 		EditBuf = EditLabel->Text;
    481 	else
    482 		EditBuf = NULL;
    483 
    484 	return(EditLabel);
    485 }
    486 
    487 
    488 /***************************************************************************
    489  * MessageListClass::Get_Edit_Buf -- gets edit buffer                      *
    490  *                                                                         *
    491  * INPUT:                                                                  *
    492  *      none.                                                              *
    493  *                                                                         *
    494  * OUTPUT:                                                                 *
    495  *      ptr to edit buffer, minus the "To:" header                         *
    496  *                                                                         *
    497  * WARNINGS:                                                               *
    498  *      none.                                                              *
    499  *                                                                         *
    500  * HISTORY:                                                                *
    501  *   05/21/1995 BRR : Created.                                             *
    502  *=========================================================================*/
    503 char * MessageListClass::Get_Edit_Buf(void)
    504 {
    505 	if (!EditBuf)
    506 		return(NULL);
    507 
    508 	return(EditBuf + EditInitPos);
    509 }
    510 
    511 
    512 /***************************************************************************
    513  * MessageListClass::Manage -- Manages multiplayer messages                *
    514  *                                                                         *
    515  * If this routine returns TRUE, the caller should update the display.     *
    516  *                                                                         *
    517  * INPUT:                                                                  *
    518  *      none.                                                              *
    519  *                                                                         *
    520  * OUTPUT:                                                                 *
    521  *      none.                                                              *
    522  *                                                                         *
    523  * WARNINGS:                                                               *
    524  *      0 = no change has occurred, 1 = changed                            *
    525  *                                                                         *
    526  * HISTORY:                                                                *
    527  *   05/05/1995 BRR : Created.                                             *
    528  *=========================================================================*/
    529 int MessageListClass::Manage (void)
    530 {
    531 	TextLabelClass *txtlabel;
    532 	TextLabelClass *next;
    533 	int changed = 0;
    534 	int y;
    535 	GadgetClass *gadg;
    536 	int i;
    537 
    538 	/*------------------------------------------------------------------------
    539 	Loop through all messages
    540 	------------------------------------------------------------------------*/
    541 	txtlabel = MessageList;
    542 	while (txtlabel) {
    543 		/*.....................................................................
    544 		If this message's time is up, remove it from the list
    545 		.....................................................................*/
    546 		if (txtlabel->UserData != 0 && (unsigned)TickCount.Time() > txtlabel->UserData) {
    547 			/*..................................................................
    548 			If we're about to delete the edit message, clear our edit message
    549 			values.
    550 			..................................................................*/
    551 			if (txtlabel == EditLabel) {
    552 				EditLabel = 0;
    553 				EditBuf = 0;
    554 			}
    555 			/*..................................................................
    556 			Save the next ptr in the list; remove this entry
    557 			..................................................................*/
    558 			next = (TextLabelClass *)txtlabel->Get_Next();
    559 			MessageList = (TextLabelClass *)txtlabel->Remove();
    560 			for (i = 0; i < MAX_NUM_MESSAGES; i++) {
    561 				if (txtlabel->Text == MessageBuffers[i])
    562 					BufferAvail[i] = 1;
    563 			}
    564 			delete txtlabel;
    565 			changed = 1;
    566 			txtlabel = next;
    567 		} else {
    568 			txtlabel = (TextLabelClass *)txtlabel->Get_Next();
    569 		}
    570 	}
    571 
    572 	/*------------------------------------------------------------------------
    573 	If a changed has been made, recompute the y-coord of all messages
    574 	------------------------------------------------------------------------*/
    575 	if (changed) {
    576 
    577 		y = MessageY;
    578 		if (MessageList) {
    579 			gadg = MessageList;
    580 			while (gadg) {
    581 				gadg->Y = y;
    582 				gadg = gadg->Get_Next();
    583 				y += Height;
    584 			}
    585 		}
    586 	}
    587 
    588 	return(changed);
    589 }
    590 
    591 
    592 /***************************************************************************
    593  * MessageListClass::Input -- Handles input for sending messages           *
    594  *                                                                         *
    595  * INPUT:                                                                  *
    596  *      input         key value to process                                 *
    597  *                                                                         *
    598  * OUTPUT:                                                                 *
    599  *      1 = caller should redraw the message list (no need to complete     *
    600  *        refresh, though)                                                 *
    601  *      2 = caller should completely refresh the display.                  *
    602  *      3 = caller should send the edit message.                           *
    603  *      (sets 'input' to 0 if it processes it.)                            *
    604  *                                                                         *
    605  * WARNINGS:                                                               *
    606  *      none.                                                              *
    607  *                                                                         *
    608  * HISTORY:                                                                *
    609  *   05/05/1995 BRR : Created.                                             *
    610  *=========================================================================*/
    611 int MessageListClass::Input(KeyNumType &input)
    612 {
    613 	KeyASCIIType ascii;
    614 	int retcode = 0;
    615 
    616 	/*------------------------------------------------------------------------
    617 	Do nothing if nothing to do.
    618 	------------------------------------------------------------------------*/
    619 	if (input == KN_NONE)
    620 		return(0);
    621 
    622 	/*------------------------------------------------------------------------
    623 	Leave mouse events alone.
    624 	------------------------------------------------------------------------*/
    625 	if ( (input & (~KN_RLSE_BIT))==KN_LMOUSE ||
    626 		(input & (~KN_RLSE_BIT))==KN_RMOUSE)
    627 		return(0);
    628 
    629 	/*------------------------------------------------------------------------
    630 	If we're in 'edit mode', handle keys
    631 	------------------------------------------------------------------------*/
    632 	if (EditLabel) {
    633 		ascii = (KeyASCIIType)(Keyboard::To_ASCII(input) & 0x00ff);
    634 
    635 		/*
    636 		** Allow numeric keypad presses to map to ascii numbers
    637 		*/
    638 		if ((input & WWKEY_VK_BIT) && ascii >='0' && ascii <= '9') {
    639 
    640 			input = (KeyNumType)(input & ~WWKEY_VK_BIT);
    641 
    642 		} else {
    643 			/*
    644 			** Filter out all special keys except return, escape and backspace
    645 			*/
    646 			if ((!(input & WWKEY_VK_BIT) && !(input & KN_BUTTON)
    647 					&& ascii >= ' ' && ascii <= 127)
    648 				|| (input & 0xff)== (KN_RETURN & 0xff)
    649 				|| (input & 0xff)== (KN_BACKSPACE & 0xff)
    650 				|| (input & 0xff)== (KN_ESC & 0xff) ) {
    651 
    652 				//ascii = (KeyASCIIType)(Keyboard->To_ASCII(input));
    653 			} else {
    654 				input = KN_NONE;
    655 				return (0);
    656 			}
    657 		}
    658 
    659 
    660 		switch (ascii) {
    661 			/*------------------------------------------------------------------
    662 			ESC = abort message
    663 			------------------------------------------------------------------*/
    664 			case KA_ESC & 0xff:
    665 				EditLabel->UserData = 1;		// force it to be removed
    666 				input = KN_NONE;
    667 				break;
    668 
    669 			/*------------------------------------------------------------------
    670 			RETURN = send the message
    671 			------------------------------------------------------------------*/
    672 			case KA_RETURN & 0xff:
    673 				EditLabel->UserData = 1;		// force it to be removed
    674 				retcode = 3;
    675 				input = KN_NONE;
    676 				break;
    677 
    678 			/*------------------------------------------------------------------
    679 			BACKSPACE = remove a character
    680 			------------------------------------------------------------------*/
    681 			case KA_BACKSPACE & 0xff:
    682 				if (EditCurPos > EditInitPos) {
    683 					EditCurPos--;
    684 					EditBuf[EditCurPos] = 0;
    685 					retcode = 2;
    686 				}
    687 				input = KN_NONE;
    688 				break;
    689 
    690 			/*------------------------------------------------------------------
    691 			default: add a character.  Reserve the last buffer position for null.
    692 			(EditCurPos - EditInitPos) is the buffer index # of the next
    693 			character, after the "To:" prefix.
    694 			------------------------------------------------------------------*/
    695 			default:
    696 				if ( (EditCurPos - EditInitPos) < (MaxChars - 1) ) {
    697 					if (!(input & WWKEY_VK_BIT) && ascii >= ' ' && ascii <= 127) {
    698 						EditBuf[EditCurPos] = ascii;
    699 						EditCurPos++;
    700 						retcode = 1;
    701 
    702 						/*
    703 						** Verify that the additional character would not overrun the on screen edit box.
    704 						*/
    705 						Fancy_Text_Print(TXT_NONE, 0, 0, EditLabel->Color, TBLACK, EditLabel->Style);
    706 						int width = String_Pixel_Width(EditBuf);
    707 						if (width >= Width){
    708 							EditBuf[EditCurPos--] = 0;
    709 							retcode = 0;
    710 						}
    711 
    712 					}
    713 				}
    714 				input = KN_NONE;
    715 				break;
    716 		}
    717 	}
    718 
    719 	return(retcode);
    720 }
    721 
    722 
    723 /***************************************************************************
    724  * MessageListClass::Draw -- draws messages                                *
    725  *                                                                         *
    726  * INPUT:                                                                  *
    727  *      none                                                               *
    728  *                                                                         *
    729  * OUTPUT:                                                                 *
    730  *      none.                                                              *
    731  *                                                                         *
    732  * WARNINGS:                                                               *
    733  *      none.                                                              *
    734  *                                                                         *
    735  * HISTORY:                                                                *
    736  *   05/22/1995 BRR : Created.                                             *
    737  *=========================================================================*/
    738 void MessageListClass::Draw(void)
    739 {
    740 	if (MessageList) {
    741 		Hide_Mouse();
    742 		MessageList->Draw_All();
    743 		Show_Mouse();
    744 	}
    745 }
    746 
    747 
    748 /***************************************************************************
    749  * MessageListClass::Num_Messages -- returns # messages in the list        *
    750  *                                                                         *
    751  * INPUT:                                                                  *
    752  *      none.                                                              *
    753  *                                                                         *
    754  * OUTPUT:                                                                 *
    755  *      # of messages                                                      *
    756  *                                                                         *
    757  * WARNINGS:                                                               *
    758  *      none.                                                              *
    759  *                                                                         *
    760  * HISTORY:                                                                *
    761  *   06/26/1995 BRR : Created.                                             *
    762  *=========================================================================*/
    763 int MessageListClass::Num_Messages(void)
    764 {
    765 	GadgetClass *gadg;
    766 	int num;
    767 
    768 	num = 0;
    769 
    770 	if (MessageList) {
    771 		gadg = MessageList;
    772 		while (gadg) {
    773 			num++;
    774 			gadg = gadg->Get_Next();
    775 		}
    776 	}
    777 
    778 	return (num);
    779 }
    780 
    781 
    782 /***************************************************************************
    783  * MessageListClass::Set_Width -- sets allowable width of messages         *
    784  *                                                                         *
    785  * INPUT:                                                                  *
    786  *      width      pixel width                                             *
    787  *                                                                         *
    788  * OUTPUT:                                                                 *
    789  *      none.                                                              *
    790  *                                                                         *
    791  * WARNINGS:                                                               *
    792  *      none.                                                              *
    793  *                                                                         *
    794  * HISTORY:                                                                *
    795  *   06/26/1995 BRR : Created.                                             *
    796  *=========================================================================*/
    797 void MessageListClass::Set_Width(int width)
    798 {
    799 	GadgetClass *gadg;
    800 
    801 	if (MessageList) {
    802 		gadg = MessageList;
    803 		while (gadg) {
    804 			((TextLabelClass *)gadg)->PixWidth = width;
    805 			gadg = gadg->Get_Next();
    806 		}
    807 	}
    808 }
    809