CnC_Remastered_Collection

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

COMQUEUE.CPP (40921B)


      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&c0\vcs\code\comqueue.cpv   4.1   11 Apr 1996 18:28:16   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  *                                                                         *
     21  *                 Project Name : Command & Conquer                        *
     22  *                                                                         *
     23  *                    File Name : COMQUEUE.CPP                             *
     24  *                                                                         *
     25  *                   Programmer : Bill Randolph                            *
     26  *                                                                         *
     27  *                   Start Date : December 19, 1994                        *
     28  *                                                                         *
     29  *                  Last Update : May 31, 1995 [BRR]                       *
     30  *                                                                         *
     31  *-------------------------------------------------------------------------*
     32  * Functions:                                                              *
     33  *   CommQueueClass::Add_Delay -- adds a new delay value for response time *
     34  *   CommQueueClass::Avg_Response_Time -- returns average response time    *
     35  *   CommQueueClass::CommQueueClass -- class constructor                   *
     36  *   CommQueueClass::Configure_Debug -- sets up special debug values       * 
     37  *   CommQueueClass::Get_Receive -- gets ptr to queue entry                *
     38  *   CommQueueClass::Get_Send -- gets ptr to queue entry                   *
     39  *   CommQueueClass::Init -- initializes this queue                        *
     40  *   CommQueueClass::Max_Response_Time -- returns max response time        *
     41  *   CommQueueClass::Mono_Debug_Print -- Debug output routine              * 
     42  *   CommQueueClass::Mono_Debug_Print2 -- Debug output; alternate format   * 
     43  *   CommQueueClass::Next_Receive -- gets ptr to next entry in send queue  *
     44  *   CommQueueClass::Next_Send -- gets ptr to next entry in send queue     *
     45  *   CommQueueClass::Queue_Receive -- queues a received message            *
     46  *   CommQueueClass::Queue_Send -- queues a message for sending            *
     47  *   CommQueueClass::Reset_Response_Time -- resets computations            *
     48  *   CommQueueClass::UnQueue_Receive -- removes next entry from send queue *
     49  *   CommQueueClass::UnQueue_Send -- removes next entry from send queue    *
     50  *   CommQueueClass::~CommQueueClass -- class destructor                   *
     51  * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
     52 
     53 #if (0)
     54 #include "function.h"
     55 
     56 
     57 /***************************************************************************
     58  * CommQueueClass::CommQueueClass -- class constructor             			*
     59  *                                                                         *
     60  * INPUT:                                                                  *
     61  *		numsend		# queue entries for sending										*
     62  *		numreceive	# queue entries for receiving										*
     63  *		maxlen		maximum desired packet length, in bytes						*
     64  *                                                                         *
     65  * OUTPUT:                                                                 *
     66  *		none.																						*
     67  *                                                                         *
     68  * WARNINGS:                                                               *
     69  *		none.																						*
     70  *                                                                         *
     71  * HISTORY:                                                                *
     72  *   12/19/1994 BR : Created.                                              *
     73  *=========================================================================*/
     74 CommQueueClass::CommQueueClass(int numsend, int numreceive, int maxlen)
     75 {
     76 	int i;
     77 
     78 	/*
     79 	**	Init variables 
     80 	*/
     81 	MaxSend = numsend;
     82 	MaxReceive = numreceive;
     83 	MaxPacketSize = maxlen;
     84 
     85 	/*
     86 	**	Allocate the queue entries 
     87 	*/
     88 	SendQueue = new SendQueueType[numsend];
     89 	ReceiveQueue = new ReceiveQueueType[numreceive];
     90 
     91 	/*
     92 	**	Allocate queue entry buffers 
     93 	*/
     94 	for (i = 0; i < MaxSend; i++) {
     95 		SendQueue[i].Buffer = new char[maxlen];
     96 	}
     97 
     98 	for (i = 0; i < MaxReceive; i++) {
     99 		ReceiveQueue[i].Buffer = new char[maxlen];
    100 	}
    101 
    102 	Init();
    103 }
    104 
    105 
    106 /***************************************************************************
    107  * CommQueueClass::~CommQueueClass -- class destructor             			*
    108  *                                                                         *
    109  * INPUT:                                                                  *
    110  *		none.																						*
    111  *                                                                         *
    112  * OUTPUT:                                                                 *
    113  *		none.																						*
    114  *                                                                         *
    115  * WARNINGS:                                                               *
    116  *		none.																						*
    117  *                                                                         *
    118  * HISTORY:                                                                *
    119  *   12/19/1994 BR : Created.                                              *
    120  *=========================================================================*/
    121 CommQueueClass::~CommQueueClass()
    122 {
    123 	int i;
    124 
    125 	/*
    126 	**	Free queue entry buffers 
    127 	*/
    128 	for (i = 0; i < MaxSend; i++) {
    129 		delete [] SendQueue[i].Buffer;
    130 	}
    131 
    132 	for (i = 0; i < MaxReceive; i++) {
    133 		delete [] ReceiveQueue[i].Buffer;
    134 	}
    135 
    136 	delete [] SendQueue;
    137 	delete [] ReceiveQueue;
    138 }
    139 
    140 
    141 /***************************************************************************
    142  * CommQueueClass::Init -- initializes this queue                          *
    143  *                                                                         *
    144  * INPUT:                                                                  *
    145  *		none.																						*
    146  *                                                                         *
    147  * OUTPUT:                                                                 *
    148  *		none.																						*
    149  *                                                                         *
    150  * WARNINGS:                                                               *
    151  *		none.																						*
    152  *                                                                         *
    153  * HISTORY:                                                                *
    154  *   01/20/1995 BR : Created.                                              *
    155  *=========================================================================*/
    156 void CommQueueClass::Init(void)
    157 {
    158 	int i;
    159 
    160 	/*
    161 	**	Init data members
    162 	*/
    163 	SendTotal = 0L;
    164 	ReceiveTotal = 0L;
    165 
    166 	DelaySum = 0L;
    167 	NumDelay = 0L;
    168 	MeanDelay = 0L;
    169 	MaxDelay = 0L;
    170 
    171 	SendCount = 0;
    172 	SendNext = 0;
    173 	SendEmpty = 0;
    174 
    175 	ReceiveCount = 0;
    176 	ReceiveNext = 0;
    177 	ReceiveEmpty = 0;
    178 
    179 	/*
    180 	**	Init the queue entries
    181 	*/
    182 	for (i = 0; i < MaxSend; i++) {
    183 		SendQueue[i].IsActive = 0;
    184 		SendQueue[i].IsACK = 0;
    185 		SendQueue[i].FirstTime = 0L;
    186 		SendQueue[i].LastTime = 0L;
    187 		SendQueue[i].SendCount = 0L;
    188 		ReceiveQueue[i].BufLen = 0;
    189 	}
    190 	for (i = 0; i < MaxReceive; i++) {
    191 		ReceiveQueue[i].IsActive = 0;
    192 		ReceiveQueue[i].IsRead = 0;
    193 		ReceiveQueue[i].IsACK = 0;
    194 		ReceiveQueue[i].BufLen = 0;
    195 	}
    196 	
    197 	/*
    198 	**	Init debug values
    199 	*/
    200 	DebugOffset = 0;
    201 	DebugSize = 0;
    202 	DebugNames = NULL;
    203 	DebugMaxNames = 0;
    204 }
    205 
    206 
    207 /***************************************************************************
    208  * CommQueueClass::Queue_Send -- queues a message for sending              *
    209  *                                                                         *
    210  * INPUT:                                                                  *
    211  *		buf			buffer containing the message										*
    212  *		buflen		length of 'buf'														*
    213  *                                                                         *
    214  * OUTPUT:                                                                 *
    215  *		1 = OK, 0 = no room in the queue													*
    216  *                                                                         *
    217  * WARNINGS:                                                               *
    218  *		none.																						*
    219  *                                                                         *
    220  * HISTORY:                                                                *
    221  *   12/20/1994 BR : Created.                                              *
    222  *=========================================================================*/
    223 int CommQueueClass::Queue_Send(void *buf, int buflen)
    224 {
    225 	/*
    226 	**	Error if no room in the queue
    227 	*/
    228 	if (SendCount==MaxSend || SendQueue[SendEmpty].IsActive!=0) {
    229 		return(0); 
    230 	}
    231 
    232 	/*
    233 	**	Set entry flags 
    234 	*/
    235 	SendQueue[SendEmpty].IsActive = 1;			// entry is now active
    236 	SendQueue[SendEmpty].IsACK = 0;				// entry hasn't been ACK'd
    237 	SendQueue[SendEmpty].FirstTime = 0L;		// filled in by Manager when sent
    238 	SendQueue[SendEmpty].LastTime = 0L;			// filled in by Manager when sent
    239 	SendQueue[SendEmpty].SendCount = 0L;		// filled in by Manager when sent
    240 	SendQueue[SendEmpty].BufLen = buflen;		// save buffer size
    241 
    242 	/*
    243 	**	Copy the packet data 
    244 	*/
    245 	memcpy(SendQueue[SendEmpty].Buffer,buf,buflen);
    246 
    247 	/*
    248 	**	Increment counters & entry ptr 
    249 	*/
    250 	SendCount++;
    251 	SendEmpty++;
    252 	if (SendEmpty==MaxSend) {
    253 		SendEmpty = 0;
    254 	}
    255 
    256 	SendTotal++;
    257 
    258 	return(1);
    259 }
    260 
    261 
    262 /***************************************************************************
    263  * CommQueueClass::UnQueue_Send -- removes next entry from send queue		*
    264  *                                                                         *
    265  * INPUT:                                                                  *
    266  *		buf			buffer to store entry's data in; if NULL, it's discarded	*
    267  *		buflen		filled in with length of entry retrieved						*
    268  *                                                                         *
    269  * OUTPUT:                                                                 *
    270  *		1 = OK, 0 = no entry to retreive													*
    271  *                                                                         *
    272  * WARNINGS:                                                               *
    273  *		none.																						*
    274  *                                                                         *
    275  * HISTORY:                                                                *
    276  *   12/20/1994 BR : Created.                                              *
    277  *=========================================================================*/
    278 int CommQueueClass::UnQueue_Send(void *buf, int *buflen)
    279 {
    280 	/*
    281 	**	Error if no entry to retrieve 
    282 	*/
    283 	if (SendCount==0 || SendQueue[SendNext].IsActive==0) {
    284 		return(0);
    285 	}
    286 
    287 	/*
    288 	**	Copy the data from the entry 
    289 	*/
    290 	if (buf!=NULL) {
    291 		memcpy(buf,SendQueue[SendNext].Buffer,SendQueue[SendNext].BufLen);
    292 		(*buflen) = SendQueue[SendNext].BufLen;
    293 	}
    294 
    295 	/*
    296 	**	Set entry flags 
    297 	*/
    298 	SendQueue[SendNext].IsActive = 0;
    299 	SendQueue[SendNext].IsACK = 0;
    300 	SendQueue[SendNext].FirstTime = 0L;
    301 	SendQueue[SendNext].LastTime = 0L;
    302 	SendQueue[SendNext].SendCount = 0L;
    303 	SendQueue[SendNext].BufLen = 0;
    304 	SendCount--;
    305 	SendNext++;
    306 	if (SendNext==MaxSend) {
    307 		SendNext = 0;
    308 	}
    309 
    310 	return(1);
    311 }
    312 
    313 
    314 /***************************************************************************
    315  * CommQueueClass::Next_Send -- gets ptr to next entry in send queue       *
    316  *                                                                         *
    317  * INPUT:                                                                  *
    318  *		none.																						*
    319  *                                                                         *
    320  * OUTPUT:                                                                 *
    321  *		ptr to entry, NULL if there is none.											*
    322  *                                                                         *
    323  * WARNINGS:                                                               *
    324  *		none.																						*
    325  *                                                                         *
    326  * HISTORY:                                                                *
    327  *   12/20/1994 BR : Created.                                              *
    328  *=========================================================================*/
    329 SendQueueType * CommQueueClass::Next_Send(void)
    330 {
    331 	if (SendCount==0) {
    332 		return(NULL);
    333 	} else {
    334 		return(&SendQueue[SendNext]);
    335 	}
    336 }
    337 
    338 
    339 /***************************************************************************
    340  * CommQueueClass::Get_Send -- gets ptr to queue entry                     *
    341  *                                                                         *
    342  * This routine gets a pointer to the indicated queue entry.  The index		*
    343  * value is relative to the next-accessable queue entry; 0 = get the			*
    344  * next available queue entry, 1 = get the one behind that, etc.				*
    345  *                                                                         *
    346  * INPUT:                                                                  *
    347  *		index		index of entry to get (0 = 1st available)							*
    348  *                                                                         *
    349  * OUTPUT:                                                                 *
    350  *		ptr to entry																			*
    351  *                                                                         *
    352  * WARNINGS:                                                               *
    353  *		none.																						*
    354  *                                                                         *
    355  * HISTORY:                                                                *
    356  *   12/21/1994 BR : Created.                                              *
    357  *=========================================================================*/
    358 SendQueueType * CommQueueClass::Get_Send(int index)
    359 {
    360 	int i;
    361 
    362 	i = SendNext + index;
    363 	if (i >= MaxSend) {
    364 		i -= MaxSend;
    365 	}
    366 
    367 	if (SendQueue[i].IsActive==0) {
    368 		return(NULL);
    369 	} else {
    370 		return(&SendQueue[i]);
    371 	}
    372 }
    373 
    374 
    375 /***************************************************************************
    376  * CommQueueClass::Queue_Receive -- queues a received message					*
    377  *                                                                         *
    378  * INPUT:                                                                  *
    379  *		buf			buffer containing the message										*
    380  *		buflen		length of 'buf'														*
    381  *                                                                         *
    382  * OUTPUT:                                                                 *
    383  *		1 = OK, 0 = no room in the queue													*
    384  *                                                                         *
    385  * WARNINGS:                                                               *
    386  *		none.																						*
    387  *                                                                         *
    388  * HISTORY:                                                                *
    389  *   12/20/1994 BR : Created.                                              *
    390  *=========================================================================*/
    391 int CommQueueClass::Queue_Receive(void *buf, int buflen)
    392 {
    393 	/*
    394 	**	Error if no room in the queue
    395 	*/
    396 	if (ReceiveCount==MaxReceive || ReceiveQueue[ReceiveEmpty].IsActive!=0) {
    397 		return(0); 
    398 	}
    399 
    400 	/*
    401 	**	Set entry flags
    402 	*/
    403 	ReceiveQueue[ReceiveEmpty].IsActive = 1;
    404 	ReceiveQueue[ReceiveEmpty].IsRead = 0;
    405 	ReceiveQueue[ReceiveEmpty].IsACK = 0;
    406 	ReceiveQueue[ReceiveEmpty].BufLen = buflen;
    407 
    408 	/*
    409 	**	Copy the packet data
    410 	*/
    411 	memcpy(ReceiveQueue[ReceiveEmpty].Buffer,buf,buflen);
    412 
    413 	/*
    414 	**	Increment counters & entry ptr 
    415 	*/
    416 	ReceiveCount++;
    417 	ReceiveEmpty++;
    418 	if (ReceiveEmpty==MaxReceive) {
    419 		ReceiveEmpty = 0;
    420 	}
    421 
    422 	ReceiveTotal++;
    423 
    424 	return(1);
    425 }
    426 
    427 
    428 /***************************************************************************
    429  * CommQueueClass::UnQueue_Receive -- removes next entry from send queue	*
    430  *                                                                         *
    431  * INPUT:                                                                  *
    432  *		buf			buffer to store entry's data in; if NULL, it's discarded	*
    433  *		buflen		filled in with length of entry retrieved						*
    434  *                                                                         *
    435  * OUTPUT:                                                                 *
    436  *		1 = OK, 0 = no entry to retreive													*
    437  *                                                                         *
    438  * WARNINGS:                                                               *
    439  *		none.																						*
    440  *                                                                         *
    441  * HISTORY:                                                                *
    442  *   12/20/1994 BR : Created.                                              *
    443  *=========================================================================*/
    444 int CommQueueClass::UnQueue_Receive(void *buf, int *buflen)
    445 {
    446 	/*
    447 	**	Error if no entry to retrieve 
    448 	*/
    449 	if (ReceiveCount==0 || ReceiveQueue[ReceiveNext].IsActive==0) {
    450 		return(0);
    451 	}
    452 
    453 	/*
    454 	**	Copy the data from the entry
    455 	*/
    456 	if (buf!=NULL) {
    457 		memcpy(buf,ReceiveQueue[ReceiveNext].Buffer,
    458 			ReceiveQueue[ReceiveNext].BufLen);
    459 		(*buflen) = ReceiveQueue[ReceiveNext].BufLen;
    460 	}
    461 
    462 	/*
    463 	**	Set entry flags
    464 	*/
    465 	ReceiveQueue[ReceiveNext].IsActive = 0;
    466 	ReceiveQueue[ReceiveNext].IsRead = 0;
    467 	ReceiveQueue[ReceiveNext].IsACK = 0;
    468 	ReceiveQueue[ReceiveNext].BufLen = 0;
    469 	ReceiveCount--;
    470 	ReceiveNext++;
    471 	if (ReceiveNext==MaxReceive) {
    472 		ReceiveNext = 0;
    473 	}
    474 
    475 	return(1);
    476 }
    477 
    478 
    479 /***************************************************************************
    480  * CommQueueClass::Next_Receive -- gets ptr to next entry in send queue    *
    481  *                                                                         *
    482  * INPUT:                                                                  *
    483  *		none.																						*
    484  *                                                                         *
    485  * OUTPUT:                                                                 *
    486  *		ptr to entry, NULL if there is none.											*
    487  *                                                                         *
    488  * WARNINGS:                                                               *
    489  *		none.																						*
    490  *                                                                         *
    491  * HISTORY:                                                                *
    492  *   12/20/1994 BR : Created.                                              *
    493  *=========================================================================*/
    494 ReceiveQueueType * CommQueueClass::Next_Receive(void)
    495 {
    496 	if (ReceiveCount==0) {
    497 		return(NULL);
    498 	} else {
    499 		return(&ReceiveQueue[ReceiveNext]);
    500 	}
    501 }
    502 
    503 
    504 /***************************************************************************
    505  * CommQueueClass::Get_Receive -- gets ptr to queue entry                  *
    506  *                                                                         *
    507  * This routine gets a pointer to the indicated queue entry.  The index		*
    508  * value is relative to the next-accessable queue entry; 0 = get the			*
    509  * next available queue entry, 1 = get the one behind that, etc.				*
    510  *                                                                         *
    511  * INPUT:                                                                  *
    512  *		index		index of entry to get (0 = 1st available)							*
    513  *                                                                         *
    514  * OUTPUT:                                                                 *
    515  *		ptr to entry																			*
    516  *                                                                         *
    517  * WARNINGS:                                                               *
    518  *		none.																						*
    519  *                                                                         *
    520  * HISTORY:                                                                *
    521  *   12/21/1994 BR : Created.                                              *
    522  *=========================================================================*/
    523 ReceiveQueueType * CommQueueClass::Get_Receive(int index)
    524 {
    525 	int i;
    526 
    527 	i = ReceiveNext + index;
    528 	if (i >= MaxReceive) {
    529 		i -= MaxReceive;
    530 	}
    531 
    532 	if (ReceiveQueue[i].IsActive==0) {
    533 		return(NULL);
    534 	} else {
    535 		return(&ReceiveQueue[i]);
    536 	}
    537 }
    538 
    539 
    540 /***************************************************************************
    541  * CommQueueClass::Add_Delay -- adds a new delay value for response time   *
    542  *                                                                         *
    543  * This routine updates the average response time for this queue.  The		*
    544  * computation is based on the average of the last 'n' delay values given,	*
    545  * It computes a running total of the last n delay values, then divides 	*
    546  * that by n to compute the average.													*
    547  *																									*
    548  * When the number of values given exceeds the max, the mean is subtracted	*
    549  * off the total, then the new value is added in.  Thus, any single delay	*
    550  * value will have an effect on the total that approaches 0 over time, and	*
    551  * the new delay value contributes to 1/n of the mean.							*
    552  *                                                                         *
    553  * INPUT:                                                                  *
    554  *		delay			value to add into the response time computation				*
    555  *                                                                         *
    556  * OUTPUT:                                                                 *
    557  *		none.																						*
    558  *                                                                         *
    559  * WARNINGS:                                                               *
    560  *		none.																						*
    561  *                                                                         *
    562  * HISTORY:                                                                *
    563  *   01/19/1995 BR : Created.                                              *
    564  *=========================================================================*/
    565 void CommQueueClass::Add_Delay(unsigned long delay)
    566 {
    567 	int roundoff = 0;
    568 
    569 	if (NumDelay==256) {
    570 		DelaySum -= MeanDelay;
    571 		DelaySum += delay;
    572 		if ( (DelaySum & 0x00ff) > 127) {
    573 			roundoff = 1;
    574 		}
    575 		MeanDelay = (DelaySum >> 8) + roundoff;
    576 	} else {
    577 		NumDelay++;
    578 		DelaySum += delay;
    579 		MeanDelay = DelaySum / NumDelay;
    580 	}
    581 
    582 	if (delay > MaxDelay) {
    583 		MaxDelay = delay;
    584 	}
    585 }
    586 
    587 
    588 /***************************************************************************
    589  * CommQueueClass::Avg_Response_Time -- returns average response time    	*
    590  *                                                                         *
    591  * INPUT:                                                                  *
    592  *		none.																						*
    593  *                                                                         *
    594  * OUTPUT:                                                                 *
    595  *		latest computed average response time											*
    596  *                                                                         *
    597  * WARNINGS:                                                               *
    598  *		none.																						*
    599  *                                                                         *
    600  * HISTORY:                                                                *
    601  *   01/19/1995 BR : Created.                                              *
    602  *=========================================================================*/
    603 unsigned long CommQueueClass::Avg_Response_Time(void)
    604 {
    605 	return(MeanDelay);
    606 }
    607 
    608 
    609 /***************************************************************************
    610  * CommQueueClass::Max_Response_Time -- returns max response time    		*
    611  *                                                                         *
    612  * INPUT:                                                                  *
    613  *		none.																						*
    614  *                                                                         *
    615  * OUTPUT:                                                                 *
    616  *		latest computed average response time											*
    617  *                                                                         *
    618  * WARNINGS:                                                               *
    619  *		none.																						*
    620  *                                                                         *
    621  * HISTORY:                                                                *
    622  *   01/19/1995 BR : Created.                                              *
    623  *=========================================================================*/
    624 unsigned long CommQueueClass::Max_Response_Time(void)
    625 {
    626 	return(MaxDelay);
    627 }
    628 
    629 
    630 /***************************************************************************
    631  * CommQueueClass::Reset_Response_Time -- resets computations					*
    632  *                                                                         *
    633  * INPUT:                                                                  *
    634  *		none.																						*
    635  *                                                                         *
    636  * OUTPUT:                                                                 *
    637  *		none.																						*
    638  *                                                                         *
    639  * WARNINGS:                                                               *
    640  *		none.																						*
    641  *                                                                         *
    642  * HISTORY:                                                                *
    643  *   01/19/1995 BR : Created.                                              *
    644  *=========================================================================*/
    645 void CommQueueClass::Reset_Response_Time(void)
    646 {
    647 	DelaySum = 0L;
    648 	NumDelay = 0L;
    649 	MeanDelay = 0L;
    650 	MaxDelay = 0L;
    651 }
    652 
    653 
    654 /*************************************************************************** 
    655  * CommQueueClass::Configure_Debug -- sets up special debug values         * 
    656  *                                                                         * 
    657  * Mono_Debug_Print2() can look into a packet to pull out a particular		*
    658  * ID, and can print both that ID and a string corresponding to				*
    659  * that ID.  This routine configures these values so it can find				*
    660  * and decode the ID.  This ID is used in addition to the normal				*
    661  * CommHeaderType values.																	*
    662  *                                                                         * 
    663  * INPUT:                                                                  * 
    664  *		offset		ID's byte offset into packet										*
    665  *		size			size of ID, in bytes; 0 if none									*
    666  *		names			ptr to array of names; use ID as an index into this		*
    667  *		maxnames		max # in the names array; 0 if none.							*
    668  *                                                                         * 
    669  * OUTPUT:                                                                 * 
    670  *		none.																						*
    671  *                                                                         * 
    672  * WARNINGS:                                                               * 
    673  *		Names shouldn't be longer than 12 characters.								*
    674  *                                                                         * 
    675  * HISTORY:                                                                * 
    676  *   05/31/1995 BRR : Created.                                             * 
    677  *=========================================================================*/
    678 void CommQueueClass::Configure_Debug(int offset, int size, char **names, 
    679 	int maxnames)
    680 {
    681 	DebugOffset = offset;
    682 	DebugSize = size;
    683 	DebugNames = names;
    684 	DebugMaxNames = maxnames;
    685 }
    686 
    687 
    688 /*************************************************************************** 
    689  * Mono_Debug_Print -- Debug output routine                                * 
    690  *                                                                         * 
    691  * This routine leaves 5 lines at the top for the caller's use.				*
    692  *                                                                         * 
    693  * INPUT:                                                                  * 
    694  *		refresh		1 = clear screen & completely refresh							*
    695  *                                                                         * 
    696  * OUTPUT:                                                                 * 
    697  *		none.																						*
    698  *                                                                         * 
    699  * WARNINGS:                                                               * 
    700  *		none.																						*
    701  *                                                                         * 
    702  * HISTORY:                                                                * 
    703  *   05/02/1995 BRR : Created.                                             * 
    704  *=========================================================================*/
    705 void CommQueueClass::Mono_Debug_Print(int refresh)
    706 {
    707 #ifdef WWLIB32_H
    708 	int i;												// loop counter
    709 	static int send_col[] = {1,14,28};			// coords of send queue columns
    710 	static int receive_col[] = {40,54,68};		// coords of recv queue columns
    711 	int row,col;										// current row,col for printing
    712 	int num;												// max # items to print
    713 
    714 	struct CommHdr {									// this mirrors the CommHeaderType
    715 		unsigned short MagicNumber;
    716 		unsigned char Code;
    717 		unsigned long PacketID;
    718 	} *hdr;
    719 
    720 	/*
    721 	**	If few enough entries, call the verbose debug version
    722 	*/
    723 	if (MaxSend <= 16) {
    724 		Mono_Debug_Print2(refresh);
    725 		return;
    726 	}
    727 
    728 	/*
    729 	**	Refresh the screen
    730 	*/
    731 	if (refresh) {
    732 		Mono_Clear_Screen ();
    733 		Mono_Printf("ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿\n");
    734 		Mono_Printf("³                                                                             ³\n");
    735 		Mono_Printf("³                                                                             ³\n");
    736 		Mono_Printf("³                                                                             ³\n");
    737 		Mono_Printf("ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´\n");
    738 		Mono_Printf("³              Send Queue              ³             Receive Queue            ³\n");
    739 		Mono_Printf("³                                      ³                                      ³\n");
    740 		Mono_Printf("³ ID  Ct ACK   ID  Ct ACK    ID  Ct ACK³ ID  Rd ACK    ID  Rd ACK   ID  Rd ACK³\n");
    741 		Mono_Printf("³                                      ³                                      ³\n");
    742 		Mono_Printf("³                                      ³                                      ³\n");
    743 		Mono_Printf("³                                      ³                                      ³\n");
    744 		Mono_Printf("³                                      ³                                      ³\n");
    745 		Mono_Printf("³                                      ³                                      ³\n");
    746 		Mono_Printf("³                                      ³                                      ³\n");
    747 		Mono_Printf("³                                      ³                                      ³\n");
    748 		Mono_Printf("³                                      ³                                      ³\n");
    749 		Mono_Printf("³                                      ³                                      ³\n");
    750 		Mono_Printf("³                                      ³                                      ³\n");
    751 		Mono_Printf("³                                      ³                                      ³\n");
    752 		Mono_Printf("³                                      ³                                      ³\n");
    753 		Mono_Printf("³                                      ³                                      ³\n");
    754 		Mono_Printf("³                                      ³                                      ³\n");
    755 		Mono_Printf("³                                      ³                                      ³\n");
    756 		Mono_Printf("³                                      ³                                      ³\n");
    757 		Mono_Printf("ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ");
    758 	}
    759 
    760 	/*
    761 	**	Print Send Queue items
    762 	*/
    763 	if (MaxSend <= 48) {
    764 		num = MaxSend;
    765 	} else {
    766 		num = 48;
    767 	}
    768 	col = 0;
    769 	row = 0;
    770 	for (i = 0; i < MaxSend; i++) {
    771 		Mono_Set_Cursor (send_col[col],row + 8);
    772 		if (SendQueue[i].IsActive) {
    773 			hdr = (CommHdr *)SendQueue[i].Buffer;
    774 			hdr->MagicNumber = hdr->MagicNumber;
    775 			hdr->Code = hdr->Code;
    776 			Mono_Printf ("%4d %2d  %d",hdr->PacketID, SendQueue[i].SendCount,
    777 				SendQueue[i].IsACK);
    778 		} else {
    779 			Mono_Printf ("____ __  _ ");
    780 		}
    781 
    782 		row++;
    783 		if (row > 15) {
    784 			row = 0;
    785 			col++;
    786 		}
    787 	}
    788 
    789 	/*
    790 	**	Print Receive Queue items
    791 	*/
    792 	if (MaxReceive <= 48) {
    793 		num = MaxSend;
    794 	} else {
    795 		num = 48;
    796 	}
    797 	col = 0;
    798 	row = 0;
    799 	for (i = 0; i < MaxReceive; i++) {
    800 		Mono_Set_Cursor (receive_col[col],row + 8);
    801 		if (ReceiveQueue[i].IsActive) {
    802 			hdr = (CommHdr *)ReceiveQueue[i].Buffer;
    803 			Mono_Printf ("%4d  %d  %d",hdr->PacketID, ReceiveQueue[i].IsRead,
    804 				ReceiveQueue[i].IsACK);
    805 		} else {
    806 			Mono_Printf ("____  _  _ ");
    807 		}
    808 
    809 		row++;
    810 		if (row > 15) {
    811 			row = 0;
    812 			col++;
    813 		}
    814 	}
    815 
    816 #else
    817 	refresh = refresh;
    818 #endif	
    819 }
    820 
    821 
    822 /*************************************************************************** 
    823  * CommQueueClass::Mono_Debug_Print2 -- Debug output; alternate format     * 
    824  *                                                                         * 
    825  * This routine prints more information than the other version; it's			*
    826  * called only if the number of queue entries is small enough to support	*
    827  * this format.																				*
    828  *                                                                         * 
    829  * INPUT:                                                                  * 
    830  *		refresh		1 = clear screen & completely refresh							*
    831  *                                                                         * 
    832  * OUTPUT:                                                                 * 
    833  *		none.																						*
    834  *                                                                         * 
    835  * WARNINGS:                                                               * 
    836  *		none.																						*
    837  *                                                                         * 
    838  * HISTORY:                                                                * 
    839  *   05/31/1995 BRR : Created.                                             * 
    840  *=========================================================================*/
    841 void CommQueueClass::Mono_Debug_Print2(int refresh)
    842 {
    843 #ifdef WWLIB32_H
    844 	int i;												// loop counter
    845 	char txt[80];
    846 	int val;
    847 
    848 	struct CommHdr {									// this mirrors the CommHeaderType
    849 		unsigned short MagicNumber;
    850 		unsigned char Code;
    851 		unsigned long PacketID;
    852 	} *hdr;
    853 
    854 	/*
    855 	**	Refresh the screen
    856 	*/
    857 	if (refresh) {
    858 		Mono_Clear_Screen ();
    859 		Mono_Printf("ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿\n");
    860 		Mono_Printf("³                                                                             ³\n");
    861 		Mono_Printf("³                                                                             ³\n");
    862 		Mono_Printf("³                                                                             ³\n");
    863 		Mono_Printf("ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´\n");
    864 		Mono_Printf("³              Send Queue              ³             Receive Queue            ³\n");
    865 		Mono_Printf("³                                      ³                                      ³\n");
    866 		Mono_Printf("³ ID  Ct Type   Data  Name         ACK ³ ID  Rd Type   Data  Name         ACK ³\n");
    867 		Mono_Printf("³                                      ³                                      ³\n");
    868 		Mono_Printf("³                                      ³                                      ³\n");
    869 		Mono_Printf("³                                      ³                                      ³\n");
    870 		Mono_Printf("³                                      ³                                      ³\n");
    871 		Mono_Printf("³                                      ³                                      ³\n");
    872 		Mono_Printf("³                                      ³                                      ³\n");
    873 		Mono_Printf("³                                      ³                                      ³\n");
    874 		Mono_Printf("³                                      ³                                      ³\n");
    875 		Mono_Printf("³                                      ³                                      ³\n");
    876 		Mono_Printf("³                                      ³                                      ³\n");
    877 		Mono_Printf("³                                      ³                                      ³\n");
    878 		Mono_Printf("³                                      ³                                      ³\n");
    879 		Mono_Printf("³                                      ³                                      ³\n");
    880 		Mono_Printf("³                                      ³                                      ³\n");
    881 		Mono_Printf("³                                      ³                                      ³\n");
    882 		Mono_Printf("³                                      ³                                      ³\n");
    883 		Mono_Printf("ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ");
    884 	}
    885 
    886 	/*
    887 	**	Print Send Queue items
    888 	*/
    889 	for (i = 0; i < MaxSend; i++) {
    890 		Mono_Set_Cursor (1,8 + i);
    891 		
    892 		/*
    893 		**	Print an active entry
    894 		*/
    895 		if (SendQueue[i].IsActive) {
    896 			
    897 			/*
    898 			**	Get header info
    899 			*/
    900 			hdr = (CommHdr *)SendQueue[i].Buffer;
    901 			hdr->MagicNumber = hdr->MagicNumber;
    902 			hdr->Code = hdr->Code;
    903 			sprintf(txt,"%4d %2d %-5s  ",
    904 				hdr->PacketID,
    905 				SendQueue[i].SendCount,
    906 				ConnectionClass::Command_Name(hdr->Code));
    907 
    908 			/*
    909 			**	Decode app's ID & its name
    910 			*/
    911 			if (DebugSize && (DebugOffset + DebugSize) <= SendQueue[i].BufLen) {
    912 				if (DebugSize==1) {
    913 					val = *(SendQueue[i].Buffer + DebugOffset);
    914 				} else {
    915 					if (DebugSize==2) {
    916 						val = *((short *)(SendQueue[i].Buffer + DebugOffset));
    917 					} else {
    918 						if (DebugSize==4) {
    919 							val = *((int *)(SendQueue[i].Buffer + DebugOffset));
    920 						}
    921 					} 
    922 				}
    923 				sprintf(txt + strlen(txt),"%4d  ",val);
    924 
    925 				if (DebugMaxNames && val > 0 && val < DebugMaxNames) {
    926 					sprintf(txt + strlen(txt),"%-12s  %x",
    927 						DebugNames[val],
    928 						SendQueue[i].IsACK);
    929 				} else {
    930 					sprintf(txt + strlen(txt),"              %x",SendQueue[i].IsACK);
    931 				}
    932 			}
    933 		} else {
    934 
    935 			/*
    936 			**	Entry isn't active; print blanks
    937 			*/
    938 			Mono_Printf("____ __                            _");
    939 		}
    940 	}
    941 
    942 	/*
    943 	**	Print Receive Queue items
    944 	*/
    945 	for (i = 0; i < MaxReceive; i++) {
    946 		Mono_Set_Cursor (40,8 + i);
    947 		
    948 		/*
    949 		**	Print an active entry
    950 		*/
    951 		if (ReceiveQueue[i].IsActive) {
    952 			
    953 			/*
    954 			**	Get header info
    955 			*/
    956 			hdr = (CommHdr *)ReceiveQueue[i].Buffer;
    957 			hdr->MagicNumber = hdr->MagicNumber;
    958 			hdr->Code = hdr->Code;
    959 			sprintf(txt,"%4d %2d %-5s  ",
    960 				hdr->PacketID,
    961 				ReceiveQueue[i].IsRead,
    962 				ConnectionClass::Command_Name(hdr->Code));
    963 			
    964 			/*
    965 			**	Decode app's ID & its name
    966 			*/
    967 			if (DebugSize && (DebugOffset + DebugSize) <= SendQueue[i].BufLen) {
    968 				if (DebugSize==1) {
    969 					val = *(ReceiveQueue[i].Buffer + DebugOffset);
    970 				} else {
    971 					if (DebugSize==2) {
    972 						val = *((short *)(ReceiveQueue[i].Buffer + DebugOffset));
    973 					} else {
    974 						if (DebugSize==4) {
    975 							val = *((int *)(ReceiveQueue[i].Buffer + DebugOffset));
    976 						}
    977 					}
    978 				} 
    979 				sprintf(txt + strlen(txt),"%4d  ",val);
    980 
    981 				if (DebugMaxNames && val > 0 && val < DebugMaxNames) {
    982 					sprintf(txt + strlen(txt),"%-12s  %x", DebugNames[val], ReceiveQueue[i].IsACK);
    983 				} else {
    984 					sprintf(txt + strlen(txt),"              %x",ReceiveQueue[i].IsACK);
    985 				}
    986 			}
    987 		} else {
    988 
    989 			/*
    990 			**	Entry isn't active; print blanks
    991 			*/
    992 			Mono_Printf("____ __                            _");
    993 		}
    994 	}
    995 
    996 #else
    997 	refresh = refresh;
    998 #endif	
    999 }
   1000 
   1001 
   1002 #endif