CnC_Remastered_Collection

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

MSGLIST.CPP (57797B)


      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: /CounterStrike/MSGLIST.CPP 2     3/04/97 2:52p Joe_bostic $ */
     17 /***************************************************************************
     18  ***              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               ***
     19  *                                                                         *
     20  *                 Project Name : Command & Conquer                        *
     21  *                                                                         *
     22  *                    File Name : MSGLIST.CPP                              *
     23  *                                                                         *
     24  *                   Programmer : Bill R. Randolph                         *
     25  *                                                                         *
     26  *                   Start Date : 05/22/95                                 *
     27  *                                                                         *
     28  *                  Last Update : March 4, 1997 [JLB]                      *
     29  *                                                                         *
     30  *-------------------------------------------------------------------------*
     31  * Functions:                                                              *
     32  *   MessageListClass::MessageListClass -- constructor                     *
     33  *   MessageListClass::~MessageListClass -- destructor                     *
     34  *   MessageListClass::Init -- Inits message system, sets options          *
     35  *   MessageListClass::Add_Message -- displays the given message           *
     36  *   MessageListClass::Get_Message -- retrieves given message              *
     37  *   MessageListClass::Get_Label -- retrieves given text label					*
     38  *   MessageListClass::Concat_Message -- concats the given message         *
     39  *   MessageListClass::Add_Edit -- Adds editable string to message list    *
     40  *   MessageListClass::Remove_Edit -- removes the edit field               *
     41  *   MessageListClass::Get_Edit_Buf -- gets edit buffer                    *
     42  *   MessageListClass::Set_Edit_Color -- sets color of edit gizmo          *
     43  *   MessageListClass::Manage -- Manages multiplayer messages              *
     44  *   MessageListClass::Input -- Handles input for sending messages         *
     45  *   MessageListClass::Draw -- Draws the messages                          *
     46  *   MessageListClass::Num_Messages -- returns # messages in the list      *
     47  *   MessageListClass::Set_Width -- sets allowable width of messages       *
     48  *   MessageListClass::Trim_Message -- trims chars off start of message    *
     49  *   MessageListClass::Compute_Y -- recomputes y-coord for all messages    *
     50  *   MessageListClass::Reset -- Reset so no messages are visible.          * 
     51  * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
     52 
     53 #include "function.h"
     54 
     55 
     56 /**************************** Globals **************************************/
     57 
     58 
     59 /***************************************************************************
     60  * MessageListClass::MessageListClass -- constructor                       *
     61  *                                                                         *
     62  * INPUT:                                                                  *
     63  *    x,y			coord of upper-left of top message                    	*
     64  *    max_msg		max messages allowed, including edit message          	*
     65  *                                                                         *
     66  * OUTPUT:                                                                 *
     67  *    none.                                                              	*
     68  *                                                                         *
     69  * WARNINGS:                                                               *
     70  *    none.                                                              	*
     71  *                                                                         *
     72  * HISTORY:                                                                *
     73  *   05/21/1995 BRR : Created.                                             *
     74  *=========================================================================*/
     75 MessageListClass::MessageListClass(void)
     76 {
     77 	int i;
     78 
     79 	//------------------------------------------------------------------------
     80 	// Init all data members
     81 	//------------------------------------------------------------------------
     82 	MessageList = 0;
     83 	MessageX = 0;
     84 	MessageY = 0;
     85 	MaxMessages = 0;
     86 	MaxChars = 0;
     87 	Height = 0;
     88 
     89 	EnableOverflow = 0;
     90 	AdjustEdit = 0;
     91 	IsEdit = 0;
     92 	EditX = 0;
     93 	EditY = 0;
     94 	EditLabel = 0;
     95 	EditBuf[0] = 0;
     96 	OverflowBuf[0] = 0;
     97 	EditCurPos = 0;
     98 	EditInitPos = 0;
     99 	CursorChar = 0;
    100 	OverflowStart = 0;
    101 	OverflowEnd = 0;
    102 
    103 	for (i = 0; i < MAX_NUM_MESSAGES; i++) {
    104 		BufferAvail[i] = 1;
    105 	}
    106 
    107 }	// end of MessageListClass
    108 
    109 
    110 /***************************************************************************
    111  * MessageListClass::~MessageListClass -- destructor                       *
    112  *                                                                         *
    113  * INPUT:                                                                  *
    114  *    x,y			coord of upper-left of top message                     	*
    115  *    max_msg		max messages allowed, including edit message          	*
    116  *                                                                         *
    117  * OUTPUT:                                                                 *
    118  *    none.                                                              	*
    119  *                                                                         *
    120  * WARNINGS:                                                               *
    121  *    none.                                                              	*
    122  *                                                                         *
    123  * HISTORY:                                                                *
    124  *   05/21/1995 BRR : Created.                                             *
    125  *=========================================================================*/
    126 MessageListClass::~MessageListClass()
    127 {
    128 	Init(0,0,0,0,0,0,0,0,0,0);
    129 
    130 }	// end of ~MessageListClass
    131 
    132 
    133 /***************************************************************************
    134  * MessageListClass::Init -- Inits message system, sets options            *
    135  *                                                                         *
    136  * INPUT:                                                                  *
    137  *    x,y				coord of upper-left of top message                    *
    138  *    max_msg			max messages allowed, NOT including edit message      *
    139  *    maxchars			max # characters allowed per message                	*
    140  *		height			pixel height of a line of text								*
    141  *		edit_x			x-coord of edit field; -1 = put at the top of the		*
    142  *							other messages														*
    143  *		edit_y			y-coord of edit field; -1 = put at the top of the		*
    144  *							other messages														*
    145  *		overflow_on		true = enable the overflow typing feature					*
    146  *		over_start		start index for overflow processing							*
    147  *		over_end			end index for overflow processing							*
    148  *     width          pixel width of message buffer                         *
    149  *                                                                         *
    150  * OUTPUT:                                                                 *
    151  *    none.                                                              	*
    152  *                                                                         *
    153  * WARNINGS:                                                               *
    154  *    none.                                                              	*
    155  *                                                                         *
    156  * HISTORY:                                                                *
    157  *   05/21/1995 BRR : Created.                                             *
    158  *=========================================================================*/
    159 void MessageListClass::Init(int x, int y, int max_msg, int maxchars,
    160 	int height, int edit_x, int edit_y, int overflow_on, int over_start,
    161 	int over_end, int width)
    162 {
    163 	TextLabelClass * txtlabel;
    164 	int i;
    165 
    166 	Width = width;
    167 
    168 	//------------------------------------------------------------------------
    169 	//	Remove every entry in the list
    170 	//------------------------------------------------------------------------
    171 	txtlabel = MessageList;
    172 	while (txtlabel) {
    173 		MessageList = (TextLabelClass *)txtlabel->Remove();
    174 		delete txtlabel;
    175 		txtlabel = MessageList;
    176 	}
    177 
    178 	//------------------------------------------------------------------------
    179 	//	Mark all buffers as available
    180 	//------------------------------------------------------------------------
    181 	for (i = 0; i < MAX_NUM_MESSAGES; i++) {
    182 		BufferAvail[i] = 1;
    183 	}
    184 
    185 	//------------------------------------------------------------------------
    186 	//	Remove the editable message
    187 	//------------------------------------------------------------------------
    188 	if (IsEdit) {
    189 		delete EditLabel;
    190 		EditLabel = 0;
    191 	}
    192 
    193 	//------------------------------------------------------------------------
    194 	//	Init variables
    195 	//------------------------------------------------------------------------
    196 	MessageList = 0;
    197 	MessageX = x;
    198 	MessageY = y;
    199 
    200 	MaxMessages = max_msg;
    201 	if (MaxMessages > MAX_NUM_MESSAGES)
    202 		MaxMessages = MAX_NUM_MESSAGES;
    203 
    204 	MaxChars = maxchars;
    205 	if (MaxChars > MAX_MESSAGE_LENGTH)
    206 		MaxChars = MAX_MESSAGE_LENGTH;
    207 
    208 	Height = height;
    209 
    210 	//------------------------------------------------------------------------
    211 	// Init the edit field variables.  If edit_x or edit_y is -1, place the
    212 	// edit field above the other messages; otherwise, place it at the desired
    213 	// coords.
    214 	//------------------------------------------------------------------------
    215 	EnableOverflow = overflow_on;
    216 	IsEdit = 0;
    217 	if (edit_x == -1 || edit_y == -1) {
    218 		AdjustEdit = 1;
    219 		EditX = x;
    220 		EditY = y;
    221 	}
    222 	else {
    223 		AdjustEdit = 0;
    224 		EditX = edit_x;
    225 		EditY = edit_y;
    226 	}
    227 	EditLabel = 0;
    228 	EditBuf[0] = 0;
    229 	OverflowBuf[0] = 0;
    230 	EditCurPos = 0;
    231 	EditInitPos = 0;
    232 	CursorChar = 0;
    233 
    234 	//------------------------------------------------------------------------
    235 	// Init the overflow processing indices
    236 	//------------------------------------------------------------------------
    237 	OverflowStart = over_start;
    238 	OverflowEnd = over_end;
    239 	if (OverflowEnd >= MaxChars) {
    240 		OverflowEnd = MaxChars - 1;
    241 	}
    242 	if (OverflowStart >= OverflowEnd) {
    243 		OverflowStart = OverflowEnd - 1;
    244 	}
    245 
    246 }	// end of Init
    247 
    248 
    249 /*********************************************************************************************** 
    250  * MessageListClass::Reset -- Reset so no messages are visible.                                * 
    251  *                                                                                             * 
    252  *    This routine will reset the message list tracker so that any displayed messages are      * 
    253  *    cleared.                                                                                 * 
    254  *                                                                                             * 
    255  * INPUT:   none                                                                               * 
    256  *                                                                                             * 
    257  * OUTPUT:  none                                                                               * 
    258  *                                                                                             * 
    259  * WARNINGS:   none                                                                            * 
    260  *                                                                                             * 
    261  * HISTORY:                                                                                    * 
    262  *   03/04/1997 JLB : Created.                                                                 * 
    263  *=============================================================================================*/
    264 void MessageListClass::Reset(void)
    265 {
    266 	//------------------------------------------------------------------------
    267 	//	Remove every entry in the list
    268 	//------------------------------------------------------------------------
    269 	TextLabelClass * txtlabel = MessageList;
    270 	while (txtlabel) {
    271 		MessageList = (TextLabelClass *)txtlabel->Remove();
    272 		delete txtlabel;
    273 		txtlabel = MessageList;
    274 	}
    275 
    276 	//------------------------------------------------------------------------
    277 	//	Mark all buffers as available
    278 	//------------------------------------------------------------------------
    279 	for (int index = 0; index < MAX_NUM_MESSAGES; index++) {
    280 		BufferAvail[index] = 1;
    281 	}
    282 
    283 	//------------------------------------------------------------------------
    284 	//	Remove the editable message
    285 	//------------------------------------------------------------------------
    286 	if (IsEdit) {
    287 		delete EditLabel;
    288 		EditLabel = 0;
    289 	}
    290 
    291 	//------------------------------------------------------------------------
    292 	//	Init variables
    293 	//------------------------------------------------------------------------
    294 	MessageList = 0;
    295 	EditLabel = 0;
    296 	IsEdit = 0;
    297 }
    298 
    299 extern void On_Message(const char* message, float timeout_seconds, long long message_id);
    300 
    301 /***************************************************************************
    302  * MessageListClass::Add_Message -- displays the given message             *
    303  *                                                                         *
    304  * INPUT:                                                                  *
    305  *		name			name of sender, NULL = none										*
    306  *		id				numerical ID for this message										*
    307  *    txt         text to display                                        	*
    308  *    color       color to draw text in                                		*
    309  *    style       style to use                                         		*
    310  *    timeout     # of ticks the thing is supposed to last (-1 = forever)	*
    311  *                                                                         *
    312  * OUTPUT:                                                                 *
    313  *    ptr to new TextLabelClass object.                                  	*
    314  *                                                                         *
    315  * WARNINGS:                                                               *
    316  *		none.																						*
    317  *                                                                         *
    318  * HISTORY:                                                                *
    319  *   05/05/1995 BRR : Created.                                             *
    320  *   10/16/1996 JLB : Audio feedback added.                                *
    321  *=========================================================================*/
    322 TextLabelClass * MessageListClass::Add_Message(char const * name, int id, char const * txt,
    323 	PlayerColorType color, TextPrintType style, int timeout)
    324 {
    325 	TextLabelClass * txtlabel = NULL;
    326 	char message[MAX_MESSAGE_LENGTH + 30];
    327 
    328 	//------------------------------------------------------------------------
    329 	// Combine the name & message text, if there's a name given
    330 	//------------------------------------------------------------------------
    331 	if (name) {
    332 		sprintf(message, "%s:%s", name, txt);
    333 		id = -1;
    334 	} else {
    335 		strcpy(message, txt);
    336 	}
    337 
    338 #if (0)
    339 
    340 	int i;
    341 	int found;
    342 	char temp[MAX_MESSAGE_LENGTH + 30];
    343 	int print_this_pass;
    344 	char save = 0;
    345 	int mess_start;
    346 
    347 	//------------------------------------------------------------------------
    348 	//	Check that printing this wont overrun the width of the print area on screen
    349 	//------------------------------------------------------------------------
    350 
    351 	print_this_pass = 0;
    352 	Fancy_Text_Print(TXT_NONE, 0, 0, &ColorRemaps[color], TBLACK, style);
    353 	int wid = String_Pixel_Width(message);
    354 	if (wid >= Width-8) {
    355 		//------------------------------------------------------------------------
    356 		//	Bugger. Its too long. Loop through and find out how many chars we can print
    357 		//------------------------------------------------------------------------
    358 		if (name) {
    359 			sprintf (temp, "%s:", name);
    360 			mess_start = strlen (name)+1;
    361 		} else {
    362 			mess_start = 0;
    363 		}
    364 		for (int i=1 ; i<(int)strlen(txt) ; i++) {
    365 			strncpy (&temp[mess_start], txt, i);
    366 			temp [mess_start + i] = 0;
    367 			wid = String_Pixel_Width(temp);
    368 			if (wid >= Width-8) {
    369 				print_this_pass = mess_start + i-1;
    370 				break;
    371 			}
    372 		}
    373 
    374 		//------------------------------------------------------------------------
    375 		//	Prematurely terminate the string so it doesn't all print.
    376 		// We will re-enter at the end to print the rest.
    377 		//------------------------------------------------------------------------
    378 		if (print_this_pass) {
    379 			save = message [print_this_pass];
    380 			message [print_this_pass] = 0;
    381 		}
    382 	}
    383 
    384 
    385 
    386 	//------------------------------------------------------------------------
    387 	//	Remove the top-most message if we're about to exceed the max allowed
    388 	//------------------------------------------------------------------------
    389 	if ( (MaxMessages > 0) && ((Num_Messages() + 1) > MaxMessages)) {
    390 		txtlabel = MessageList;
    391 
    392 		if (txtlabel==NULL)
    393 			return(NULL);
    394 
    395 		//.....................................................................
    396 		//	Remove this message from the list; mark its buffer as being available.
    397 		//.....................................................................
    398 		MessageList = (TextLabelClass *)txtlabel->Remove();
    399 		for (i = 0; i < MAX_NUM_MESSAGES; i++) {
    400 			if (txtlabel->Text == MessageBuffers[i])
    401 				BufferAvail[i] = 1;
    402 		}
    403 		delete txtlabel;
    404 	}
    405 
    406 	//------------------------------------------------------------------------
    407 	//	Create the message
    408 	//------------------------------------------------------------------------
    409 	txtlabel = new TextLabelClass (message, MessageX, MessageY,
    410 		&ColorRemaps[color], style);
    411 	if (timeout==-1) {
    412 		txtlabel->UserData1 = 0;
    413 	}
    414 	else {
    415 		txtlabel->UserData1 = TickCount + timeout;
    416 	}
    417 	txtlabel->UserData2 = id;
    418 
    419 	//------------------------------------------------------------------------
    420 	//	Find a buffer to store our message in; if there are none, don't add the
    421 	//	message.
    422 	//------------------------------------------------------------------------
    423 	found = 0;
    424 	for (i = 0; i < MAX_NUM_MESSAGES; i++) {
    425 		if (BufferAvail[i]) {
    426 			BufferAvail[i] = 0;
    427 			memset (MessageBuffers[i],0,MAX_MESSAGE_LENGTH + 30);
    428 			strcpy (MessageBuffers[i],message);
    429 			txtlabel->Text = MessageBuffers[i];
    430 			found = 1;
    431 			break;
    432 		}
    433 	}
    434 	if (!found) {
    435 		delete txtlabel;
    436 		return (NULL);
    437 	}
    438 
    439 #endif
    440 
    441 	On_Message(message, timeout * 60.0f / TICKS_PER_MINUTE, id);
    442 	//Sound_Effect(VOC_INCOMING_MESSAGE);
    443 
    444 #if (0)
    445 
    446 	//------------------------------------------------------------------------
    447 	//	Attach the message to our list
    448 	//------------------------------------------------------------------------
    449 	if (MessageList) {
    450 		txtlabel->Add_Tail (*MessageList);
    451 	}
    452 	else {
    453 		MessageList = txtlabel;
    454 	}
    455 
    456 	//------------------------------------------------------------------------
    457 	//	Recompute all messages' y-coordinate values
    458 	//------------------------------------------------------------------------
    459 	Compute_Y();
    460 
    461 	//------------------------------------------------------------------------
    462 	//	If we terminated the string before the end then we need to reenter to
    463 	// add a new message with the rest of the string.
    464 	//------------------------------------------------------------------------
    465 	if (save) {
    466 		message [print_this_pass] = save;
    467 		Add_Message (name, id, &message [print_this_pass], color, style, timeout);
    468 	}
    469 
    470 #endif
    471 
    472 	return(txtlabel);
    473 
    474 }	// end of Add_Message
    475 
    476 
    477 /***************************************************************************
    478  * MessageListClass::Get_Message -- retrieves given message                *
    479  *                                                                         *
    480  * INPUT:                                                                  *
    481  *		id			ID of message to get														*
    482  *                                                                         *
    483  * OUTPUT:                                                                 *
    484  *		ptr to message text, NULL if not found											*
    485  *                                                                         *
    486  * WARNINGS:                                                               *
    487  *		none.																						*
    488  *                                                                         *
    489  * HISTORY:                                                                *
    490  *   11/07/1995 BRR : Created.                                             *
    491  *=========================================================================*/
    492 char * MessageListClass::Get_Message(int id)
    493 {
    494 	TextLabelClass * gadg;
    495 
    496 	//------------------------------------------------------------------------
    497 	// Scan the message list, searching for the given ID
    498 	//------------------------------------------------------------------------
    499 	if (MessageList) {
    500 		gadg = MessageList;
    501 		while (gadg) {
    502 			if (gadg->UserData2 == id) {
    503 				return (gadg->Text);
    504 			}
    505 			gadg = (TextLabelClass *)gadg->Get_Next();
    506 		}
    507 	}
    508 
    509 	return (NULL);
    510 
    511 }	// end of Get_Message
    512 
    513 
    514 /***************************************************************************
    515  * MessageListClass::Get_Label -- retrieves given text label					*
    516  *                                                                         *
    517  * INPUT:                                                                  *
    518  *		id			ID of message to get														*
    519  *                                                                         *
    520  * OUTPUT:                                                                 *
    521  *		ptr to message text, NULL if not found											*
    522  *                                                                         *
    523  * WARNINGS:                                                               *
    524  *		none.																						*
    525  *                                                                         *
    526  * HISTORY:                                                                *
    527  *   11/07/1995 BRR : Created.                                             *
    528  *=========================================================================*/
    529 TextLabelClass * MessageListClass::Get_Label(int id)
    530 {
    531 	TextLabelClass * gadg;
    532 
    533 	//------------------------------------------------------------------------
    534 	// Scan the message list, searching for the given ID
    535 	//------------------------------------------------------------------------
    536 	if (MessageList) {
    537 		gadg = MessageList;
    538 		while (gadg) {
    539 			if (gadg->UserData2 == id) {
    540 				return (gadg);
    541 			}
    542 			gadg = (TextLabelClass *)gadg->Get_Next();
    543 		}
    544 	}
    545 
    546 	return (NULL);
    547 
    548 }	// end of Get_Label
    549 
    550 
    551 /***************************************************************************
    552  * MessageListClass::Concat_Message -- concats the given message           *
    553  *                                                                         *
    554  * INPUT:                                                                  *
    555  *		name			name of sender; NULL = none										*
    556  *		id				ID of message to concatenate to									*
    557  *		txt			text to concatenate onto existing message						*
    558  *		timeout		new timeout for message												*
    559  *                                                                         *
    560  * OUTPUT:                                                                 *
    561  *		1 = OK, 0 = error (id or name not found)										*
    562  *                                                                         *
    563  * WARNINGS:                                                               *
    564  *		If the required message doesn't exist, this routine does nothing.		*
    565  *                                                                         *
    566  * HISTORY:                                                                *
    567  *   11/07/1995 BRR : Created.                                             *
    568  *=========================================================================*/
    569 int MessageListClass::Concat_Message(char const * name, int id, char const * txt, int timeout)
    570 {
    571 	int min_chars;
    572 	int max_chars;
    573 	char * msg;
    574 	TextLabelClass * tlabel;
    575 	int found;
    576 
    577 	//------------------------------------------------------------------------
    578 	// If no name is given, or the concatenation feature is turned off,
    579 	// don't concatenate the message
    580 	//------------------------------------------------------------------------
    581 	if (!name || !EnableOverflow) {
    582 		return (0);
    583 	}
    584 
    585 	//------------------------------------------------------------------------
    586 	// Scan through all active messages, searching for one with a matching
    587 	// name & ID
    588 	//------------------------------------------------------------------------
    589 	found = 0;
    590 	if (MessageList) {
    591 		tlabel = MessageList;
    592 		while (tlabel) {
    593 			if (tlabel->UserData2 == id &&
    594 				!memcmp(tlabel->Text,name,strlen(name))) {
    595 				found = 1;
    596 				break;
    597 			}
    598 			tlabel = (TextLabelClass *)tlabel->Get_Next();
    599 		}
    600 	}
    601 
    602 	//------------------------------------------------------------------------
    603 	// name and ID not found; return
    604 	//------------------------------------------------------------------------
    605 	if (!found) {
    606 		return (0);
    607 	}
    608 
    609 	//------------------------------------------------------------------------
    610 	// set a pointer to the text string, plus the name and colon
    611 	//------------------------------------------------------------------------
    612 	msg = tlabel->Text + strlen(name) + 1;
    613 
    614 	//------------------------------------------------------------------------
    615 	// If there's room enough in the message, just add the given string
    616 	//------------------------------------------------------------------------
    617 	if ( (int)(strlen(msg) + strlen(txt)) < MaxChars) {
    618 
    619 		//---------------------------------------------------------------------
    620 		// We need to trim the message if there is no room to draw it
    621 		//---------------------------------------------------------------------
    622 		char *concat_test = new char [MaxChars+1];
    623 		Fancy_Text_Print(TXT_NONE, 0, 0, tlabel->Color, TBLACK, tlabel->Style);
    624 		int name_width = String_Pixel_Width(tlabel->Text) - String_Pixel_Width(msg);
    625 		int width;
    626 
    627 		strcpy (concat_test, msg);
    628 		strcat (concat_test, txt);
    629 		width = String_Pixel_Width(concat_test) + name_width;
    630 		min_chars = 10;
    631 
    632 		while (width >= Width-8){
    633 
    634 			max_chars = strlen (msg);
    635 			if (max_chars < min_chars) {
    636 				max_chars = min_chars;
    637 			}
    638 
    639 			Trim_Message (NULL, msg, min_chars, max_chars, 0);
    640 
    641 			strcpy (concat_test, msg);
    642 			strcat (concat_test, txt);
    643 
    644 			width = String_Pixel_Width(concat_test) + name_width;
    645 		};
    646 
    647 		delete [] concat_test;
    648 
    649 		strcat (msg,txt);
    650 	}
    651 
    652 	//------------------------------------------------------------------------
    653 	// Otherwise, trim off some characters from the beginning of the
    654 	// message.  Trim off at least enough to leave room for the new text.
    655 	// Trim from left to right to remove the minimum required text.
    656 	//------------------------------------------------------------------------
    657 	else {
    658 		min_chars = (strlen(msg) + strlen(txt)) - MaxChars;
    659 		max_chars = strlen(msg);
    660 		if (max_chars < min_chars) {
    661 			max_chars = min_chars;
    662 		}
    663 		Trim_Message (NULL, msg, min_chars, max_chars, 0);
    664 		strcat (msg, txt);
    665 	}
    666 
    667 	//------------------------------------------------------------------------
    668 	// Set the new timeout value for the message
    669 	//------------------------------------------------------------------------
    670 	if (timeout==-1) {
    671 		tlabel->UserData1 = 0;
    672 	}
    673 	else {
    674 		tlabel->UserData1 = TickCount + timeout;
    675 	}
    676 
    677 	return (1);
    678 
    679 }	// end of Concat_Message
    680 
    681 
    682 
    683 /***********************************************************************************************
    684  * MessageListClass::Set_Edit_Focus -- Give the gadget system focus to the edit box            *
    685  *                                                                                             *
    686  *                                                                                             *
    687  *                                                                                             *
    688  * INPUT:    Nothing                                                                           *
    689  *                                                                                             *
    690  * OUTPUT:   Nothing                                                                           *
    691  *                                                                                             *
    692  * WARNINGS: None                                                                              *
    693  *                                                                                             *
    694  * HISTORY:                                                                                    *
    695  *    10/19/96 4:41PM ST : Created                                                             *
    696  *=============================================================================================*/
    697 void MessageListClass::Set_Edit_Focus (void)
    698 {
    699 	if (IsEdit) EditLabel->Set_Focus();
    700 }
    701 
    702 
    703 /***********************************************************************************************
    704  * MessageListClass::Has_Edit_Focus -- Find out if the edit box has the input focus            *
    705  *                                                                                             *
    706  *                                                                                             *
    707  *                                                                                             *
    708  * INPUT:    Nothing                                                                           *
    709  *                                                                                             *
    710  * OUTPUT:   Nothing                                                                           *
    711  *                                                                                             *
    712  * WARNINGS: None                                                                              *
    713  *                                                                                             *
    714  * HISTORY:                                                                                    *
    715  *    10/19/96 4:41PM ST : Created                                                             *
    716  *=============================================================================================*/
    717 bool MessageListClass::Has_Edit_Focus (void)
    718 {
    719 	if (IsEdit){
    720 		return (EditLabel->Has_Focus());
    721 	}else{
    722 		return(false);
    723 	}
    724 }
    725 
    726 
    727 
    728 /***************************************************************************
    729  * MessageListClass::Add_Edit -- Adds editable string to message list      *
    730  *                                                                         *
    731  * INPUT:                                                                  *
    732  *    color			color of edit message                                		*
    733  *    style			style of edit message                                		*
    734  *    to				string: who to send to; NULL = none								*
    735  *		cursor		character to use as a cursor; 0 = none							*
    736  *                                                                         *
    737  * OUTPUT:                                                                 *
    738  *    ptr to new TextLabelClass                                          	*
    739  *                                                                         *
    740  * WARNINGS:                                                               *
    741  *    none.                                                              	*
    742  *                                                                         *
    743  * HISTORY:                                                                *
    744  *   05/22/1995 BRR : Created.                                             *
    745  *=========================================================================*/
    746 TextLabelClass * MessageListClass::Add_Edit(PlayerColorType color,
    747 	TextPrintType style, char * to, char cursor, int width)
    748 {
    749 	int i;
    750 	TextLabelClass * txtlabel;
    751 
    752 	//------------------------------------------------------------------------
    753 	//	Do nothing if we're already in "edit" mode
    754 	//------------------------------------------------------------------------
    755 	if (IsEdit) {
    756 		EditLabel->Set_Focus();
    757 		return(NULL);
    758 	}
    759 
    760 	//------------------------------------------------------------------------
    761 	//	Remove the top-most message if we're about to exceed the max allowed
    762 	//------------------------------------------------------------------------
    763 	if (AdjustEdit && ((Num_Messages() + 1) > MaxMessages)) {
    764 		txtlabel = MessageList;
    765 		MessageList = (TextLabelClass *)txtlabel->Remove();
    766 		for (i = 0; i < MAX_NUM_MESSAGES; i++) {
    767 			if (txtlabel->Text == MessageBuffers[i])
    768 				BufferAvail[i] = 1;
    769 		}
    770 		delete txtlabel;
    771 	}
    772 
    773 	//------------------------------------------------------------------------
    774 	// If no 'to' field was passed in, ignore it
    775 	//------------------------------------------------------------------------
    776 	if (!to) {
    777 		to = "";
    778 	}
    779 
    780 	//------------------------------------------------------------------------
    781 	// Set the cursor character
    782 	//------------------------------------------------------------------------
    783 	CursorChar = cursor;
    784 
    785 	//------------------------------------------------------------------------
    786 	//	Initialize the buffer positions; create a new text label object
    787 	//------------------------------------------------------------------------
    788 	memset (EditBuf, 0, sizeof(EditBuf));
    789 	strcpy (EditBuf, to);
    790 	OverflowBuf[0] = 0;
    791 	EditCurPos = EditInitPos = strlen(to);
    792 	EditLabel = new TextLabelClass (EditBuf, EditX, EditY,
    793 		&ColorRemaps[color], style);
    794 
    795 	Width = width;
    796 
    797 	if (EditLabel) {
    798 		IsEdit = 1;
    799 		EditLabel->Set_Focus();
    800 	}
    801 	else {
    802 		IsEdit = 0;
    803 	}
    804 
    805 	//------------------------------------------------------------------------
    806 	// If the edit field appears over the message list, recompute the y-value
    807 	// for all messages.  Also, adjust MaxMessages down by one, since there
    808 	// is now one less slot available.
    809 	//------------------------------------------------------------------------
    810 	if (AdjustEdit) {
    811 		Compute_Y();
    812 		MaxMessages--;
    813 	}
    814 
    815 	return(EditLabel);
    816 
    817 }	// end of Add_Edit
    818 
    819 
    820 /***************************************************************************
    821  * MessageListClass::Remove_Edit -- removes the edit field                 *
    822  *                                                                         *
    823  * INPUT:                                                                  *
    824  *		none.																						*
    825  *                                                                         *
    826  * OUTPUT:                                                                 *
    827  *		none.																						*
    828  *                                                                         *
    829  * WARNINGS:                                                               *
    830  *		none.																						*
    831  *                                                                         *
    832  * HISTORY:                                                                *
    833  *   11/06/1995 BRR : Created.                                             *
    834  *=========================================================================*/
    835 void MessageListClass::Remove_Edit(void)
    836 {
    837 	//------------------------------------------------------------------------
    838 	// If the edit field is active, delete it
    839 	//------------------------------------------------------------------------
    840 	if (IsEdit) {
    841 		IsEdit = 0;
    842 		delete EditLabel;
    843 
    844 		//.....................................................................
    845 		// If the edit field appears over the message list, recompute the
    846 		// y-value for all messages.  Adjust MaxMessages back up, since there
    847 		// is now a new available slot.
    848 		//.....................................................................
    849 		if (AdjustEdit) {
    850 			Compute_Y();
    851 			MaxMessages++;
    852 		}
    853 	}
    854 
    855 }	// end if Remove_Edit
    856 
    857 
    858 /***************************************************************************
    859  * MessageListClass::Get_Edit_Buf -- gets edit buffer                      *
    860  *                                                                         *
    861  * INPUT:                                                                  *
    862  *    none.                                                              	*
    863  *                                                                         *
    864  * OUTPUT:                                                                 *
    865  *    ptr to edit buffer, minus the "To:" header                         	*
    866  *                                                                         *
    867  * WARNINGS:                                                               *
    868  *    none.                                                              	*
    869  *                                                                         *
    870  * HISTORY:                                                                *
    871  *   05/21/1995 BRR : Created.                                             *
    872  *=========================================================================*/
    873 char * MessageListClass::Get_Edit_Buf(void)
    874 {
    875 	return(EditBuf + EditInitPos);
    876 
    877 }	// end of Get_Edit_Buf
    878 
    879 
    880 /***************************************************************************
    881  * MessageListClass::Set_Edit_Color -- sets color of edit gizmo            *
    882  *                                                                         *
    883  * INPUT:                                                                  *
    884  *		color		color to set edit label to												*
    885  *                                                                         *
    886  * OUTPUT:                                                                 *
    887  *		none.																						*
    888  *                                                                         *
    889  * WARNINGS:                                                               *
    890  *		none.																						*
    891  *                                                                         *
    892  * HISTORY:                                                                *
    893  *   12/08/1995 BRR : Created.                                             *
    894  *=========================================================================*/
    895 void MessageListClass::Set_Edit_Color(PlayerColorType color)
    896 {
    897 	if (IsEdit) {
    898 		EditLabel->Color = &ColorRemaps[color];
    899 	}
    900 
    901 }	// end of Set_Edit_Color
    902 
    903 
    904 /***************************************************************************
    905  * MessageListClass::Manage -- Manages multiplayer messages                *
    906  *                                                                         *
    907  * If this routine returns TRUE, the caller should update the display.     *
    908  *                                                                         *
    909  * INPUT:                                                                  *
    910  *    none.                                                              	*
    911  *                                                                         *
    912  * OUTPUT:                                                                 *
    913  *    none.                                                              	*
    914  *                                                                         *
    915  * WARNINGS:                                                               *
    916  *    0 = no change has occurred, 1 = changed                            	*
    917  *                                                                         *
    918  * HISTORY:                                                                *
    919  *   05/05/1995 BRR : Created.                                             *
    920  *=========================================================================*/
    921 int MessageListClass::Manage (void)
    922 {
    923 	TextLabelClass * txtlabel;
    924 	TextLabelClass * next;
    925 	int changed = 0;
    926 	int i;
    927 
    928 	//------------------------------------------------------------------------
    929 	//	Loop through all messages
    930 	//------------------------------------------------------------------------
    931 	txtlabel = MessageList;
    932 	while (txtlabel) {
    933 
    934 		//.....................................................................
    935 		//	If this message's time is up, remove it from the list
    936 		//.....................................................................
    937 		if (txtlabel->UserData1 != 0 && TickCount > txtlabel->UserData1) {
    938 
    939 			//..................................................................
    940 			//	Save the next ptr in the list; remove this entry
    941 			//..................................................................
    942 			next = (TextLabelClass *)txtlabel->Get_Next();
    943 			MessageList = (TextLabelClass *)txtlabel->Remove();
    944 			for (i = 0; i < MAX_NUM_MESSAGES; i++) {
    945 				if (txtlabel->Text == MessageBuffers[i]) {
    946 					BufferAvail[i] = 1;
    947 				}
    948 			}
    949 			delete txtlabel;
    950 			changed = 1;
    951 			txtlabel = next;
    952 		}
    953 		else {
    954 			txtlabel = (TextLabelClass *)txtlabel->Get_Next();
    955 		}
    956 	}
    957 
    958 	//------------------------------------------------------------------------
    959 	//	If a changed has been made, recompute the y-coord of all messages
    960 	//------------------------------------------------------------------------
    961 	if (changed) {
    962 		Compute_Y();
    963 	}
    964 
    965 	return(changed);
    966 
    967 }	// end of Manage
    968 
    969 
    970 /***************************************************************************
    971  * MessageListClass::Input -- Handles input for sending messages           *
    972  *                                                                         *
    973  * INPUT:                                                                  *
    974  *    input         key value to process                                 	*
    975  *                                                                         *
    976  * OUTPUT:                                                                 *
    977  *    1 = caller should redraw the message list (no need to complete     	*
    978  *        refresh, though)                                                 *
    979  *    2 = caller should completely refresh the display.                  	*
    980  *    3 = caller should send the edit message.                           	*
    981  *        (sets 'input' to 0 if it processes it.)                          *
    982  *		4 = caller should send the Overflow buffer									*
    983  *                                                                         *
    984  * WARNINGS:                                                               *
    985  *    none.                                                              	*
    986  *                                                                         *
    987  * HISTORY:                                                                *
    988  *   05/05/1995 BRR : Created.                                             *
    989  *=========================================================================*/
    990 int MessageListClass::Input(KeyNumType &input)
    991 {
    992 	KeyASCIIType ascii;
    993 	int retcode = 0;
    994 	int numchars;
    995 
    996 	//------------------------------------------------------------------------
    997 	//	Do nothing if nothing to do.
    998 	//------------------------------------------------------------------------
    999 	if (input == KN_NONE) {
   1000 		return(0);
   1001 	}
   1002 
   1003 	//------------------------------------------------------------------------
   1004 	//	Leave mouse events alone.
   1005 	//------------------------------------------------------------------------
   1006 	if ( (input & (~KN_RLSE_BIT))==KN_LMOUSE ||
   1007 		(input & (~KN_RLSE_BIT))==KN_RMOUSE) {
   1008 		return(0);
   1009 	}
   1010 
   1011 	//------------------------------------------------------------------------
   1012 	//	If we're in 'edit mode', handle keys
   1013 	//------------------------------------------------------------------------
   1014 	if (IsEdit) {
   1015 
   1016 
   1017 		ascii = (KeyASCIIType)(Keyboard->To_ASCII(input) & 0x00ff);
   1018 
   1019 #ifdef WIN32
   1020 		/*
   1021 		** Allow numeric keypad presses to map to ascii numbers
   1022 		*/
   1023 		if ((input & WWKEY_VK_BIT) && ascii >='0' && ascii <= '9') {
   1024 
   1025 			input = (KeyNumType)(input & ~WWKEY_VK_BIT);
   1026 
   1027 		} else {
   1028 			/*
   1029 			** Filter out all special keys except return, escape and backspace
   1030 			*/
   1031 			if ((!(input & WWKEY_VK_BIT) && !(input & KN_BUTTON)
   1032 					&& ascii >= ' ' && ascii <= 127)
   1033 				|| (input & 0xff)== (KN_RETURN & 0xff)
   1034 				|| (input & 0xff)== (KN_BACKSPACE & 0xff)
   1035 				|| (input & 0xff)== (KN_ESC & 0xff) ) {
   1036 
   1037 				//ascii = (KeyASCIIType)(Keyboard->To_ASCII(input));
   1038 			} else {
   1039 				input = KN_NONE;
   1040 				return (0);
   1041 			}
   1042 		}
   1043 #endif	//WIN32
   1044 
   1045 
   1046 
   1047 		switch (ascii) {
   1048 			//..................................................................
   1049 			//	ESC = abort message
   1050 			//..................................................................
   1051 			case KA_ESC & 0xff:
   1052 				Remove_Edit();
   1053 				retcode = 2;
   1054 				input = KN_NONE;
   1055 				break;
   1056 
   1057 			//..................................................................
   1058 			//	RETURN = send the message.
   1059 			// Add a space to the end, in case another message gets concatenated
   1060 			// onto this one after we send it; then, they won't be mushed
   1061 			// together.
   1062 			//..................................................................
   1063 			case KA_RETURN & 0xff:
   1064 				if (EditCurPos == EditInitPos) {
   1065 					retcode = 0;
   1066 					input = KN_NONE;
   1067 					break;
   1068 				}
   1069 				if ( (EditCurPos - EditInitPos) < (MaxChars - 1) ) {
   1070 					EditBuf[EditCurPos] = ' ';
   1071 					EditCurPos++;
   1072 					EditBuf[EditCurPos] = 0;
   1073 				}
   1074 				Remove_Edit();
   1075 				retcode = 3;
   1076 				input = KN_NONE;
   1077 				break;
   1078 
   1079 			//..................................................................
   1080 			//	BACKSPACE = remove a character
   1081 			//..................................................................
   1082 			case KA_BACKSPACE & 0xff:
   1083 				if (EditCurPos > EditInitPos) {
   1084 					EditCurPos--;
   1085 					EditBuf[EditCurPos] = 0;
   1086 					retcode = 2;
   1087 				}
   1088 				input = KN_NONE;
   1089 				EditLabel->Set_Focus();
   1090 				break;
   1091 
   1092 			//..................................................................
   1093 			// default: add a character.  Reserve the last buffer position for
   1094 			// null.  (EditCurPos - EditInitPos) is the buffer index # of the
   1095 			// next character, after the "To:" prefix.
   1096 			//..................................................................
   1097 			default:
   1098 				EditLabel->Set_Focus();
   1099 				bool overflowed = false;
   1100 				if (ascii >= ' ' && ascii <= 127) {
   1101 					if ( (EditCurPos - EditInitPos) < (MaxChars - 1) ) {
   1102 
   1103 						EditBuf[EditCurPos] = ascii;
   1104 						EditCurPos++;
   1105 						EditBuf[EditCurPos] = 0;
   1106 						retcode = 1;
   1107 
   1108 						/*
   1109 						** Verify that the additional character would not overrun the on screen edit box.
   1110 						*/
   1111 						Fancy_Text_Print(TXT_NONE, 0, 0, EditLabel->Color, TBLACK, EditLabel->Style);
   1112 						int width = String_Pixel_Width(EditBuf);
   1113 						if (width >= Width-10) {
   1114 							overflowed = true;
   1115 							EditCurPos--;
   1116 							EditBuf[EditCurPos] = 0;
   1117 							retcode = 0;
   1118 						}
   1119 					} else {
   1120 					//............................................................
   1121 					// If there's no room in the buffer, and overflow is enabled,
   1122 					// trim the extra characters off (from right to left, to
   1123 					// remove the max possible characters), and then add the new
   1124 					// character in.
   1125 					//............................................................
   1126 						overflowed = true;
   1127 					}
   1128 
   1129 					if (/*BGEnableOverflow &&*/ overflowed) {
   1130 						numchars = Trim_Message (OverflowBuf, EditBuf + EditInitPos,
   1131 							OverflowStart,OverflowEnd, 1);
   1132 						EditCurPos -= numchars;
   1133 						EditBuf[EditCurPos] = ascii;
   1134 						EditCurPos++;
   1135 						EditBuf[EditCurPos] = 0;
   1136 						retcode = 4;
   1137 					}
   1138 				}
   1139 				input = KN_NONE;
   1140 				break;
   1141 		}
   1142 	}
   1143 
   1144 	return(retcode);
   1145 
   1146 }	// end of Input
   1147 
   1148 
   1149 /***************************************************************************
   1150  * MessageListClass::Draw -- draws messages                                *
   1151  *                                                                         *
   1152  * INPUT:                                                                  *
   1153  *    none                                                               	*
   1154  *                                                                         *
   1155  * OUTPUT:                                                                 *
   1156  *    none.                                                              	*
   1157  *                                                                         *
   1158  * WARNINGS:                                                               *
   1159  *    none.                                                              	*
   1160  *                                                                         *
   1161  * HISTORY:                                                                *
   1162  *   05/22/1995 BRR : Created.                                             *
   1163  *=========================================================================*/
   1164 void MessageListClass::Draw(void)
   1165 {
   1166 	char txt[2] = {0,0};
   1167 
   1168 	if (IsEdit) {
   1169 		if (LogicPage == &SeenBuff) {
   1170 			Hide_Mouse();
   1171 		}
   1172 		EditLabel->Draw_Me(true);
   1173 
   1174 		if (CursorChar && (EditCurPos - EditInitPos) < (MaxChars - 1) && EditLabel->Has_Focus()) {
   1175 			txt[0] = CursorChar;
   1176 			Fancy_Text_Print(txt,
   1177 				EditLabel->X + String_Pixel_Width(EditLabel->Text),
   1178 				EditLabel->Y,
   1179 				EditLabel->Color,
   1180 				TBLACK,
   1181 				EditLabel->Style);
   1182 		}
   1183 
   1184 		if (LogicPage == &SeenBuff) {
   1185 			Show_Mouse();
   1186 		}
   1187 	}
   1188 	if (MessageList) {
   1189 		if (LogicPage == &SeenBuff) {
   1190 			Hide_Mouse();
   1191 		}
   1192 		MessageList->Draw_All();
   1193 		if (LogicPage == &SeenBuff) {
   1194 			Show_Mouse();
   1195 		}
   1196 	}
   1197 
   1198 }	// end of Draw
   1199 
   1200 
   1201 /***************************************************************************
   1202  * MessageListClass::Num_Messages -- returns # messages in the list        *
   1203  *                                                                         *
   1204  * INPUT:                                                                  *
   1205  *    none.                                                              	*
   1206  *                                                                         *
   1207  * OUTPUT:                                                                 *
   1208  *    # of messages, including the edit field if it's above the messages	*
   1209  *                                                                         *
   1210  * WARNINGS:                                                               *
   1211  *    none.                                                              	*
   1212  *                                                                         *
   1213  * HISTORY:                                                                *
   1214  *   06/26/1995 BRR : Created.                                             *
   1215  *=========================================================================*/
   1216 int MessageListClass::Num_Messages(void)
   1217 {
   1218 	GadgetClass * gadg;
   1219 	int num;
   1220 
   1221 	num = 0;
   1222 
   1223 	if (MessageList) {
   1224 		gadg = MessageList;
   1225 		while (gadg) {
   1226 			num++;
   1227 			gadg = gadg->Get_Next();
   1228 		}
   1229 	}
   1230 
   1231 	if (IsEdit && AdjustEdit) {
   1232 		num++;
   1233 	}
   1234 
   1235 	return (num);
   1236 
   1237 }	// end of Num_Messages
   1238 
   1239 
   1240 /***************************************************************************
   1241  * MessageListClass::Set_Width -- sets allowable width of messages         *
   1242  *                                                                         *
   1243  * INPUT:                                                                  *
   1244  *    width      pixel width                                             	*
   1245  *                                                                         *
   1246  * OUTPUT:                                                                 *
   1247  *    none.                                                              	*
   1248  *                                                                         *
   1249  * WARNINGS:                                                               *
   1250  *    none.                                                              	*
   1251  *                                                                         *
   1252  * HISTORY:                                                                *
   1253  *   06/26/1995 BRR : Created.                                             *
   1254  *=========================================================================*/
   1255 void MessageListClass::Set_Width(int width)
   1256 {
   1257 	GadgetClass * gadg;
   1258 
   1259 	if (MessageList) {
   1260 		gadg = MessageList;
   1261 		while (gadg) {
   1262 			((TextLabelClass *)gadg)->PixWidth = width;
   1263 			gadg = gadg->Get_Next();
   1264 		}
   1265 	}
   1266 
   1267 	if (IsEdit) {
   1268 		EditLabel->PixWidth = width;
   1269 	}
   1270 
   1271 }	// end of Set_Width
   1272 
   1273 
   1274 /***************************************************************************
   1275  * MessageListClass::Trim_Message -- trims chars off start of message      *
   1276  *                                                                         *
   1277  * INPUT:                                                                  *
   1278  *		dest				buffer to store removed characters in; NULL = none		*
   1279  *		src				text buffer to trim												*
   1280  *		min_chars		min # chars that must be trimmed off						*
   1281  *		max_chars		max # chars allowed to trim									*
   1282  *		scandir			0 = left-to-right, 1 = right-to-left						*
   1283  *                                                                         *
   1284  * OUTPUT:                                                                 *
   1285  *		# characters removed																	*
   1286  *                                                                         *
   1287  * WARNINGS:                                                               *
   1288  *		none.																						*
   1289  *                                                                         *
   1290  * HISTORY:                                                                *
   1291  *   11/07/1995 BRR : Created.                                             *
   1292  *=========================================================================*/
   1293 int MessageListClass::Trim_Message(char * dest, char * src, int min_chars,
   1294 	int max_chars, int scandir)
   1295 {
   1296 	int i;
   1297 	int len;
   1298 	int found;
   1299 
   1300 	//------------------------------------------------------------------------
   1301 	// validate parameters
   1302 	//------------------------------------------------------------------------
   1303 	if (min_chars <= 0) {
   1304 		return(0);
   1305 	}
   1306 
   1307 	len = strlen (src);
   1308 	if (max_chars > len) {
   1309 		max_chars = len;
   1310 	}
   1311 
   1312 	//------------------------------------------------------------------------
   1313 	// find 1st available white space; if there is none, just trim off
   1314 	// 'min_chars' characters.  'i' will be the number of chars to trim.
   1315 	// The chars removed will include the white space.
   1316 	//------------------------------------------------------------------------
   1317 	found = 0;
   1318 	//........................................................................
   1319 	// scan from left to right
   1320 	//........................................................................
   1321 	if (scandir == 0) {
   1322 		for (i = min_chars; i <= max_chars; i++) {
   1323 			if (isspace(src[i - 1])) {
   1324 				found = 1;
   1325 				break;
   1326 			}
   1327 		}
   1328 	}
   1329 	//........................................................................
   1330 	// scan from right to left
   1331 	//........................................................................
   1332 	else {
   1333 		for (i = max_chars; i >= min_chars; i--) {
   1334 			if (isspace(src[i - 1])) {
   1335 				found = 1;
   1336 				break;
   1337 			}
   1338 		}
   1339 	}
   1340 	//........................................................................
   1341 	// If no whitespace was found, just set 'i' to the min # characters
   1342 	//........................................................................
   1343 	if (!found) {
   1344 		i = min_chars;
   1345 	}
   1346 
   1347 	//------------------------------------------------------------------------
   1348 	// Save trimmed characters in the dest buffer, if there is one
   1349 	//------------------------------------------------------------------------
   1350 	if (dest) {
   1351 		memcpy (dest, src, i);
   1352 		dest[i] ='\0';
   1353 	}
   1354 
   1355 	//------------------------------------------------------------------------
   1356 	// Shift characters over in the source buffer
   1357 	//------------------------------------------------------------------------
   1358 	memmove (src, src + i, len - i + 1);
   1359 
   1360 	return (i);
   1361 
   1362 }	// end of Trim_Message
   1363 
   1364 
   1365 /***************************************************************************
   1366  * MessageListClass::Compute_Y -- recomputes y-coord for all messages      *
   1367  *                                                                         *
   1368  * INPUT:                                                                  *
   1369  *		none.																						*
   1370  *                                                                         *
   1371  * OUTPUT:                                                                 *
   1372  *		none.																						*
   1373  *                                                                         *
   1374  * WARNINGS:                                                               *
   1375  *		none.																						*
   1376  *                                                                         *
   1377  * HISTORY:                                                                *
   1378  *   11/07/1995 BRR : Created.                                             *
   1379  *=========================================================================*/
   1380 void MessageListClass::Compute_Y(void)
   1381 {
   1382 	GadgetClass * gadg;
   1383 	int y;
   1384 
   1385 	//------------------------------------------------------------------------
   1386 	// If the editable message is attached to the message list, 'AdjustEdit'
   1387 	// will be set; so, adjust all y-values downward one line.  Otherwise,
   1388 	// the editable message has its own screen coordinates.
   1389 	//------------------------------------------------------------------------
   1390 	if (IsEdit && AdjustEdit) {
   1391 		y = MessageY + Height;
   1392 	}
   1393 	else {
   1394 		y = MessageY;
   1395 	}
   1396 	if (MessageList) {
   1397 		gadg = MessageList;
   1398 		while (gadg) {
   1399 			gadg->Y = y;
   1400 			gadg = gadg->Get_Next();
   1401 			y += Height;
   1402 		}
   1403 	}
   1404 
   1405 }	// end of Compute_Y
   1406 
   1407 
   1408 /*************************** end of msglist.cpp ****************************/