DEBUG.CPP 20 KB

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