MONOC.CPP 56 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132
  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: /CounterStrike/MONOC.CPP 1 3/03/97 10:25a 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 : MONO.CPP *
  26. * *
  27. * Programmer : Joe L. Bostic *
  28. * *
  29. * Start Date : July 2, 1994 *
  30. * *
  31. * Last Update : June 5, 1996 [JLB] *
  32. * *
  33. *---------------------------------------------------------------------------------------------*
  34. * Functions: *
  35. * MonoClass::Clear -- Clears the monochrome screen object. *
  36. * MonoClass::Draw_Box -- Draws a box using the IBM linedraw characters. *
  37. * MonoClass::Fill_Attrib -- Fill a block with specified attribute. *
  38. * MonoClass::MonoClass -- The default constructor for monochrome screen object. *
  39. * MonoClass::Pan -- Scroll the window right or left. *
  40. * MonoClass::Print -- Prints the text string at the current cursor coordinates. *
  41. * MonoClass::Print -- Simple print of text number. *
  42. * MonoClass::Printf -- Prints a formatted string to the monochrome screen. *
  43. * MonoClass::Printf -- Prints formatted text using text string number. *
  44. * MonoClass::Scroll -- Scroll the monochrome screen up by the specified lines. *
  45. * MonoClass::Set_Cursor -- Sets the monochrome cursor to the coordinates specified. *
  46. * MonoClass::Sub_Window -- Partitions the mono screen into a sub-window. *
  47. * MonoClass::Text_Print -- Prints text to the monochrome object at coordinates indicated. *
  48. * MonoClass::Text_Print -- Simple text printing from text number. *
  49. * MonoClass::View -- Brings the mono object to the main display. *
  50. * MonoClass::operator = -- Handles making one mono object have the same imagery as another. *
  51. * MonoClass::~MonoClass -- The default destructor for a monochrome screen object. *
  52. * Mono_Clear_Screen -- Clear the currently visible monochrome page. *
  53. * Mono_Draw_Rect -- Draws rectangle to monochrome screen. *
  54. * Mono_Print -- Prints simple text to monochrome screen. *
  55. * Mono_Printf -- Prints formatted text to visible page. *
  56. * Mono_Text_Print -- Prints text to location specified. *
  57. * Mono_X -- Fetches the X cursor position for current visible mono page. *
  58. * Mono_Y -- Fetches the Y cursor position for current mono page. *
  59. * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  60. //#include "watcom.h"
  61. #include "monoc.h"
  62. #include "function.h"
  63. #include <stdlib.h>
  64. #include <stdio.h>
  65. #include <dos.h>
  66. #include <mem.h>
  67. #include <stdarg.h>
  68. #include <string.h>
  69. extern void output(short port, short data);
  70. #pragma aux output parm [dx] [ax] = \
  71. "out dx,al" \
  72. "inc dx" \
  73. "mov al,ah" \
  74. "out dx,al"
  75. bool MonoClass::Enabled = 0;
  76. MonoClass * MonoClass::PageUsage[MonoClass::MAX_MONO_PAGES];
  77. //MonoClass::MonoPageType * MonoClass::MonoRAM = (MonoClass::MonoPageType *) 0xB0000;
  78. /*
  79. ** These are the IBM linedraw characters.
  80. */
  81. MonoClass::BoxDataType const MonoClass::CharData[MonoClass::COUNT] = {
  82. {0xDA,0xC4,0xBF,0xB3,0xD9,0xC4,0xC0,0xB3}, // Single line
  83. {0xD5,0xCD,0xB8,0xB3,0xBE,0xCD,0xD4,0xB3}, // Double horz.
  84. {0xD6,0xC4,0xB7,0xBA,0xBD,0xC4,0xD3,0xBA}, // Double vert.
  85. {0xC9,0xCD,0xBB,0xBA,0xBC,0xCD,0xC8,0xBA} // Double horz and vert.
  86. };
  87. #ifdef NEVER
  88. template<class T>
  89. T min(T a, T b) {
  90. if (a < b) return(a);
  91. return(b);
  92. }
  93. template<class T>
  94. T max(T a, T b) {
  95. if (a > b) return(a);
  96. return(b);
  97. }
  98. #endif
  99. /***********************************************************************************************
  100. * MonoClass::MonoClass -- The default constructor for monochrome screen object. *
  101. * *
  102. * This is the constructor for monochrome screen objects. It handles allocating a free *
  103. * monochrome page. If there are no more pages available, then this is a big error. The *
  104. * page allocated may not be the visible one. Call the View function in order to bring *
  105. * it to the displayed page. *
  106. * *
  107. * INPUT: none *
  108. * *
  109. * OUTPUT: none *
  110. * *
  111. * WARNINGS: none *
  112. * *
  113. * HISTORY: *
  114. * 10/17/1994 JLB : Created. *
  115. *=============================================================================================*/
  116. MonoClass::MonoClass(void) :
  117. X(0),
  118. Y(0),
  119. Attrib(NORMAL),
  120. Page(0),
  121. SubX(0),
  122. SubY(0),
  123. SubW(COLUMNS),
  124. SubH(LINES)
  125. {
  126. int index;
  127. for (index = 0; index < MAX_MONO_PAGES; index++) {
  128. if (!PageUsage[index]) {
  129. PageUsage[index] = this;
  130. Page = (char)index;
  131. break;
  132. }
  133. }
  134. if (index == MAX_MONO_PAGES) {
  135. // Major error message should pop up here!
  136. delete this;
  137. }
  138. }
  139. /***********************************************************************************************
  140. * MonoClass::~MonoClass -- The default destructor for a monochrome screen object. *
  141. * *
  142. * This is the default destructor for a monochrome screen object. *
  143. * *
  144. * INPUT: none *
  145. * *
  146. * OUTPUT: none *
  147. * *
  148. * WARNINGS: none *
  149. * *
  150. * HISTORY: *
  151. * 10/17/1994 JLB : Created. *
  152. *=============================================================================================*/
  153. MonoClass::~MonoClass(void)
  154. {
  155. PageUsage[Page] = 0;
  156. }
  157. /***********************************************************************************************
  158. * MonoClass::Pan -- Scroll the window right or left. *
  159. * *
  160. * This routine will scroll the window to the right or left as indicated by the number of *
  161. * rows. *
  162. * *
  163. * INPUT: cols -- The number of columns to pan the window. Positive numbers pan to the left *
  164. * while negative numbers pan to the right. *
  165. * *
  166. * OUTPUT: none *
  167. * *
  168. * WARNINGS: none *
  169. * *
  170. * HISTORY: *
  171. * 06/05/1996 JLB : Created. *
  172. *=============================================================================================*/
  173. void MonoClass::Pan(int cols)
  174. {
  175. if (cols == 0) return;
  176. if (abs(cols) >= SubW) {
  177. Clear();
  178. return;
  179. }
  180. CellType cell;
  181. cell.Character = ' ';
  182. cell.Attribute = Attrib;
  183. if (cols > 0) {
  184. for (int index = SubY; index < SubY+SubH; index++) {
  185. memmove(&Page_Ptr()->Data[index][SubX], &Page_Ptr()->Data[index][SubX+cols], sizeof(CellType)*(SubW-cols));
  186. for (int cc = SubX+SubW-cols; cc < SubX+SubW; cc++) {
  187. Page_Ptr()->Data[index][cc] = cell;
  188. }
  189. }
  190. } else {
  191. for (int index = SubY; index < SubY+SubH; index++) {
  192. memmove(&Page_Ptr()->Data[index][SubX-cols], &Page_Ptr()->Data[index][SubX], sizeof(CellType)*(SubW+cols));
  193. for (int cc = SubX; cc < SubX-cols; cc++) {
  194. Page_Ptr()->Data[index][cc] = cell;
  195. }
  196. }
  197. }
  198. Set_Cursor(X-cols, Y);
  199. }
  200. /***********************************************************************************************
  201. * MonoClass::Sub_Window -- Partitions the mono screen into a sub-window. *
  202. * *
  203. * This routine is used to partition the monochrome screen so that only a sub-window will *
  204. * be processed. By using this, a separate rectangle of the screen can be cleared, *
  205. * scrolled, panned, or printed into. *
  206. * *
  207. * INPUT: x,y -- The upper left corner of the new sub-window. *
  208. * *
  209. * w,h -- Dimensions of the sub-window specified in characters. *
  210. * *
  211. * OUTPUT: none *
  212. * *
  213. * WARNINGS: The parameters are clipped as necessary. *
  214. * *
  215. * HISTORY: *
  216. * 06/05/1996 JLB : Created. *
  217. *=============================================================================================*/
  218. void MonoClass::Sub_Window(int x, int y, int w, int h)
  219. {
  220. /*
  221. ** Undo any sub window adjustments to the cursor position.
  222. */
  223. X += SubX;
  224. Y += SubY;
  225. /*
  226. ** Ensure parameters are legal.
  227. */
  228. x = min(x, COLUMNS-1);
  229. x = max(x, 0);
  230. y = min(y, LINES-1);
  231. y = max(y, 0);
  232. if (w == -1) w = COLUMNS-x;
  233. if (h == -1) h = LINES-y;
  234. /*
  235. ** Assign the new sub-region.
  236. */
  237. SubX = x;
  238. SubY = y;
  239. SubW = w;
  240. SubH = h;
  241. /*
  242. ** Move the cursor (if necessary) so that it falls within that region.
  243. */
  244. int xx = X;
  245. int yy = Y;
  246. xx = min(xx, SubX+SubW-1);
  247. xx = max(xx, SubX);
  248. yy = min(yy, SubY+SubH-1);
  249. yy = max(yy, SubY);
  250. Set_Cursor(xx-SubX, yy-SubY);
  251. }
  252. /***********************************************************************************************
  253. * MonoClass::Draw_Box -- Draws a box using the IBM linedraw characters. *
  254. * *
  255. * Use this routine to draw a box to the monochrome screen. The IBM line draw characters *
  256. * are used to give the it a fancy appearance. There are several line draw modes supported. *
  257. * *
  258. * INPUT: x,y -- The coordinates of the upper left corner of the box. *
  259. * *
  260. * w,y -- The width and height (respectively) to make the box. *
  261. * *
  262. * attrib -- The text attribute to use when drawing the box outline characters. *
  263. * *
  264. * thick -- The thickness style to use. Examine the BoxStyleType enum for *
  265. * elaboration on the supported styles. *
  266. * *
  267. * OUTPUT: none *
  268. * *
  269. * WARNINGS: The interior of the box is NOT cleared by this routine. It is advised that this *
  270. * area be cleared before the box is drawn. *
  271. * *
  272. * HISTORY: *
  273. * 10/17/1994 JLB : Created. *
  274. *=============================================================================================*/
  275. void MonoClass::Draw_Box(int x, int y, int w, int h, MonoAttribute attrib, BoxStyleType thick)
  276. {
  277. CellType cell;
  278. MonoAttribute oldattrib = Attrib;
  279. if (!Enabled || !w || !h) return;
  280. x = min(x, SubW);
  281. x = max(x, 0);
  282. y = min(y, SubH);
  283. y = max(y, 0);
  284. w = min(w, SubW-x);
  285. w = max(w, 1);
  286. h = min(h, SubH-y);
  287. h = max(h, 1);
  288. x += SubX;
  289. y += SubY;
  290. cell.Attribute = attrib;
  291. /*
  292. ** Draw the horizontal lines.
  293. */
  294. for (int xpos = 0; xpos < w-2; xpos++) {
  295. cell.Character = CharData[thick].TopEdge;
  296. Page_Ptr()->Data[y][x+xpos+1] = cell;
  297. cell.Character = CharData[thick].BottomEdge;
  298. Page_Ptr()->Data[y+h-1][x+xpos+1] = cell;
  299. }
  300. /*
  301. ** Draw the vertical lines.
  302. */
  303. for (int ypos = 0; ypos < h-2; ypos++) {
  304. cell.Character = CharData[thick].LeftEdge;
  305. Page_Ptr()->Data[y+ypos+1][x] = cell;
  306. cell.Character = CharData[thick].RightEdge;
  307. Page_Ptr()->Data[y+ypos+1][x+w-1] = cell;
  308. }
  309. /*
  310. ** Draw the four corners.
  311. */
  312. if (w > 1 && h > 1) {
  313. cell.Character = CharData[thick].UpperLeft;
  314. Page_Ptr()->Data[y][x] = cell;
  315. cell.Character = CharData[thick].UpperRight;
  316. Page_Ptr()->Data[y][x+w-1] = cell;
  317. cell.Character = CharData[thick].BottomRight;
  318. Page_Ptr()->Data[y+h-1][x+w-1] = cell;
  319. cell.Character = CharData[thick].BottomLeft;
  320. Page_Ptr()->Data[y+h-1][x] = cell;
  321. }
  322. Attrib = oldattrib;
  323. }
  324. /***********************************************************************************************
  325. * MonoClass::Set_Cursor -- Sets the monochrome cursor to the coordinates specified. *
  326. * *
  327. * Use this routine to set the monochrome's cursor position to the coordinates specified. *
  328. * This is the normal way of controlling where the next Print or Printf will output the *
  329. * text to. *
  330. * *
  331. * INPUT: x,y -- The coordinate to position the monochrome cursor. 0,0 is the upper left *
  332. * corner. *
  333. * *
  334. * OUTPUT: none *
  335. * *
  336. * WARNINGS: none *
  337. * *
  338. * HISTORY: *
  339. * 10/17/1994 JLB : Created. *
  340. *=============================================================================================*/
  341. void MonoClass::Set_Cursor(int x, int y)
  342. {
  343. x = min(x, SubW);
  344. x = max(x, 0);
  345. y = min(y, SubH);
  346. y = max(y, 0);
  347. X = x;
  348. Y = y;
  349. if (!Enabled) return;
  350. /*
  351. ** Update the visible cursor position only if the this mono page is the currently
  352. ** visible one.
  353. */
  354. int pos = ((y+SubY)*COLUMNS)+(x+SubX);
  355. if (Page == 0) {
  356. output(CONTROL_PORT, (short)(0x0E|(pos&0xFF00)));
  357. output(CONTROL_PORT, (short)(0x0F|(pos<<8)));
  358. }
  359. }
  360. /***********************************************************************************************
  361. * MonoClass::Clear -- Clears the monochrome screen object. *
  362. * *
  363. * This routine will fill the monochrome screen object with spaces. It is clearing the *
  364. * screen of data, making it free for output. The cursor is positioned at the upper left *
  365. * corner of the screen by this routine. *
  366. * *
  367. * INPUT: none *
  368. * *
  369. * OUTPUT: none *
  370. * *
  371. * WARNINGS: none *
  372. * *
  373. * HISTORY: *
  374. * 10/17/1994 JLB : Created. *
  375. *=============================================================================================*/
  376. void MonoClass::Clear(void)
  377. {
  378. if (!Enabled) return;
  379. Set_Cursor(0, 0);
  380. CellType cell;
  381. cell.Attribute = Attrib;
  382. cell.Character = ' ';
  383. for (int rows = 0; rows < SubH; rows++) {
  384. for (int cols = 0; cols < SubW; cols++) {
  385. Page_Ptr()->Data[rows+SubX][cols+SubY] = cell;
  386. }
  387. }
  388. }
  389. /***********************************************************************************************
  390. * MonoClass::Fill_Attrib -- Fill a block with specified attribute. *
  391. * *
  392. * This routine will give the specified attribute to the characters within the block *
  393. * but will not change the characters themselves. You can use this routine to change the *
  394. * underline, blink, or inverse characteristics of text. *
  395. * *
  396. * INPUT: x,y -- The upper left coordinate of the region to change. *
  397. * *
  398. * w,h -- The dimensions of the region to change (in characters). *
  399. * *
  400. * attrib -- The attribute to fill into the region specified. *
  401. * *
  402. * OUTPUT: none *
  403. * *
  404. * WARNINGS: none *
  405. * *
  406. * HISTORY: *
  407. * 06/04/1996 JLB : Created. *
  408. *=============================================================================================*/
  409. void MonoClass::Fill_Attrib(int x, int y, int w, int h, MonoAttribute attrib)
  410. {
  411. if (!w || !h || (unsigned)x >= SubW || (unsigned)h >= SubH || (unsigned)x+w > SubW || (unsigned)y+h > SubH) return;
  412. for (int rows = y; rows < y+h; rows++) {
  413. for (int cols = x; cols < x+w; cols++) {
  414. Page_Ptr()->Data[rows+SubY][cols+SubX].Attribute = attrib;
  415. }
  416. }
  417. }
  418. /***********************************************************************************************
  419. * MonoClass::Scroll -- Scroll the monochrome screen up by the specified lines. *
  420. * *
  421. * Use this routine to scroll the monochrome screen up by the number of lines specified. *
  422. * This routine is typically called by the printing functions so that the monochrome screen *
  423. * behaves in the expected manner -- printing at the bottom of the screen scrolls it up *
  424. * to make room for new text. *
  425. * *
  426. * INPUT: lines -- The number of lines to scroll the monochrome screen. *
  427. * *
  428. * OUTPUT: none *
  429. * *
  430. * WARNINGS: none *
  431. * *
  432. * HISTORY: *
  433. * 10/17/1994 JLB : Created. *
  434. *=============================================================================================*/
  435. void MonoClass::Scroll(int lines)
  436. {
  437. if (!Enabled || lines <= 0) return;
  438. if (abs(lines) >= SubH) {
  439. Clear();
  440. return;
  441. }
  442. CellType cell;
  443. cell.Attribute = Attrib;
  444. cell.Character = ' ';
  445. if (lines > 0) {
  446. for (int row = 0; row < SubH-lines; row++) {
  447. memmove(&Page_Ptr()->Data[SubY+row][SubX], &Page_Ptr()->Data[SubY+row+1][SubX], SubW*sizeof(CellType));
  448. }
  449. for (int frow = SubH-lines; frow < SubH; frow++) {
  450. for (int cc = 0; cc < SubW; cc++) {
  451. Page_Ptr()->Data[SubY+frow][SubX+cc] = cell;
  452. }
  453. }
  454. } else {
  455. for (int row = SubH-1; row >= -lines; row--) {
  456. memmove(&Page_Ptr()->Data[SubY+row][SubX], &Page_Ptr()->Data[SubY+row-1][SubX], SubW*sizeof(CellType));
  457. }
  458. for (int frow = 0; frow < -lines; frow++) {
  459. for (int cc = 0; cc < SubW; cc++) {
  460. Page_Ptr()->Data[SubY+frow][SubX+cc] = cell;
  461. }
  462. }
  463. }
  464. Set_Cursor(X, Y-lines);
  465. }
  466. /***********************************************************************************************
  467. * MonoClass::Printf -- Prints a formatted string to the monochrome screen. *
  468. * *
  469. * Use this routine to output a formatted string, using the standard formatting options, *
  470. * to the monochrome screen object's current cursor position. *
  471. * *
  472. * INPUT: text -- Pointer to the text to print. *
  473. * *
  474. * ... -- Any optional parameters to supply in formatting the text. *
  475. * *
  476. * OUTPUT: none *
  477. * *
  478. * WARNINGS: The total formatted text length must not exceed 255 characters. *
  479. * *
  480. * HISTORY: *
  481. * 10/17/1994 JLB : Created. *
  482. *=============================================================================================*/
  483. void MonoClass::Printf(char const *text, ...)
  484. {
  485. va_list va;
  486. /*
  487. ** The buffer object is placed at the end of the local variable list
  488. ** so that if the sprintf happens to spill past the end, it isn't likely
  489. ** to trash anything (important). The buffer is then manually truncated
  490. ** to maximum allowed size before being printed.
  491. */
  492. char buffer[256];
  493. if (!Enabled) return;
  494. va_start(va, text);
  495. vsprintf(buffer, text, va);
  496. buffer[sizeof(buffer)-1] = '\0';
  497. Print(buffer);
  498. va_end(va);
  499. }
  500. /***********************************************************************************************
  501. * MonoClass::Printf -- Prints formatted text using text string number. *
  502. * *
  503. * This routine will take the given text string number and print the formatted text to *
  504. * the monochrome screen. *
  505. * *
  506. * INPUT: text -- The text number to convert into real text (by way of external function). *
  507. * *
  508. * ... -- Additional parameters as needed. *
  509. * *
  510. * OUTPUT: none *
  511. * *
  512. * WARNINGS: none *
  513. * *
  514. * HISTORY: *
  515. * 06/04/1996 JLB : Created. *
  516. *=============================================================================================*/
  517. void MonoClass::Printf(int text, ...)
  518. {
  519. va_list va;
  520. /*
  521. ** The buffer object is placed at the end of the local variable list
  522. ** so that if the sprintf happens to spill past the end, it isn't likely
  523. ** to trash anything (important). The buffer is then manually truncated
  524. ** to maximum allowed size before being printed.
  525. */
  526. char buffer[256];
  527. if (!Enabled) return;
  528. va_start(va, text);
  529. vsprintf(buffer, Text_String(text), va);
  530. buffer[sizeof(buffer)-1] = '\0';
  531. Print(buffer);
  532. va_end(va);
  533. }
  534. /***********************************************************************************************
  535. * MonoClass::Print -- Prints the text string at the current cursor coordinates. *
  536. * *
  537. * Use this routine to output the specified text string at the monochrome object's current *
  538. * text coordinate position. *
  539. * *
  540. * INPUT: ptr -- Pointer to the string to print. *
  541. * *
  542. * OUTPUT: none *
  543. * *
  544. * WARNINGS: none *
  545. * *
  546. * HISTORY: *
  547. * 10/17/1994 JLB : Created. *
  548. *=============================================================================================*/
  549. void MonoClass::Print(char const * ptr)
  550. {
  551. int startcol = X;
  552. char const * text;
  553. CellType cell;
  554. if (!ptr || !Enabled) return;
  555. text = ptr;
  556. cell.Attribute = Attrib;
  557. while (*text) {
  558. cell.Character = *text;
  559. /*
  560. ** Sometimes the character string is used for cursor control instead
  561. ** of plain text output. Check for this case.
  562. */
  563. switch (cell.Character) {
  564. /*
  565. ** The "return" code behaves as it did in the old C library
  566. ** mono system. That is, it returns the cursor position to
  567. ** the next line but at the starting column of the print.
  568. */
  569. case '\r':
  570. if (Y == SubH-1) {
  571. Scroll(1);
  572. }
  573. Set_Cursor(startcol, Y+1);
  574. break;
  575. /*
  576. ** The TAB character is not currently handled. Convert it to
  577. ** a space instead.
  578. */
  579. case '\t':
  580. cell.Character = ' ';
  581. // fall into normal print case.
  582. /*
  583. ** All other characters are output directly and the cursor moves
  584. ** rightward to match. If the cursor wraps past the right
  585. ** edge it is moved to the next now down at left margin. If the
  586. ** cursor goes off the bottom of the display, the display is scrolled
  587. ** upward a line.
  588. */
  589. default:
  590. Page_Ptr()->Data[SubY+Y][SubX+X] = cell;
  591. if (X < SubW-1) {
  592. Set_Cursor(X+1, Y);
  593. break;
  594. }
  595. // Fall into newline case.
  596. /*
  597. ** The "newline" code behaves like the console newline character.
  598. ** That is, it moves the cursor down one line and at the first
  599. ** column.
  600. */
  601. case '\n':
  602. if (Y == SubH-1) {
  603. Scroll(1);
  604. }
  605. Set_Cursor(0, Y+1);
  606. break;
  607. }
  608. text++;
  609. }
  610. }
  611. /***********************************************************************************************
  612. * MonoClass::Text_Print -- Prints text to the monochrome object at coordinates indicated. *
  613. * *
  614. * Use this routine to output text to the monochrome object at the X and Y coordinates *
  615. * specified. *
  616. * *
  617. * INPUT: text -- Pointer to the text string to display. *
  618. * *
  619. * x,y -- The X and Y character coordinates to start the printing at. *
  620. * *
  621. * attrib-- Optional parameter that specifies what text attribute code to use. *
  622. * *
  623. * OUTPUT: none *
  624. * *
  625. * WARNINGS: none *
  626. * *
  627. * HISTORY: *
  628. * 10/17/1994 JLB : Created. *
  629. *=============================================================================================*/
  630. void MonoClass::Text_Print(char const *text, int x, int y, MonoAttribute attrib)
  631. {
  632. int oldx = X;
  633. int oldy = Y;
  634. MonoAttribute oldattrib = Attrib;
  635. X = (char)x;
  636. Y = (char)y;
  637. Attrib = attrib;
  638. Print(text);
  639. Attrib = oldattrib;
  640. Set_Cursor(oldx, oldy);
  641. }
  642. /***********************************************************************************************
  643. * MonoClass::Text_Print -- Simple text printing from text number. *
  644. * *
  645. * This will print the text (represented by the text number) to the location on the *
  646. * monochrome screen specified. *
  647. * *
  648. * INPUT: text -- The text number to print (converted to real text by external routine). *
  649. * *
  650. * x,y -- The coordinates to begin the printing at. *
  651. * *
  652. * attrib-- The character attribute to use while printing. *
  653. * *
  654. * OUTPUT: none *
  655. * *
  656. * WARNINGS: none *
  657. * *
  658. * HISTORY: *
  659. * 06/04/1996 JLB : Created. *
  660. *=============================================================================================*/
  661. void MonoClass::Text_Print(int text, int x, int y, MonoAttribute attrib)
  662. {
  663. int oldx = X;
  664. int oldy = Y;
  665. MonoAttribute oldattrib = Attrib;
  666. if (text != 0) {
  667. X = (char)x;
  668. Y = (char)y;
  669. Attrib = attrib;
  670. Print(Text_String(text));
  671. Attrib = oldattrib;
  672. Set_Cursor(oldx, oldy);
  673. }
  674. }
  675. /***********************************************************************************************
  676. * MonoClass::Print -- Simple print of text number. *
  677. * *
  678. * Prints text represented by the text number specified. *
  679. * *
  680. * INPUT: text -- The text number to print (converted to real text by external routine). *
  681. * *
  682. * OUTPUT: none *
  683. * *
  684. * WARNINGS: none *
  685. * *
  686. * HISTORY: *
  687. * 06/04/1996 JLB : Created. *
  688. *=============================================================================================*/
  689. void MonoClass::Print(int text)
  690. {
  691. Print(Text_String(text));
  692. }
  693. /***********************************************************************************************
  694. * MonoClass::operator = -- Handles making one mono object have the same imagery as another. *
  695. * *
  696. * The assignment operator will handle copying the imagery from one monochrome object to *
  697. * another. Use this routine in to make two monochrome class objects visually identical. *
  698. * *
  699. * INPUT: src -- A reference to the source (right side) monochrome object. *
  700. * *
  701. * OUTPUT: none *
  702. * *
  703. * WARNINGS: none *
  704. * *
  705. * HISTORY: *
  706. * 10/17/1994 JLB : Created. *
  707. *=============================================================================================*/
  708. MonoClass & MonoClass::operator = (MonoClass const & src)
  709. {
  710. memmove(Page_Ptr(), src.Page_Ptr(), sizeof(MonoPageType));
  711. Set_Cursor(src.X, src.Y);
  712. return(*this);
  713. }
  714. /***********************************************************************************************
  715. * MonoClass::View -- Brings the mono object to the main display. *
  716. * *
  717. * Use this routine to display the mono object on the monochrome screen. It is possible *
  718. * that the mono object exists on some background screen memory. Calling this routine will *
  719. * perform the necessary memory swapping to bring the data to the front. The mono object *
  720. * that was currently being viewed is not destroyed by this function. It is merely moved *
  721. * off to some background page. It can be treated normally, except that is just isn't *
  722. * visible. *
  723. * *
  724. * INPUT: none *
  725. * *
  726. * OUTPUT: none *
  727. * *
  728. * WARNINGS: none *
  729. * *
  730. * HISTORY: *
  731. * 10/17/1994 JLB : Created. *
  732. *=============================================================================================*/
  733. void MonoClass::View(void)
  734. {
  735. if (Get_Current() == this) return;
  736. /*
  737. ** If the visible page is already assigned to a real monochrome page
  738. ** object, then it must be swapped with the new one.
  739. */
  740. MonoClass * displace = Get_Current();
  741. if (displace) {
  742. for (int line = 0; line < LINES; line++) {
  743. for (int col = 0; col < COLUMNS; col++) {
  744. CellType temp = Page_Ptr()->Data[line][col];
  745. Page_Ptr()->Data[line][col] = Raw_Ptr(0)->Data[line][col];
  746. Raw_Ptr(0)->Data[line][col] = temp;
  747. }
  748. }
  749. displace->Page = Page;
  750. } else {
  751. /*
  752. ** Just copy the new page over since the display page is not assigned
  753. ** to a real monochrome page object.
  754. */
  755. memmove(Raw_Ptr(0), Page_Ptr(), sizeof(MonoPageType));
  756. }
  757. PageUsage[Page] = displace;
  758. PageUsage[0] = this;
  759. Page = 0;
  760. Set_Cursor(X, Y);
  761. }
  762. /************************************************************************************
  763. ** This is the set of C wrapper functions that access the MonoClass support routines.
  764. ** Since the C interface doesn't have the ability to write to non-visible pages, it
  765. ** will just blast the output to whichever mono page is currently visible. If there is
  766. ** no mono class object that is visible, then one will be created -- BUT NOT FREED.
  767. ** Typically, this is ok, since the C interface will create only one MonoClass object
  768. ** and the system supports up to 8.
  769. */
  770. void Mono_Set_Cursor(int x, int y)
  771. {
  772. if (MonoClass::Is_Enabled()) {
  773. MonoClass * mono = MonoClass::Get_Current();
  774. if (!mono) {
  775. mono = new MonoClass();
  776. mono->View();
  777. }
  778. mono->Set_Cursor(x, y);
  779. }
  780. }
  781. /***********************************************************************************************
  782. * Mono_Printf -- Prints formatted text to visible page. *
  783. * *
  784. * This routine will print formatted text (with parameters) to the visible monochrome page *
  785. * at whatever the current cursor location is. *
  786. * *
  787. * INPUT: string -- The string to use as the main text and formatting control string. *
  788. * *
  789. * ... -- Any additional parameters required by the formatting string. *
  790. * *
  791. * OUTPUT: Returns with the number of characters written to the display. *
  792. * *
  793. * WARNINGS: The total size of the formatted text must not exceed 256 characters. *
  794. * *
  795. * HISTORY: *
  796. * 06/04/1996 JLB : Created. *
  797. *=============================================================================================*/
  798. int Mono_Printf(char const * string, ...)
  799. {
  800. va_list va;
  801. char buffer[256];
  802. buffer[0] = '\0';
  803. if (MonoClass::Is_Enabled()) {
  804. MonoClass * mono = MonoClass::Get_Current();
  805. if (!mono) {
  806. mono = new MonoClass();
  807. mono->View();
  808. }
  809. va_start(va, string);
  810. vsprintf(buffer, string, va);
  811. mono->Print(buffer);
  812. va_end(va);
  813. }
  814. return((short)strlen(buffer));
  815. }
  816. /***********************************************************************************************
  817. * Mono_Clear_Screen -- Clear the currently visible monochrome page. *
  818. * *
  819. * This routine will clear the currently visible monochrome page. *
  820. * *
  821. * INPUT: none *
  822. * *
  823. * OUTPUT: none *
  824. * *
  825. * WARNINGS: none *
  826. * *
  827. * HISTORY: *
  828. * 06/04/1996 JLB : Created. *
  829. *=============================================================================================*/
  830. void Mono_Clear_Screen(void)
  831. {
  832. if (MonoClass::Is_Enabled()) {
  833. MonoClass * mono = MonoClass::Get_Current();
  834. if (!mono) {
  835. mono = new MonoClass();
  836. mono->View();
  837. }
  838. mono->Clear();
  839. }
  840. }
  841. /***********************************************************************************************
  842. * Mono_Text_Print -- Prints text to location specified. *
  843. * *
  844. * This routine will print the specified text to the location indicated. *
  845. * *
  846. * INPUT: text -- Pointer to the text to print. *
  847. * *
  848. * x,y -- The coordinate to print the text at. *
  849. * *
  850. * attrib-- The attribute to use when printing the text. *
  851. * *
  852. * OUTPUT: none *
  853. * *
  854. * WARNINGS: none *
  855. * *
  856. * HISTORY: *
  857. * 06/04/1996 JLB : Created. *
  858. *=============================================================================================*/
  859. void Mono_Text_Print(void const *text, int x, int y, int attrib)
  860. {
  861. if (MonoClass::Is_Enabled()) {
  862. MonoClass * mono = MonoClass::Get_Current();
  863. if (!mono) {
  864. mono = new MonoClass();
  865. mono->View();
  866. }
  867. mono->Text_Print((const char*)text, x, y, (MonoClass::MonoAttribute)attrib);
  868. }
  869. }
  870. /***********************************************************************************************
  871. * Mono_Draw_Rect -- Draws rectangle to monochrome screen. *
  872. * *
  873. * Use this routine to draw a rectangle to the monochrome screen. The dimensions, attribute,*
  874. * and line style are controlled by parameters. *
  875. * *
  876. * INPUT: x,y -- Coordinate of upper left corner of the box to draw. *
  877. * *
  878. * w,h -- The width and height of the box to draw. *
  879. * *
  880. * attrib-- The attribute to use when drawing the box. *
  881. * *
  882. * thick -- The line drawing style to use. *
  883. * *
  884. * OUTPUT: none *
  885. * *
  886. * WARNINGS: none *
  887. * *
  888. * HISTORY: *
  889. * 06/04/1996 JLB : Created. *
  890. *=============================================================================================*/
  891. void Mono_Draw_Rect(int x, int y, int w, int h, int attrib, int thick)
  892. {
  893. if (MonoClass::Is_Enabled()) {
  894. MonoClass * mono = MonoClass::Get_Current();
  895. if (!mono) {
  896. mono = new MonoClass();
  897. mono->View();
  898. }
  899. mono->Draw_Box(x, y, w, h, (MonoClass::MonoAttribute)attrib, (MonoClass::BoxStyleType)thick);
  900. }
  901. }
  902. /***********************************************************************************************
  903. * Mono_Print -- Prints simple text to monochrome screen. *
  904. * *
  905. * This is the non-formatting print to the monochrome screen. *
  906. * *
  907. * INPUT: text -- Pointer to the text that will be printed. *
  908. * *
  909. * OUTPUT: none *
  910. * *
  911. * WARNINGS: none *
  912. * *
  913. * HISTORY: *
  914. * 06/04/1996 JLB : Created. *
  915. *=============================================================================================*/
  916. void Mono_Print(void const *text)
  917. {
  918. if (MonoClass::Is_Enabled()) {
  919. MonoClass * mono = MonoClass::Get_Current();
  920. if (!mono) {
  921. mono = new MonoClass();
  922. mono->View();
  923. }
  924. mono->Print((const char*)text);
  925. }
  926. }
  927. /***********************************************************************************************
  928. * Mono_X -- Fetches the X cursor position for current visible mono page. *
  929. * *
  930. * Use this routine to get the current cursor X position. This only applies to the *
  931. * currently visible monochrome page. *
  932. * *
  933. * INPUT: none *
  934. * *
  935. * OUTPUT: Returns with X position of cursor. *
  936. * *
  937. * WARNINGS: none *
  938. * *
  939. * HISTORY: *
  940. * 06/04/1996 JLB : Created. *
  941. *=============================================================================================*/
  942. int Mono_X(void)
  943. {
  944. if (MonoClass::Is_Enabled()) {
  945. MonoClass * mono = MonoClass::Get_Current();
  946. if (!mono) {
  947. mono = new MonoClass();
  948. mono->View();
  949. }
  950. return(short)mono->Get_X();
  951. }
  952. return(0);
  953. }
  954. /***********************************************************************************************
  955. * Mono_Y -- Fetches the Y cursor position for current mono page. *
  956. * *
  957. * This routine will fetch the current Y cursor position for the monochrome page. *
  958. * *
  959. * INPUT: none *
  960. * *
  961. * OUTPUT: Returns with the current Y position of the monochrome page. *
  962. * *
  963. * WARNINGS: none *
  964. * *
  965. * HISTORY: *
  966. * 06/04/1996 JLB : Created. *
  967. *=============================================================================================*/
  968. int Mono_Y(void)
  969. {
  970. if (MonoClass::Is_Enabled()) {
  971. MonoClass * mono = MonoClass::Get_Current();
  972. if (!mono) {
  973. mono = new MonoClass();
  974. mono->View();
  975. }
  976. return(short)mono->Get_X();
  977. }
  978. return(0);
  979. }
  980. void Mono_Put_Char(char , int )
  981. {
  982. }
  983. void Mono_Scroll(int )
  984. {
  985. }
  986. void Mono_View_Page(int )
  987. {
  988. }
  989. int Mono_Printf(int string, ...)
  990. {
  991. va_list va;
  992. char buffer[256];
  993. buffer[0] = '\0';
  994. if (MonoClass::Is_Enabled()) {
  995. MonoClass * mono = MonoClass::Get_Current();
  996. if (!mono) {
  997. mono = new MonoClass();
  998. mono->View();
  999. }
  1000. va_start(va, string);
  1001. vsprintf(buffer, Text_String(string), va);
  1002. mono->Print(buffer);
  1003. va_end(va);
  1004. }
  1005. return((short)strlen(buffer));
  1006. }