DEBUG.CPP 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690
  1. /*
  2. ** Command & Conquer(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&c\vcs\code\debug.cpv 2.17 16 Oct 1995 16:49:18 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 : DEBUG.CPP *
  26. * *
  27. * Programmer : Joe L. Bostic *
  28. * *
  29. * Start Date : September 10, 1993 *
  30. * *
  31. * Last Update : July 5, 1994 [JLB] *
  32. * *
  33. *---------------------------------------------------------------------------------------------*
  34. * Functions: *
  35. * Self_Regulate -- Regulates the logic timer to result in smooth animation. *
  36. * Debug_Key -- Debug mode keyboard processing. *
  37. * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  38. #include "function.h"
  39. #include <stdarg.h>
  40. #include <filepcx.h>
  41. #include <io.h>
  42. #ifdef CHEAT_KEYS
  43. extern bool ScreenRecording;
  44. /***********************************************************************************************
  45. * Debug_Key -- Debug mode keyboard processing. *
  46. * *
  47. * If debugging is enabled, then this routine will be called for every keystroke that the *
  48. * game doesn't recognize. These extra keys usually perform some debugging function. *
  49. * *
  50. * INPUT: input -- The key code that was pressed. *
  51. * *
  52. * OUTPUT: none *
  53. * *
  54. * WARNINGS: none *
  55. * *
  56. * HISTORY: *
  57. * 10/07/1992 JLB : Created. *
  58. *=============================================================================================*/
  59. void Debug_Key(unsigned input)
  60. {
  61. static int map_x = -1;
  62. static int map_y = -1;
  63. static int map_width = -1;
  64. static int map_height = -1;
  65. if (!input || input & KN_BUTTON) return;
  66. /*
  67. ** Processing of normal keystrokes.
  68. */
  69. if (Debug_Flag) {
  70. switch (input) {
  71. case KN_L:
  72. extern int NetMonoMode,NewMonoMode;
  73. if (NetMonoMode)
  74. NetMonoMode = 0;
  75. else
  76. NetMonoMode = 1;
  77. NewMonoMode = 1;
  78. break;
  79. /*
  80. ** Start saving off screens
  81. */
  82. case (int)KN_K|(int)KN_CTRL_BIT:
  83. ScreenRecording = true;
  84. break;
  85. case KN_K:
  86. /*
  87. ** time to create a screen shot using the PCX code (if it works)
  88. */
  89. {
  90. GraphicBufferClass temp_page( SeenBuff.Get_Width(),
  91. SeenBuff.Get_Height(),
  92. NULL,
  93. SeenBuff.Get_Width() * SeenBuff.Get_Height());
  94. char filename[30];
  95. SeenBuff.Blit(temp_page);
  96. for (int lp = 0; lp < 99; lp ++) {
  97. if (lp < 10) {
  98. sprintf(filename, "scrsht0%d.pcx", lp);
  99. } else {
  100. sprintf(filename, "scrsht%d.pcx", lp);
  101. }
  102. if (access(filename, F_OK) == -1)
  103. break;
  104. }
  105. Write_PCX_File(filename, temp_page, (unsigned char *)CurrentPalette);
  106. //Map.Place_Random_Crate();
  107. }
  108. break;
  109. case KN_P:
  110. Keyboard::Clear();
  111. while (!Keyboard::Check()) {
  112. Self_Regulate();
  113. Sound_Callback();
  114. }
  115. Keyboard::Clear();
  116. break;
  117. case KN_O:
  118. {
  119. AircraftClass * air = new AircraftClass(AIRCRAFT_ORCA, PlayerPtr->Class->House);
  120. if (air) {
  121. air->Altitude = 0;
  122. air->Unlimbo(Map.Pixel_To_Coord(Get_Mouse_X(), Get_Mouse_Y()), DIR_N);
  123. }
  124. }
  125. break;
  126. case (int)KN_B|(int)KN_ALT_BIT:
  127. {
  128. Debug_Instant_Build ^= 1;
  129. }
  130. break;
  131. case KN_B:
  132. {
  133. AircraftClass * air = new AircraftClass(AIRCRAFT_HELICOPTER, PlayerPtr->Class->House);
  134. if (air) {
  135. air->Altitude = 0;
  136. air->Unlimbo(Map.Pixel_To_Coord(Get_Mouse_X(), Get_Mouse_Y()), DIR_N);
  137. }
  138. }
  139. break;
  140. case KN_T:
  141. {
  142. AircraftClass * air = new AircraftClass(AIRCRAFT_TRANSPORT, PlayerPtr->Class->House);
  143. if (air) {
  144. air->Altitude = 0;
  145. air->Unlimbo(Map.Pixel_To_Coord(Get_Mouse_X(), Get_Mouse_Y()), DIR_N);
  146. }
  147. }
  148. break;
  149. case KN_GRAVE:
  150. new AnimClass(ANIM_ART_EXP1, Map.Pixel_To_Coord(Get_Mouse_X(), Get_Mouse_Y()));
  151. Explosion_Damage(Map.Pixel_To_Coord(Get_Mouse_X(), Get_Mouse_Y()), 250, NULL, WARHEAD_HE);
  152. break;
  153. case KN_Z:
  154. // new AnimClass(ANIM_LZ_SMOKE, Map.Pixel_To_Coord(Get_Mouse_X(), Get_Mouse_Y()));
  155. GDI_Ending();
  156. break;
  157. case KN_C:
  158. Debug_Cheat = (Debug_Cheat == false);
  159. PlayerPtr->IsRecalcNeeded = true;
  160. PlayerPtr->Add_Nuke_Piece();
  161. PlayerPtr->Add_Nuke_Piece();
  162. PlayerPtr->Add_Nuke_Piece();
  163. /*
  164. ** This placement might affect any prerequisite requirements for construction
  165. ** lists. Update the buildable options accordingly.
  166. */
  167. if (!ScenarioInit) {
  168. Map.Recalc();
  169. for (int index = 0; index < Buildings.Count(); index++) {
  170. Buildings.Ptr(index)->Update_Buildables();
  171. }
  172. }
  173. break;
  174. case (int)KN_Z|(int)KN_ALT_BIT:
  175. if (map_x == -1) {
  176. map_x = Map.MapCellX;
  177. map_y = Map.MapCellY;
  178. map_width = Map.MapCellWidth;
  179. map_height = Map.MapCellHeight;
  180. Map.MapCellX = 1;
  181. Map.MapCellY = 1;
  182. Map.MapCellWidth = 62;
  183. Map.MapCellHeight = 62;
  184. } else {
  185. Map.MapCellX = map_x;
  186. Map.MapCellY = map_y;
  187. Map.MapCellWidth = map_width;
  188. Map.MapCellHeight = map_height;
  189. map_x = -1;
  190. map_y = -1;
  191. map_width = -1;
  192. map_height = -1;
  193. }
  194. break;
  195. #ifdef NEVER
  196. case KN_G:
  197. HouseClass::As_Pointer(HOUSE_GOOD)->Flag_Attach(Map.Click_Cell_Calc(Get_Mouse_X(), Get_Mouse_Y()));
  198. break;
  199. case KN_N:
  200. HouseClass::As_Pointer(HOUSE_BAD)->Flag_Attach(Map.Click_Cell_Calc(Get_Mouse_X(), Get_Mouse_Y()));
  201. break;
  202. #endif
  203. case KN_R:
  204. if (CurrentObject.Count()) {
  205. ((TechnoClass *)CurrentObject[0])->IsCloakable = true;
  206. }
  207. break;
  208. case KN_M:
  209. if (Debug_Flag) {
  210. if (MonoClass::Is_Enabled()) {
  211. MonoClass::Disable();
  212. } else {
  213. MonoClass::Enable();
  214. }
  215. }
  216. break;
  217. case (int)KN_W|(int)KN_ALT_BIT:
  218. PlayerPtr->Flag_To_Win();
  219. break;
  220. case (int)KN_L|(int)KN_ALT_BIT:
  221. PlayerPtr->Flag_To_Lose();
  222. break;
  223. case KN_F:
  224. Debug_Find_Path ^= 1;
  225. break;
  226. case KN_DELETE:
  227. if (CurrentObject.Count()) {
  228. Map.Recalc();
  229. //CurrentObject[0]->Detach_All();
  230. delete CurrentObject[0];
  231. }
  232. break;
  233. case KN_D:
  234. if (Teams.Ptr(0)) {
  235. delete Teams.Ptr(0);
  236. }
  237. break;
  238. case (int)KN_DELETE|(int)KN_SHIFT_BIT:
  239. if (CurrentObject.Count()) {
  240. Map.Recalc();
  241. int damage = 50;
  242. CurrentObject[0]->Take_Damage(damage, 0, WARHEAD_SA);
  243. }
  244. break;
  245. case KN_INSERT:
  246. if (CurrentObject.Count()) {
  247. Map.PendingObject = &CurrentObject[0]->Class_Of();
  248. if (Map.PendingObject) {
  249. Map.PendingHouse = CurrentObject[0]->Owner();
  250. Map.PendingObjectPtr = Map.PendingObject->Create_One_Of(HouseClass::As_Pointer(Map.PendingHouse));
  251. if (Map.PendingObjectPtr) {
  252. Map.Set_Cursor_Pos();
  253. Map.Set_Cursor_Shape(Map.PendingObject->Occupy_List());
  254. }
  255. }
  256. }
  257. break;
  258. #ifdef NEVER
  259. case KN_1:
  260. case KN_2:
  261. case KN_3:
  262. case KN_4:
  263. case KN_5:
  264. case KN_6:
  265. case KN_7:
  266. case KN_8:
  267. case KN_9:
  268. case KN_0:
  269. MonoPage = (input & 0xFF) - KN_1;
  270. MonoPage %= sizeof(MonoArray)/sizeof(MonoArray[0]);
  271. MonoArray[MonoPage].View();
  272. input = 0;
  273. break;
  274. #endif
  275. #ifdef NEVER
  276. case ((int)KN_F1 | (int)KN_SHIFT_BIT):
  277. Special.IsBarOn = (Special.IsBarOn == false);
  278. Map.Flag_To_Redraw(true);
  279. break;
  280. case ((int)KN_F1 | (int)KN_SHIFT_BIT): // quick load/save for debugging
  281. if (!Save_Game(0,"Command & Conquer Save Game File")) {
  282. CCMessageBox().Process("Error saving game!");
  283. Prog_End();
  284. exit(EXIT_SUCCESS);
  285. }
  286. break;
  287. case ((int)KN_F2 | (int)KN_SHIFT_BIT): // quick load/save for debugging
  288. if (!Load_Game(0)) {
  289. CCMessageBox().Process("Error loading game!");
  290. Prog_End();
  291. exit(EXIT_SUCCESS);
  292. }
  293. break;
  294. //#ifdef SCENARIO_EDITOR
  295. case KN_F2: // enable/disable the map editor
  296. Go_Editor(!Debug_Map);
  297. break;
  298. //#endif
  299. #endif
  300. #ifdef NEVER
  301. case KN_F2: {
  302. Debug_Map++;
  303. Scenario_Editor();
  304. Debug_Map--;
  305. #ifdef NEVER
  306. COORDINATE coord;
  307. int index;
  308. static COORDINATE _coords[] = {
  309. 0x00010001L,
  310. 0x00800080L,
  311. 0x00810081L,
  312. 0x00010081L,
  313. 0x00810001L,
  314. 0x00800081L,
  315. 0x00800001L,
  316. 0x00010080L,
  317. 0x00810080L,
  318. 0L
  319. };
  320. index = 0;
  321. while (_coords[index]) {
  322. coord = _coords[index++];
  323. Mono_Printf("Spillage for %08lX = %d.\r", coord, Coord_Spillage_Number(coord));
  324. }
  325. Keyboard::Clear();
  326. Keyboard::Get();
  327. #endif
  328. #ifdef NEVER
  329. #define MAX_RADIUS 10
  330. COORDINATE coord;
  331. int x,y;
  332. COORDINATE const *ptr;
  333. int input;
  334. int f1,f2;
  335. TurnTrackType const *track;
  336. #define XCENTER 160
  337. #define YCENTER 100
  338. for (;;) {
  339. VisiblePage.Clear();
  340. // Draw grid.
  341. {
  342. static int _gridx[] = {0,64,128,192,0,64,128,192,0,64,128,192};
  343. static int _gridy[] = {0,0,0,0,64,64,64,64,128,128,128,128};
  344. int index;
  345. for (index = 0; index < 12; index++) {
  346. LogicPage->Put_Pixel((_gridx[index]+XCENTER)-(32+64),(_gridy[index]+YCENTER)-(32+64), DKGRAY);
  347. }
  348. }
  349. // Get facing #1.
  350. LogicPage->Print("Facing #1 (0-7)?", 0, 0, WHITE, BLACK);
  351. input = Keyboard::Get();
  352. if (input == KA_ESC) break;
  353. input -= KA_0;
  354. input = Bound(input, 0, 7);
  355. // input = MAX(input, 0);
  356. // input = MIN(input, 7);
  357. f1 = input;
  358. Int_Print(f1, 100, 0, WHITE, BLACK);
  359. // Get facing #2.
  360. LogicPage->Print("Facing #2 (0-7)?", 0, 10, WHITE, BLACK);
  361. input = Keyboard::Get();
  362. if (input == KA_ESC) break;
  363. input -= KA_0;
  364. input = Bound(input, 0, 7);
  365. // input = MAX(input, 0);
  366. // input = MIN(input, 7);
  367. f2 = input;
  368. Int_Print(f2, 100, 10, WHITE, BLACK);
  369. track = &TrackControl[f1][f2];
  370. if (track->Track == 0) {
  371. LogicPage->Print("Undefined track.", 0, 30, WHITE, BLACK);
  372. } else {
  373. int index; // Track index counter.
  374. ptr = TrackPointers[track->Track-1];
  375. index = 0;
  376. while (ptr[index]) {
  377. coord = Smooth_Turn(NULL, ptr[index], track->Flag);
  378. x = (int)(coord & 0xFFFF);
  379. y = (int)((coord >> 16) & 0xFFFF);
  380. LogicPage->Put_Pixel(XCENTER + (x>>2), YCENTER + (y>>2), WHITE);
  381. Delay(1);
  382. index++;
  383. }
  384. }
  385. input = Keyboard::Get();
  386. if (input == KA_ESC) break;
  387. }
  388. Map.Flag_To_Redraw(true);
  389. #endif
  390. #ifdef NEVER
  391. FILE *fh;
  392. int index;
  393. COORDINATE coord;
  394. fh = fopen("diagonal.txt", "wt");
  395. if (fh) {
  396. fprintf(fh, "track 2\n");
  397. coord = 0x0100FF00L;
  398. for (index = 0; index <= 48; index++) {
  399. fprintf(fh, "0x%08lXL\n", coord);
  400. coord = Coord_Move(coord, 32, 11);
  401. }
  402. fprintf(fh, "\n\n");
  403. fprintf(fh, "track 1\n");
  404. coord = 0x01000000L;
  405. for (index = 0; index <= 40; index++) {
  406. fprintf(fh, "0x%08lXL\n", coord);
  407. coord = Coord_Move(coord, 0, 11);
  408. }
  409. fprintf(fh, "\n\n");
  410. fclose(fh);
  411. }
  412. #endif
  413. #ifdef NEVER
  414. FILE *fh;
  415. int x,y,radius;
  416. int radsize[MAX_RADIUS+2];
  417. int count;
  418. memset(radsize, 0, sizeof(radsize));
  419. fh = fopen("Range.txt", "wt");
  420. if (fh) {
  421. fprintf(fh, "int const RadiusOffset[] = {\n");
  422. for (radius = 0; radius <= MAX_RADIUS; radius++) {
  423. fprintf(fh, "\t/* %-2d */\t", radius);
  424. for (y = -MAX_RADIUS; y <= MAX_RADIUS; y++) {
  425. for (x = -MAX_RADIUS; x <= MAX_RADIUS; x++) {
  426. int xd,yd,dist;
  427. xd = ABS(x);
  428. yd = ABS(y);
  429. if (xd > yd) {
  430. dist = yd/2 + xd;
  431. } else {
  432. dist = xd/2 + yd;
  433. }
  434. if (dist == radius) {
  435. dist = y*MAP_CELL_W + x;
  436. if (y) {
  437. if (y < 0) {
  438. fprintf(fh, "(-MCW*%d)", ABS(y));
  439. } else {
  440. fprintf(fh, "(MCW*%d)", ABS(y));
  441. }
  442. fprintf(fh, "%c%d,", (x<0) ? '-' : '+', ABS(x));
  443. } else {
  444. fprintf(fh, "%d,", x);
  445. }
  446. radsize[radius]++;
  447. }
  448. }
  449. }
  450. fprintf(fh, "\n");
  451. }
  452. fprintf(fh, "};\n\n");
  453. count = 0;
  454. fprintf(fh, "int const RadiusCount[%d] = {", MAX_RADIUS+1);
  455. for (radius = 0; radius <= MAX_RADIUS; radius++) {
  456. count += radsize[radius];
  457. fprintf(fh, "%d", count);
  458. if (radius != MAX_RADIUS) {
  459. fprintf(fh, ",");
  460. }
  461. }
  462. fprintf(fh, "};\n");
  463. fclose(fh);
  464. }
  465. #endif
  466. }
  467. break;
  468. #endif
  469. #ifdef NEVER
  470. case ((int)KN_F3 | (int)KN_ALT_BIT): // quick load/save for debugging
  471. Debug_Threat = (Debug_Threat == false);
  472. Map.Flag_To_Redraw(true);
  473. break;
  474. #endif
  475. case KN_F3:
  476. Debug_Icon = (Debug_Icon == false);
  477. Map.Flag_To_Redraw(true);
  478. break;
  479. /*
  480. ** Reveal entire map to player.
  481. */
  482. case KN_F4:
  483. if (GameToPlay == GAME_NORMAL) {
  484. Debug_Unshroud = (Debug_Unshroud == false);
  485. Map.Flag_To_Redraw(true);
  486. }
  487. break;
  488. /*
  489. ** Shows sight and fire range in the form of circles emanating from the currently
  490. ** selected unit. The white circle is for sight range, the red circle is for
  491. ** fire range.
  492. */
  493. case KN_F7:
  494. if (CurrentObject.Count() && CurrentObject[0]->Is_Techno()) {
  495. TechnoTypeClass const & ttype = (TechnoTypeClass const &)CurrentObject[0]->Class_Of();
  496. int sight = ((int)ttype.SightRange)<<8;
  497. int weapon = 0;
  498. if (ttype.Primary != WEAPON_NONE) weapon = Weapons[ttype.Primary].Range;
  499. Set_Logic_Page(SeenBuff);
  500. COORDINATE center = CurrentObject[0]->Center_Coord();
  501. COORDINATE center2 = CurrentObject[0]->Fire_Coord(0);
  502. for (int r = 0; r < 255; r += 10) {
  503. int x,y,x1,y1;
  504. DirType r1 = (DirType)r;
  505. DirType r2 = (DirType)((r+10) & 0xFF);
  506. if (Map.Coord_To_Pixel(Coord_Move(center, r1, sight), x, y)) {
  507. Map.Coord_To_Pixel(Coord_Move(center, r2, sight), x1, y1);
  508. LogicPage->Draw_Line(x, y+8, x1, y1+8, WHITE);
  509. }
  510. if (Map.Coord_To_Pixel(Coord_Move(center2, r1, weapon), x, y)) {
  511. Map.Coord_To_Pixel(Coord_Move(center2, r2, weapon), x1, y1);
  512. LogicPage->Draw_Line(x, y+8, x1, y1+8, RED);
  513. }
  514. }
  515. }
  516. break;
  517. case ((int)KN_F4 | (int)KN_CTRL_BIT):
  518. Debug_Unshroud = (Debug_Unshroud == false);
  519. Map.Flag_To_Redraw(true);
  520. break;
  521. #ifdef NEVER
  522. case KN_F5:
  523. Special.IsShowPath = (Special.IsShowPath == false);
  524. //PlayerPtr->Credits += 1000;
  525. break;
  526. case KN_F6:
  527. if (Map.In_Radar(XY_Cell(Map.MapCellX+5, Map.MapCellY - 1))) {
  528. Mono_Printf("Arrrggggghhhhh!");
  529. } else {
  530. Mono_Printf("No Arrrggggghhhhh!");
  531. }
  532. break;
  533. case ((int)KN_F9 | (int)KN_CTRL_BIT):
  534. if (HouseClass::As_Pointer(HOUSE_GOOD))
  535. (HouseClass::As_Pointer(HOUSE_GOOD))->Blowup_All();
  536. break;
  537. case ((int)KN_F10 | (int)KN_CTRL_BIT):
  538. if (HouseClass::As_Pointer(HOUSE_BAD))
  539. (HouseClass::As_Pointer(HOUSE_BAD))->Blowup_All();
  540. break;
  541. #endif
  542. }
  543. }
  544. }
  545. /***********************************************************************************************
  546. * Self_Regulate -- Regulates the logic timer to result in smooth animation *
  547. * *
  548. * The self regulation process checks the number of frames displayed *
  549. * per second and from this determines the amount of time to devote *
  550. * to internal logic processing. By adjusting the time allotted to *
  551. * internal processing, smooth animation can be maintained. *
  552. * *
  553. * INPUT: none *
  554. * *
  555. * OUTPUT: none *
  556. * *
  557. * WARNINGS: In order for this routine to work properly it MUST be *
  558. * called every display loop. *
  559. * *
  560. * HISTORY: *
  561. * 07/31/1991 JLB : Created. *
  562. * 07/05/1994 JLB : Handles new monochrome system. *
  563. *=============================================================================================*/
  564. #define UPDATE_INTERVAL TIMER_SECOND
  565. void Self_Regulate(void)
  566. {
  567. static CountDownTimerClass DebugTimer(BT_SYSTEM);
  568. static ObjectClass * _lastobject = 0;
  569. if (!DebugTimer.Time()) {
  570. DebugTimer.Set(UPDATE_INTERVAL);
  571. if (MonoClass::Is_Enabled()) {
  572. MonoClass *mono = MonoClass::Get_Current();
  573. mono->Set_Default_Attribute(2);
  574. switch (MonoPage) {
  575. case 0:
  576. mono = &MonoArray[0];
  577. mono->Clear();
  578. /*
  579. ** Display the status of the currently selected object.
  580. */
  581. if (CurrentObject.Count()) {
  582. _lastobject = CurrentObject[0];
  583. }
  584. if (_lastobject && !_lastobject->IsActive) {
  585. _lastobject = 0;
  586. }
  587. if (_lastobject) {
  588. _lastobject->Debug_Dump(mono);
  589. }
  590. Logic.Debug_Dump(mono);
  591. mono->Set_Cursor(0, 20);
  592. mono->Printf(
  593. "Heap size:%10ld \r"
  594. "Largest: %10ld \r"
  595. "Ttl Free: %10ld \r"
  596. "Frag: %10ld \r",
  597. Heap_Size(MEM_NORMAL),
  598. Ram_Free(MEM_NORMAL),
  599. Total_Ram_Free(MEM_NORMAL),
  600. Total_Ram_Free(MEM_NORMAL)-Ram_Free(MEM_NORMAL)
  601. );
  602. *MonoClass::Get_Current() = *mono;
  603. break;
  604. }
  605. MonoArray[MonoPage] = *mono;
  606. }
  607. }
  608. }
  609. #endif