mono.cpp 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587
  1. /*
  2. ** Command & Conquer Renegade(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. /***********************************************************************************************
  19. *** 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 ***
  20. ***********************************************************************************************
  21. * *
  22. * Project Name : Command & Conquer *
  23. * *
  24. * $Archive:: /G/wwlib/mono.cpp $*
  25. * *
  26. * $Author:: Neal_k $*
  27. * *
  28. * $Modtime:: 10/04/99 10:25a $*
  29. * *
  30. * $Revision:: 3 $*
  31. * *
  32. *---------------------------------------------------------------------------------------------*
  33. * Functions: *
  34. * MonoClass::Clear -- Clears the monochrome screen object. *
  35. * MonoClass::Draw_Box -- Draws a box using the IBM linedraw characters. *
  36. * MonoClass::Fill_Attrib -- Fill a block with specified attribute. *
  37. * MonoClass::MonoClass -- The default constructor for monochrome screen object. *
  38. * MonoClass::Pan -- Scroll the window right or left. *
  39. * MonoClass::Print -- Prints the text string at the current cursor coordinates. *
  40. * MonoClass::Print -- Simple print of text number. *
  41. * MonoClass::Printf -- Prints a formatted string to the monochrome screen. *
  42. * MonoClass::Printf -- Prints formatted text using text string number. *
  43. * MonoClass::Scroll -- Scroll the monochrome screen up by the specified lines. *
  44. * MonoClass::Set_Cursor -- Sets the monochrome cursor to the coordinates specified. *
  45. * MonoClass::Sub_Window -- Partitions the mono screen into a sub-window. *
  46. * MonoClass::Text_Print -- Prints text to the monochrome object at coordinates indicated. *
  47. * MonoClass::Text_Print -- Simple text printing from text number. *
  48. * MonoClass::View -- Brings the mono object to the main display. *
  49. * MonoClass::operator = -- Handles making one mono object have the same imagery as another. *
  50. * MonoClass::~MonoClass -- The default destructor for a monochrome screen object. *
  51. * Mono_Clear_Screen -- Clear the currently visible monochrome page. *
  52. * Mono_Draw_Rect -- Draws rectangle to monochrome screen. *
  53. * Mono_Print -- Prints simple text to monochrome screen. *
  54. * Mono_Printf -- Prints formatted text to visible page. *
  55. * Mono_Text_Print -- Prints text to location specified. *
  56. * Mono_X -- Fetches the X cursor position for current visible mono page. *
  57. * Mono_Y -- Fetches the Y cursor position for current mono page. *
  58. * MonoClass::Set_Default_Attribute -- Set the default attribute for this window. *
  59. * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  60. #include "always.h"
  61. #include "data.h"
  62. #include "mono.h"
  63. #include "monodrvr.h"
  64. #include <stdio.h>
  65. /*
  66. ** Global flag to indicate whether mono output is enabled. If it is not enabled,
  67. ** then no mono output will occur.
  68. */
  69. bool MonoClass::Enabled = false;
  70. /*
  71. ** This points to the current mono displayed screen.
  72. */
  73. MonoClass * MonoClass::Current;
  74. /***********************************************************************************************
  75. * MonoClass::MonoClass -- The default constructor for monochrome screen object. *
  76. * *
  77. * This is the constructor for monochrome screen objects. It handles allocating a free *
  78. * monochrome page. If there are no more pages available, then this is a big error. The *
  79. * page allocated may not be the visible one. Call the View function in order to bring *
  80. * it to the displayed page. *
  81. * *
  82. * INPUT: none *
  83. * *
  84. * OUTPUT: none *
  85. * *
  86. * WARNINGS: none *
  87. * *
  88. * HISTORY: *
  89. * 10/17/1994 JLB : Created. *
  90. * 01/06/1997 JLB : Updated to WindowsNT style of mono output. *
  91. *=============================================================================================*/
  92. MonoClass::MonoClass(void) :
  93. Handle(INVALID_HANDLE_VALUE)
  94. {
  95. #ifdef _WINDOWS
  96. Handle = CreateFile("\\\\.\\MONO", GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
  97. if (Current == NULL) {
  98. Current = this;
  99. }
  100. #endif
  101. }
  102. /***********************************************************************************************
  103. * MonoClass::~MonoClass -- The default destructor for a monochrome screen object. *
  104. * *
  105. * This is the default destructor for a monochrome screen object. *
  106. * *
  107. * INPUT: none *
  108. * *
  109. * OUTPUT: none *
  110. * *
  111. * WARNINGS: none *
  112. * *
  113. * HISTORY: *
  114. * 10/17/1994 JLB : Created. *
  115. * 01/06/1997 JLB : Updated to WindowsNT style of mono output. *
  116. *=============================================================================================*/
  117. MonoClass::~MonoClass(void)
  118. {
  119. #ifdef _WINDOWS
  120. if (Handle != INVALID_HANDLE_VALUE) {
  121. CloseHandle(Handle);
  122. Handle = INVALID_HANDLE_VALUE;
  123. }
  124. if (Current == this) {
  125. Current = NULL;
  126. }
  127. #endif
  128. }
  129. /***********************************************************************************************
  130. * MonoClass::Pan -- Scroll the window right or left. *
  131. * *
  132. * This routine will scroll the window to the right or left as indicated by the number of *
  133. * rows. *
  134. * *
  135. * INPUT: cols -- The number of columns to pan the window. Positive numbers pan to the left *
  136. * while negative numbers pan to the right. *
  137. * *
  138. * OUTPUT: none *
  139. * *
  140. * WARNINGS: none *
  141. * *
  142. * HISTORY: *
  143. * 06/05/1996 JLB : Created. *
  144. * 01/06/1997 JLB : Updated to WindowsNT style of mono output. *
  145. *=============================================================================================*/
  146. void MonoClass::Pan(int )
  147. {
  148. #ifdef _WINDOWS
  149. if ( Enabled && (Handle != INVALID_HANDLE_VALUE) ) {
  150. unsigned long retval;
  151. DeviceIoControl(Handle, (DWORD)IOCTL_MONO_PAN, NULL, 0, NULL, 0, &retval, 0);
  152. }
  153. #endif
  154. }
  155. /***********************************************************************************************
  156. * MonoClass::Sub_Window -- Partitions the mono screen into a sub-window. *
  157. * *
  158. * This routine is used to partition the monochrome screen so that only a sub-window will *
  159. * be processed. By using this, a separate rectangle of the screen can be cleared, *
  160. * scrolled, panned, or printed into. *
  161. * *
  162. * INPUT: x,y -- The upper left corner of the new sub-window. *
  163. * *
  164. * w,h -- Dimensions of the sub-window specified in characters. *
  165. * *
  166. * OUTPUT: none *
  167. * *
  168. * WARNINGS: The parameters are clipped as necessary. *
  169. * *
  170. * HISTORY: *
  171. * 06/05/1996 JLB : Created. *
  172. * 01/06/1997 JLB : Updated to WindowsNT style of mono output. *
  173. *=============================================================================================*/
  174. void MonoClass::Sub_Window(int x, int y, int w, int h)
  175. {
  176. #ifdef _WINDOWS
  177. if ( Enabled && (Handle != INVALID_HANDLE_VALUE) ) {
  178. struct subwindow {
  179. int X,Y,W,H;
  180. } subwindow;
  181. unsigned long retval;
  182. subwindow.X = x;
  183. subwindow.Y = y;
  184. subwindow.W = w;
  185. subwindow.H = h;
  186. DeviceIoControl(Handle, (DWORD)IOCTL_MONO_SET_WINDOW, &subwindow, sizeof(subwindow), NULL, 0, &retval, 0);
  187. }
  188. #endif
  189. }
  190. /***********************************************************************************************
  191. * MonoClass::Set_Cursor -- Sets the monochrome cursor to the coordinates specified. *
  192. * *
  193. * Use this routine to set the monochrome's cursor position to the coordinates specified. *
  194. * This is the normal way of controlling where the next Print or Printf will output the *
  195. * text to. *
  196. * *
  197. * INPUT: x,y -- The coordinate to position the monochrome cursor. 0,0 is the upper left *
  198. * corner. *
  199. * *
  200. * OUTPUT: none *
  201. * *
  202. * WARNINGS: none *
  203. * *
  204. * HISTORY: *
  205. * 10/17/1994 JLB : Created. *
  206. * 01/06/1997 JLB : Updated to WindowsNT style of mono output. *
  207. *=============================================================================================*/
  208. void MonoClass::Set_Cursor(int x, int y)
  209. {
  210. #ifdef _WINDOWS
  211. if ( Enabled && (Handle != INVALID_HANDLE_VALUE) ) {
  212. struct {
  213. int X,Y;
  214. } cursor;
  215. unsigned long retval;
  216. cursor.X = x;
  217. cursor.Y = y;
  218. DeviceIoControl(Handle, (DWORD)IOCTL_MONO_SET_CURSOR, &cursor, sizeof(cursor), NULL, 0, &retval, 0);
  219. }
  220. #endif
  221. }
  222. /***********************************************************************************************
  223. * MonoClass::Clear -- Clears the monochrome screen object. *
  224. * *
  225. * This routine will fill the monochrome screen object with spaces. It is clearing the *
  226. * screen of data, making it free for output. The cursor is positioned at the upper left *
  227. * corner of the screen by this routine. *
  228. * *
  229. * INPUT: none *
  230. * *
  231. * OUTPUT: none *
  232. * *
  233. * WARNINGS: none *
  234. * *
  235. * HISTORY: *
  236. * 10/17/1994 JLB : Created. *
  237. * 01/06/1997 JLB : Updated to WindowsNT style of mono output. *
  238. *=============================================================================================*/
  239. void MonoClass::Clear(void)
  240. {
  241. #ifdef _WINDOWS
  242. if ( Enabled && (Handle != INVALID_HANDLE_VALUE) ) {
  243. unsigned long retval;
  244. DeviceIoControl(Handle, (DWORD)IOCTL_MONO_CLEAR_SCREEN, NULL, 0, NULL, 0, &retval, 0);
  245. }
  246. #endif
  247. }
  248. /***********************************************************************************************
  249. * MonoClass::Fill_Attrib -- Fill a block with specified attribute. *
  250. * *
  251. * This routine will give the specified attribute to the characters within the block *
  252. * but will not change the characters themselves. You can use this routine to change the *
  253. * underline, blink, or inverse characteristics of text. *
  254. * *
  255. * INPUT: x,y -- The upper left coordinate of the region to change. *
  256. * *
  257. * w,h -- The dimensions of the region to change (in characters). *
  258. * *
  259. * attrib -- The attribute to fill into the region specified. *
  260. * *
  261. * OUTPUT: none *
  262. * *
  263. * WARNINGS: none *
  264. * *
  265. * HISTORY: *
  266. * 06/04/1996 JLB : Created. *
  267. * 01/06/1997 JLB : Updated to WindowsNT style of mono output. *
  268. *=============================================================================================*/
  269. void MonoClass::Fill_Attrib(int x, int y, int w, int h, MonoAttribute attrib)
  270. {
  271. #ifdef _WINDOWS
  272. if ( Enabled && (Handle != INVALID_HANDLE_VALUE) ) {
  273. unsigned long retval;
  274. struct fillcontrol {
  275. int X,Y,W,H,A;
  276. } fillcontrol;
  277. fillcontrol.X = x;
  278. fillcontrol.Y = y;
  279. fillcontrol.W = w;
  280. fillcontrol.H = h;
  281. fillcontrol.A = attrib;
  282. DeviceIoControl(Handle, (DWORD)IOCTL_MONO_FILL_ATTRIB, &fillcontrol, sizeof(fillcontrol), NULL, 0, &retval, 0);
  283. }
  284. #endif
  285. }
  286. /***********************************************************************************************
  287. * MonoClass::Scroll -- Scroll the monochrome screen up by the specified lines. *
  288. * *
  289. * Use this routine to scroll the monochrome screen up by the number of lines specified. *
  290. * This routine is typically called by the printing functions so that the monochrome screen *
  291. * behaves in the expected manner -- printing at the bottom of the screen scrolls it up *
  292. * to make room for new text. *
  293. * *
  294. * INPUT: lines -- The number of lines to scroll the monochrome screen. *
  295. * *
  296. * OUTPUT: none *
  297. * *
  298. * WARNINGS: none *
  299. * *
  300. * HISTORY: *
  301. * 10/17/1994 JLB : Created. *
  302. * 01/06/1997 JLB : Updated to WindowsNT style of mono output. *
  303. *=============================================================================================*/
  304. void MonoClass::Scroll(int )
  305. {
  306. #ifdef _WINDOWS
  307. if ( Enabled && (Handle != INVALID_HANDLE_VALUE) ) {
  308. unsigned long retval;
  309. DeviceIoControl(Handle, (DWORD)IOCTL_MONO_SCROLL, NULL, 0, NULL, 0, &retval, 0);
  310. }
  311. #endif
  312. }
  313. /***********************************************************************************************
  314. * MonoClass::Printf -- Prints a formatted string to the monochrome screen. *
  315. * *
  316. * Use this routine to output a formatted string, using the standard formatting options, *
  317. * to the monochrome screen object's current cursor position. *
  318. * *
  319. * INPUT: text -- Pointer to the text to print. *
  320. * *
  321. * ... -- Any optional parameters to supply in formatting the text. *
  322. * *
  323. * OUTPUT: none *
  324. * *
  325. * WARNINGS: The total formatted text length must not exceed 255 characters. *
  326. * *
  327. * HISTORY: *
  328. * 10/17/1994 JLB : Created. *
  329. *=============================================================================================*/
  330. void MonoClass::Printf(char const *text, ...)
  331. {
  332. #ifdef _WINDOWS
  333. va_list va;
  334. /*
  335. ** The buffer object is placed at the end of the local variable list
  336. ** so that if the sprintf happens to spill past the end, it isn't likely
  337. ** to trash anything (important). The buffer is then manually truncated
  338. ** to maximum allowed size before being printed.
  339. */
  340. char buffer[256];
  341. if ( !Enabled || (Handle == INVALID_HANDLE_VALUE) ) return;
  342. va_start(va, text);
  343. vsprintf(buffer, text, va);
  344. buffer[sizeof(buffer)-1] = '\0';
  345. Print(buffer);
  346. va_end(va);
  347. #endif
  348. }
  349. /***********************************************************************************************
  350. * MonoClass::Printf -- Prints formatted text using text string number. *
  351. * *
  352. * This routine will take the given text string number and print the formatted text to *
  353. * the monochrome screen. *
  354. * *
  355. * INPUT: text -- The text number to convert into real text (by way of external function). *
  356. * *
  357. * ... -- Additional parameters as needed. *
  358. * *
  359. * OUTPUT: none *
  360. * *
  361. * WARNINGS: none *
  362. * *
  363. * HISTORY: *
  364. * 06/04/1996 JLB : Created. *
  365. *=============================================================================================*/
  366. void MonoClass::Printf(int text, ...)
  367. {
  368. #ifdef _WINDOWS
  369. va_list va;
  370. /*
  371. ** The buffer object is placed at the end of the local variable list
  372. ** so that if the sprintf happens to spill past the end, it isn't likely
  373. ** to trash anything (important). The buffer is then manually truncated
  374. ** to maximum allowed size before being printed.
  375. */
  376. char buffer[256];
  377. if ( !Enabled || (Handle == INVALID_HANDLE_VALUE) ) return;
  378. va_start(va, text);
  379. vsprintf(buffer, Fetch_String(text), va);
  380. buffer[sizeof(buffer)-1] = '\0';
  381. Print(buffer);
  382. va_end(va);
  383. #endif
  384. }
  385. /***********************************************************************************************
  386. * MonoClass::Print -- Prints the text string at the current cursor coordinates. *
  387. * *
  388. * Use this routine to output the specified text string at the monochrome object's current *
  389. * text coordinate position. *
  390. * *
  391. * INPUT: ptr -- Pointer to the string to print. *
  392. * *
  393. * OUTPUT: none *
  394. * *
  395. * WARNINGS: none *
  396. * *
  397. * HISTORY: *
  398. * 10/17/1994 JLB : Created. *
  399. * 01/06/1997 JLB : Updated to WindowsNT style of mono output. *
  400. *=============================================================================================*/
  401. void MonoClass::Print(char const * ptr)
  402. {
  403. #ifdef _WINDOWS
  404. if ( Enabled && (Handle != INVALID_HANDLE_VALUE) ) {
  405. unsigned long retval;
  406. WriteFile(Handle, ptr, strlen(ptr), &retval, NULL);
  407. }
  408. #endif
  409. }
  410. /***********************************************************************************************
  411. * MonoClass::Set_Default_Attribute -- Set the default attribute for this window. *
  412. * *
  413. * This will change the default attribute to that specified. All future text will use *
  414. * this new attribute. *
  415. * *
  416. * INPUT: attrib -- The attribute to make the current default. *
  417. * *
  418. * OUTPUT: none *
  419. * *
  420. * WARNINGS: none *
  421. * *
  422. * HISTORY: *
  423. * 01/06/1997 JLB : Created. *
  424. *=============================================================================================*/
  425. void MonoClass::Set_Default_Attribute(MonoAttribute attrib)
  426. {
  427. #ifdef _WINDOWS
  428. if ( Enabled && (Handle != INVALID_HANDLE_VALUE) ) {
  429. unsigned long retval;
  430. DeviceIoControl(Handle, (DWORD)IOCTL_MONO_SET_ATTRIBUTE, &attrib, 1, NULL, 0, &retval, 0);
  431. }
  432. #endif
  433. }
  434. /***********************************************************************************************
  435. * MonoClass::Text_Print -- Prints text to the monochrome object at coordinates indicated. *
  436. * *
  437. * Use this routine to output text to the monochrome object at the X and Y coordinates *
  438. * specified. *
  439. * *
  440. * INPUT: text -- Pointer to the text string to display. *
  441. * *
  442. * x,y -- The X and Y character coordinates to start the printing at. *
  443. * *
  444. * attrib-- Optional parameter that specifies what text attribute code to use. *
  445. * *
  446. * OUTPUT: none *
  447. * *
  448. * WARNINGS: none *
  449. * *
  450. * HISTORY: *
  451. * 10/17/1994 JLB : Created. *
  452. * 01/06/1997 JLB : Updated to WindowsNT style of mono output. *
  453. *=============================================================================================*/
  454. void MonoClass::Text_Print(char const *text, int x, int y, MonoAttribute attrib)
  455. {
  456. #ifdef _WINDOWS
  457. if ( Enabled && (Handle != INVALID_HANDLE_VALUE) ) {
  458. unsigned long retval;
  459. Set_Cursor(x, y);
  460. DeviceIoControl(Handle, (DWORD)IOCTL_MONO_SET_ATTRIBUTE, &attrib, 1, NULL, 0, &retval, 0);
  461. Print(text);
  462. }
  463. #endif
  464. }
  465. /***********************************************************************************************
  466. * MonoClass::Text_Print -- Simple text printing from text number. *
  467. * *
  468. * This will print the text (represented by the text number) to the location on the *
  469. * monochrome screen specified. *
  470. * *
  471. * INPUT: text -- The text number to print (converted to real text by external routine). *
  472. * *
  473. * x,y -- The coordinates to begin the printing at. *
  474. * *
  475. * attrib-- The character attribute to use while printing. *
  476. * *
  477. * OUTPUT: none *
  478. * *
  479. * WARNINGS: none *
  480. * *
  481. * HISTORY: *
  482. * 06/04/1996 JLB : Created. *
  483. *=============================================================================================*/
  484. void MonoClass::Text_Print(int text, int x, int y, MonoAttribute attrib)
  485. {
  486. Text_Print(Fetch_String(text), x, y, attrib);
  487. }
  488. /***********************************************************************************************
  489. * MonoClass::Print -- Simple print of text number. *
  490. * *
  491. * Prints text represented by the text number specified. *
  492. * *
  493. * INPUT: text -- The text number to print (converted to real text by external routine). *
  494. * *
  495. * OUTPUT: none *
  496. * *
  497. * WARNINGS: none *
  498. * *
  499. * HISTORY: *
  500. * 06/04/1996 JLB : Created. *
  501. *=============================================================================================*/
  502. void MonoClass::Print(int text)
  503. {
  504. Print(Fetch_String(text));
  505. }
  506. /***********************************************************************************************
  507. * MonoClass::View -- Brings the mono object to the main display. *
  508. * *
  509. * Use this routine to display the mono object on the monochrome screen. It is possible *
  510. * that the mono object exists on some background screen memory. Calling this routine will *
  511. * perform the necessary memory swapping to bring the data to the front. The mono object *
  512. * that was currently being viewed is not destroyed by this function. It is merely moved *
  513. * off to some background page. It can be treated normally, except that is just isn't *
  514. * visible. *
  515. * *
  516. * INPUT: none *
  517. * *
  518. * OUTPUT: none *
  519. * *
  520. * WARNINGS: none *
  521. * *
  522. * HISTORY: *
  523. * 10/17/1994 JLB : Created. *
  524. * 01/06/1997 JLB : Updated to WindowsNT style of mono output. *
  525. *=============================================================================================*/
  526. void MonoClass::View(void)
  527. {
  528. #ifdef _WINDOWS
  529. if ( Enabled && (Handle != INVALID_HANDLE_VALUE) ) {
  530. unsigned long retval;
  531. DeviceIoControl(Handle, (DWORD)IOCTL_MONO_BRING_TO_TOP, NULL, 0, NULL, 0, &retval, 0);
  532. Current = this;
  533. }
  534. #endif
  535. }