COMQUEUE.CPP 40 KB

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