DIALOG.CPP 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790
  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\dialog.cpv 2.17 16 Oct 1995 16:51:50 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 : DIALOG.CPP *
  26. * *
  27. * Programmer : Joe L. Bostic *
  28. * *
  29. * Start Date : September 10, 1993 *
  30. * *
  31. * Last Update : May 18, 1995 [JLB] *
  32. * *
  33. *---------------------------------------------------------------------------------------------*
  34. * Functions: *
  35. * Clip_Text_Print -- Prints text with clipping and <TAB> support. *
  36. * Dialog_Box -- draws a dialog background box *
  37. * Display_Place_Building -- Displays the "place building" dialog box. *
  38. * Display_Select_Target -- Displays the "choose target" prompt. *
  39. * Display_Status -- Display the player scenario status box. *
  40. * Draw_Box -- Displays a highlighted box. *
  41. * Fancy_Text_Print -- Prints text with a drop shadow. *
  42. * Redraw_Needed -- Determine if sidebar needs to be redrawn. *
  43. * Render_Bar_Graph -- Renders a specified bargraph. *
  44. * Simple_Text_Print -- Prints text with a drop shadow. *
  45. * Window_Box -- Draws a fancy box over the specified window. *
  46. * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  47. #include "function.h"
  48. /***********************************************************************************************
  49. * Dialog_Box -- draws a dialog background box *
  50. * *
  51. * INPUT: *
  52. * x,y,w,h the usual *
  53. * *
  54. * OUTPUT: *
  55. * none. *
  56. * *
  57. * WARNINGS: *
  58. * none. *
  59. * *
  60. * HISTORY: *
  61. * 01/26/1995 BR : Created. *
  62. *=============================================================================================*/
  63. void Dialog_Box(int x, int y, int w, int h)
  64. {
  65. Draw_Box( x, y, w, h, BOXSTYLE_GREEN_BORDER, true);
  66. }
  67. /***********************************************************************************************
  68. * Draw_Box -- Displays a highlighted box. *
  69. * *
  70. * This will draw a highlighted box to the logicpage. It can *
  71. * optionally fill the box with a color as well. This is a low level *
  72. * function and thus, it doesn't do any graphic mode color adjustments. *
  73. * *
  74. * INPUT: x,y -- Upper left corner of the box to be drawn (pixels). *
  75. * *
  76. * w,h -- Width and height of box (in pixels). *
  77. * *
  78. * up -- Is the box rendered in the "up" stated? *
  79. * *
  80. * filled-- Is the box to be filled. *
  81. * *
  82. * OUTPUT: none *
  83. * *
  84. * WARNINGS: none *
  85. * *
  86. * HISTORY: *
  87. * 05/28/1991 JLB : Created. *
  88. * 05/30/1992 JLB : Embedded color codes. *
  89. * 07/31/1992 JLB : Depressed option added. *
  90. *=============================================================================================*/
  91. extern void CC_Texture_Fill (void const *shapefile, int shapenum, int xpos, int ypos, int width, int height);
  92. void Draw_Box(int x, int y, int w, int h, BoxStyleEnum up, bool filled)
  93. {
  94. static BoxStyleType const ButtonColors[BOXSTYLE_COUNT] = {
  95. //Filler, Shadow, Hilite, Corner colors
  96. { LTGREY, WHITE, DKGREY, LTGREY}, // 0 Button is down.
  97. { LTGREY, DKGREY, WHITE, LTGREY}, // 1 Button is up w/border.
  98. { LTBLUE, BLUE, LTCYAN, LTBLUE}, // 2 Raised blue.
  99. { DKGREY, WHITE, BLACK, DKGREY}, // 3 Button is disabled down.
  100. { DKGREY, BLACK, WHITE, LTGREY}, // 4 Button is disabled up.
  101. { LTGREY, DKGREY, WHITE, LTGREY}, // 5 Button is up w/arrows.
  102. //{ CC_GREEN_BKGD, CC_LIGHT_GREEN, CC_GREEN_SHADOW, CC_GREEN_CORNERS }, // 6 Button is down.
  103. //{ CC_GREEN_BKGD, CC_GREEN_SHADOW, CC_LIGHT_GREEN, CC_GREEN_CORNERS }, // 7 Button is up w/border.
  104. { CC_GREEN_BKGD, 14, 12, 13 }, // 6 Button is down.
  105. { CC_GREEN_BKGD, 12, 14, 13 }, // 7 Button is up w/border.
  106. { DKGREY, WHITE, BLACK, DKGREY}, // 8 Button is disabled down.
  107. { DKGREY, BLACK, LTGREY, DKGREY}, // 9 Button is disabled up.
  108. //{ BLACK, CC_GREEN_BOX, CC_GREEN_BOX, BLACK}, // 10 List box.
  109. //{ BLACK, CC_GREEN_BOX, CC_GREEN_BOX, BLACK}, // 11 Menu box.
  110. { BLACK, 14, 14, BLACK}, // 10 List box.
  111. { BLACK, 14, 14, BLACK}, // 11 Menu box.
  112. };
  113. w--;
  114. h--;
  115. BoxStyleType const &style = ButtonColors[up];
  116. if (filled) {
  117. if (style.Filler == CC_GREEN_BKGD){
  118. CC_Texture_Fill (MixFileClass::Retrieve("BTEXTURE.SHP"), InMainLoop, x, y, w, h);
  119. }else{
  120. LogicPage->Fill_Rect( x, y, x+w, y+h, style.Filler);
  121. }
  122. }
  123. switch ( up ) {
  124. case ( BOXSTYLE_GREEN_BOX ):
  125. LogicPage->Draw_Rect(x, y, x+w, y+h, style.Highlight);
  126. break;
  127. case ( BOXSTYLE_GREEN_BORDER ):
  128. LogicPage->Draw_Rect(x+1, y+1, x+w-1, y+h-1, style.Highlight);
  129. break;
  130. default:
  131. LogicPage->Draw_Line(x, y+h, x+w, y+h, style.Shadow);
  132. LogicPage->Draw_Line(x+w, y, x+w, y+h, style.Shadow);
  133. LogicPage->Draw_Line(x, y, x+w, y, style.Highlight);
  134. LogicPage->Draw_Line(x, y, x, y+h, style.Highlight);
  135. LogicPage->Put_Pixel(x, y+h, style.Corner);
  136. LogicPage->Put_Pixel(x+w, y, style.Corner);
  137. break;
  138. }
  139. }
  140. /***********************************************************************************************
  141. * Format_Window_String -- Separates a String into Lines. *
  142. * This function will take a long string and break it up into lines *
  143. * which are not longer then the window width. Any character < ' ' is *
  144. * considered a new line marker and will be replaced by a NULL. *
  145. * *
  146. * INPUT: char *String - string to be formated. *
  147. * int maxlinelen - Max length of any line in pixels. *
  148. * *
  149. * OUTPUT: int - number of lines string is. *
  150. * *
  151. * WARNINGS: The string passed in will be modified - NULLs will be put *
  152. * into each position that will be a new line. *
  153. * *
  154. * HISTORY: *
  155. * 03/27/1992 SB : Created. *
  156. * 05/18/1995 JLB : Greatly revised for new font system. *
  157. *=============================================================================================*/
  158. int Format_Window_String(char * string, int maxlinelen, int & width, int & height)
  159. {
  160. int linelen;
  161. int lines = 0;
  162. width = 0;
  163. height = 0;
  164. // In no string was passed in, then there are no lines.
  165. if (!string) return(0);
  166. // While there are more letters left divide the line up.
  167. while (*string) {
  168. linelen = 0;
  169. height += FontHeight + FontYSpacing;
  170. lines++;
  171. // While the current line is less then the max length...
  172. while (linelen < maxlinelen && *string != '\r' && *string != '\0') {
  173. linelen += Char_Pixel_Width(*string++);
  174. }
  175. // if the line is to long...
  176. if (linelen >= maxlinelen) {
  177. /*
  178. ** Back up to an appropriate location to break.
  179. */
  180. while (*string != ' ' && *string != '\r' && *string != '\0') {
  181. linelen -= Char_Pixel_Width(*string--);
  182. }
  183. }
  184. /*
  185. ** Record the largest width of the worst case string.
  186. */
  187. if (linelen > width) {
  188. width = linelen;
  189. }
  190. /*
  191. ** Force a break at the end of the line.
  192. */
  193. if (*string) {
  194. *string++ = '\r';
  195. }
  196. }
  197. return(lines);
  198. }
  199. /***********************************************************************************************
  200. * Window_Box -- Draws a fancy box over the specified window. *
  201. * *
  202. * This routine will draw a fancy (shaded) box over the specified *
  203. * window. This is the effect used to give the polished look to *
  204. * screen rectangles without having to use art. *
  205. * *
  206. * INPUT: window -- Specified window to fill and border. *
  207. * *
  208. * style -- The style to render the window. *
  209. * *
  210. * OUTPUT: none *
  211. * *
  212. * WARNINGS: The rendering is done to the LogicPage. *
  213. * *
  214. * HISTORY: *
  215. * 03/03/1992 JLB : Created. *
  216. * 07/31/1992 JLB : Cool raised border effect. *
  217. * 06/08/1994 JLB : Takes appropriate enumeration parameters. *
  218. *=============================================================================================*/
  219. void Window_Box(WindowNumberType window, BoxStyleEnum style)
  220. {
  221. int x,y,w,h; // Window dimensions.
  222. int border; // Width of border.
  223. static int _border[BOXSTYLE_COUNT][2] = {
  224. {0,0}, // 0 Simple beveled edge.
  225. {2,4}, // 1 Wide raised border.
  226. {1,1}, // 2 Thick beveled edge.
  227. {2,1}, // 3 Thin raised border.
  228. {0,0}, // 4 Simple beveled edge.
  229. {20,0}, // 5 Simple beveled edge.
  230. {0,0}, // 6 Simple beveled edge.
  231. {2,4}, // 7 Wide raised border.
  232. {0,0}, // 8 Simple beveled edge.
  233. {20,0}, // 9 Simple beveled edge.
  234. {0,1} // 10 Simple 1 pixel box.
  235. };
  236. x = WindowList[window][WINDOWX]<<3;
  237. y = WindowList[window][WINDOWY];
  238. w = WindowList[window][WINDOWWIDTH]<<3;
  239. h = WindowList[window][WINDOWHEIGHT];
  240. /*
  241. ** If it is to be rendered to the seenpage, then
  242. ** hide the mouse.
  243. */
  244. if (LogicPage == (&SeenBuff)) Conditional_Hide_Mouse(x,y,x+w,y+h);
  245. Draw_Box(x, y, w, h, style, true);
  246. border = _border[style][1];
  247. /*
  248. ** Draw the second border if requested.
  249. */
  250. if (border) {
  251. Draw_Box(x+border, y+border, w-(border<<1), h-(border<<1), style, false);
  252. }
  253. /*
  254. ** Restore the mouse if it has been hidden and return.
  255. */
  256. if (LogicPage == &SeenBuff) Conditional_Show_Mouse();
  257. }
  258. /***********************************************************************************************
  259. * Simple_Text_Print -- Prints text with a drop shadow. *
  260. * *
  261. * This routine functions like Text_Print, but will render a drop *
  262. * shadow (in black). *
  263. * *
  264. * INPUT: text -- Pointer to text to render. *
  265. * *
  266. * x,y -- Pixel coordinate for to print text. *
  267. * *
  268. * fore -- Foreground color. *
  269. * *
  270. * back -- Background color. *
  271. * *
  272. * flag -- Text print control flags. *
  273. * *
  274. * OUTPUT: none *
  275. * *
  276. * WARNINGS: none *
  277. * *
  278. * HISTORY: *
  279. * 12/24/1991 JLB : Created. *
  280. * 10/26/94 JLB : Handles font X spacing in a more friendly manner. *
  281. *=============================================================================================*/
  282. void Simple_Text_Print(char const *text, unsigned x, unsigned y, unsigned fore, unsigned back, TextPrintType flag)
  283. {
  284. static int yspace=0; // Y spacing adjustment for font.
  285. static int xspace=0; // Spacing adjustment for font.
  286. void const * font=0; // Font to use.
  287. ////////////////#if (0)
  288. static unsigned char _textfontpal[16][16] = {
  289. { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
  290. { 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27, 27, 26, 25, 24 },
  291. { 0,135, 0, 0, 0, 0, 0, 0, 0, 0, 0,136, 136,135,119, 2 },
  292. { 0,159, 0, 0, 0, 0, 0, 0, 0, 0, 0,142, 143,159,41 ,167 },
  293. { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
  294. { 0,157, 0, 0, 0, 0, 0, 0, 0, 0, 0,180, 180,157,158, 5 },
  295. { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
  296. { 0,179, 0, 0, 0, 0, 0, 0, 0, 0, 0,180, 180,179,178,176 },
  297. { 0,123, 0, 0, 0, 0, 0, 0, 0, 0, 0,122, 122,123,125,127 },
  298. { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
  299. { 0,203, 0, 0, 0, 0, 0, 0, 0, 0, 0,204, 204,203,202,201 },
  300. { 0, 1, 4,166, 41, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
  301. { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
  302. { 0,203, 0, 0, 0, 0, 0, 0, 0, 0, 0,204, 204,203,202,201 },
  303. { 0,203, 0, 0, 0, 0, 0, 0, 0, 0, 0,204, 204,203,202,201 },
  304. { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
  305. };
  306. static unsigned char _textpalmedium[16] = {
  307. 0, 25, 119,41, 0, 158,0, 178, 125,0, 202,0, 0, 0, 0, 0
  308. };
  309. static unsigned char _textpalbright[16] = {
  310. 0, 24, 2, 4, 0, 5, 0, 176, 127,0, 201,0, 0, 0, 0, 0
  311. };
  312. ///////////////////////#endif //(0)
  313. int point; // Requested font size.
  314. int shadow; // Requested shadow value.
  315. unsigned char fontpalette[16]; // Working font palette array.
  316. memset(&fontpalette[0], back, 16);
  317. if ((flag & 0xf) == TPF_VCR) {
  318. fontpalette[3] = 12;
  319. fontpalette[9] = 15;
  320. fontpalette[10] = 200;
  321. fontpalette[11] = 201;
  322. fontpalette[12] = 202;
  323. fontpalette[13] = 203;
  324. fontpalette[14] = 204;
  325. fontpalette[15] = 205;
  326. }
  327. char *tempstr = NULL;
  328. if (text){
  329. /*
  330. ** remove any 0xff characters from the string
  331. */
  332. tempstr = new char [strlen (text)+1];
  333. char *tempptr = tempstr;
  334. for ( int i=0 ; i<strlen(text)+1 ; i++ ) {
  335. if (text[i] != -1){
  336. *tempptr = text[i];
  337. tempptr++;
  338. }
  339. }
  340. }
  341. /*
  342. ** A gradient font always requires special fixups for the palette.
  343. */
  344. if ((flag & 0xf) == TPF_6PT_GRAD ||
  345. (flag & 0xf) == TPF_GREEN12_GRAD ||
  346. (flag & 0xf) == TPF_GREEN12) {
  347. /*
  348. ** If a gradient palette was requested, then fill in the font palette array
  349. ** according to the color index specified.
  350. */
  351. if (flag & TPF_USE_GRAD_PAL) {
  352. memcpy(&fontpalette[0], _textfontpal[ (fore & 0x0f) ], 16);
  353. } else {
  354. /*
  355. ** Special adjustment for fonts that have gradient artwork. When there is
  356. ** no special gradient effect desired, then set the font color based on the
  357. ** forground color specified.
  358. */
  359. memset(&fontpalette[4], fore, 12);
  360. }
  361. if (flag & TPF_MEDIUM_COLOR) {
  362. fore = _textpalmedium[fore & 0x0F];
  363. memset(&fontpalette[4], fore, 12);
  364. }else{
  365. if (flag & TPF_BRIGHT_COLOR) {
  366. fore = _textpalbright[fore & 0x0F];
  367. memset(&fontpalette[4], fore, 12);
  368. }else{
  369. fore = fontpalette[1];
  370. }
  371. }
  372. }
  373. /*
  374. ** Change the current font if it differs from the font desired.
  375. */
  376. point = (flag & (TextPrintType)0x000F);
  377. xspace = 1;
  378. yspace = 0;
  379. switch (point) {
  380. case TPF_GREEN12:
  381. font = Green12FontPtr;
  382. break;
  383. case TPF_GREEN12_GRAD:
  384. font = Green12GradFontPtr;
  385. break;
  386. case TPF_MAP:
  387. font = MapFontPtr;
  388. xspace -= 1;
  389. break;
  390. case TPF_VCR:
  391. font = VCRFontPtr;
  392. break;
  393. case TPF_6PT_GRAD:
  394. font = GradFont6Ptr;
  395. xspace -= 1;
  396. //yspace -= 1;
  397. break;
  398. case TPF_3POINT:
  399. xspace += 1;
  400. font = Font3Ptr;
  401. flag = flag & ~(TPF_DROPSHADOW|TPF_FULLSHADOW|TPF_NOSHADOW);
  402. break;
  403. case TPF_6POINT:
  404. font = Font6Ptr;
  405. xspace -= 1;
  406. //yspace -= 1;
  407. break;
  408. case TPF_8POINT:
  409. font = Font8Ptr;
  410. xspace -= 2;
  411. yspace -= 4;
  412. break;
  413. case TPF_LED:
  414. xspace -= 4;
  415. font = FontLEDPtr;
  416. break;
  417. default:
  418. font = FontPtr;
  419. break;
  420. }
  421. /*
  422. ** Change the current font palette according to the dropshadow flags.
  423. */
  424. shadow = (flag & (TPF_NOSHADOW|TPF_DROPSHADOW|TPF_FULLSHADOW|TPF_LIGHTSHADOW));
  425. switch (shadow) {
  426. /*
  427. ** The text is rendered plain.
  428. */
  429. case TPF_NOSHADOW:
  430. fontpalette[2] = back;
  431. fontpalette[3] = back;
  432. xspace -= 1;
  433. yspace -= 2;
  434. break;
  435. /*
  436. ** The text is rendered with a simple
  437. ** drop shadow.
  438. */
  439. case TPF_DROPSHADOW:
  440. fontpalette[2] = BLACK;
  441. fontpalette[3] = back;
  442. xspace -= 1;
  443. break;
  444. /*
  445. ** Special engraved text look for the options
  446. ** dialog system.
  447. */
  448. case TPF_LIGHTSHADOW:
  449. fontpalette[2] = ((14 * 16) + 7)+1;
  450. fontpalette[3] = back;
  451. xspace -= 1;
  452. break;
  453. /*
  454. ** Each letter is surrounded by black. This is used
  455. ** when the text will be over a non-plain background.
  456. */
  457. case TPF_FULLSHADOW:
  458. fontpalette[2] = BLACK;
  459. fontpalette[3] = BLACK;
  460. xspace -= 1;
  461. break;
  462. default:
  463. break;
  464. }
  465. fontpalette[0] = back;
  466. fontpalette[1] = fore;
  467. /*
  468. ** Set the font and spacing according to the values they should be.
  469. */
  470. FontXSpacing = xspace;
  471. FontYSpacing = yspace;
  472. Set_Font(font);
  473. Set_Font_Palette(fontpalette);
  474. /*
  475. ** Display the (centered) message if there is one.
  476. */
  477. if (text && *text) {
  478. switch (flag & (TPF_CENTER|TPF_RIGHT)) {
  479. case TPF_CENTER:
  480. x -= String_Pixel_Width(tempstr)>>1;
  481. break;
  482. case TPF_RIGHT:
  483. x -= String_Pixel_Width(tempstr);
  484. break;
  485. default:
  486. break;
  487. }
  488. if ((unsigned)x < SeenBuff.Get_Width() && (unsigned)y < SeenBuff.Get_Height()) {
  489. LogicPage->Print(tempstr, x, y, fore, back);
  490. }
  491. }
  492. if (tempstr){
  493. delete [] tempstr;
  494. }
  495. }
  496. /***********************************************************************************************
  497. * Fancy_Text_Print -- Prints text with a drop shadow. *
  498. * *
  499. * This routine functions like Text_Print, but will render a drop *
  500. * shadow (in black). *
  501. * *
  502. * INPUT: text -- Text number to print. *
  503. * *
  504. * x,y -- Pixel coordinate for to print text. *
  505. * *
  506. * fore -- Foreground color. *
  507. * *
  508. * back -- Background color. *
  509. * *
  510. * flag -- Text print control flags. *
  511. * *
  512. * OUTPUT: none *
  513. * *
  514. * WARNINGS: This routine is much slower than normal text print and *
  515. * if rendered to the SEENPAGE, the intermediate rendering *
  516. * steps could be visible. *
  517. * *
  518. * HISTORY: *
  519. * 11/29/1994 JLB : Created *
  520. *=============================================================================================*/
  521. void Fancy_Text_Print(int text, unsigned x, unsigned y, unsigned fore, unsigned back, TextPrintType flag, ...)
  522. {
  523. char buffer[512]; // Working staging buffer.
  524. va_list arg; // Argument list var.
  525. /*
  526. ** If the text number is valid, then process it.
  527. */
  528. if (text != TXT_NONE) {
  529. va_start(arg, flag);
  530. /*
  531. ** The text string must be locked since the vsprintf function doesn't know
  532. ** how to handle EMS pointers.
  533. */
  534. char const * tptr = Text_String(text);
  535. vsprintf(buffer, tptr, arg);
  536. va_end(arg);
  537. Simple_Text_Print(buffer, x, y, fore, back, flag);
  538. } else {
  539. /*
  540. ** Just the flags are to be changed, since the text number is TXT_NONE.
  541. */
  542. Simple_Text_Print((char const *)0, x, y, fore, back, flag);
  543. }
  544. }
  545. /***********************************************************************************************
  546. * Fancy_Text_Print -- Prints text with a drop shadow. *
  547. * *
  548. * This routine functions like Text_Print, but will render a drop *
  549. * shadow (in black). *
  550. * *
  551. * INPUT: text -- Pointer to text to render. *
  552. * *
  553. * x,y -- Pixel coordinate for to print text. *
  554. * *
  555. * fore -- Foreground color. *
  556. * *
  557. * back -- Background color. *
  558. * *
  559. * flag -- Text print control flags. *
  560. * *
  561. * OUTPUT: none *
  562. * *
  563. * WARNINGS: This routine is much slower than normal text print and *
  564. * if rendered to the SEENPAGE, the intermediate rendering *
  565. * steps could be visible. *
  566. * *
  567. * HISTORY: *
  568. * 12/24/1991 JLB : Created. *
  569. * 10/26/94 JLB : Handles font X spacing in a more friendly manner. *
  570. * 11/29/1994 JLB : Separated actual draw action. *
  571. *=============================================================================================*/
  572. void Fancy_Text_Print(char const *text, unsigned x, unsigned y, unsigned fore, unsigned back, TextPrintType flag, ...)
  573. {
  574. char buffer[512]; // Working staging buffer.
  575. va_list arg; // Argument list var.
  576. /*
  577. ** If there is a valid text string pointer then build the final string into the
  578. ** working buffer before sending it to the simple string printing routine.
  579. */
  580. if (text) {
  581. /*
  582. ** Since vsprintf doesn't know about EMS pointers, be sure to surround this
  583. ** call with locking code.
  584. */
  585. va_start(arg, flag);
  586. vsprintf(buffer, text, arg);
  587. va_end(arg);
  588. Simple_Text_Print(buffer, x, y, fore, back, flag);
  589. } else {
  590. /*
  591. ** Just the flags are desired to be changed, so call the simple print routine with
  592. ** a NULL text pointer.
  593. */
  594. Simple_Text_Print((char const *)0, x, y, fore, back, flag);
  595. }
  596. }
  597. /***********************************************************************************************
  598. * Clip_Text_Print -- Prints text with clipping and <TAB> support. *
  599. * *
  600. * Use this routine to print text that that should be clipped at an arbitrary right margin *
  601. * as well as possibly recognizing <TAB> characters. Typical users of this routine would *
  602. * be list boxes. *
  603. * *
  604. * INPUT: text -- Reference to the text to print. *
  605. * *
  606. * x,y -- Pixel coordinate of the upper left corner of the text position. *
  607. * *
  608. * fore -- The foreground color to use. *
  609. * *
  610. * back -- The background color to use. *
  611. * *
  612. * flag -- The text print flags to use. *
  613. * *
  614. * width -- The maximum pixel width to draw the text. Extra characters beyond this *
  615. * point will not be printed. *
  616. * *
  617. * tabs -- Optional pointer to a series of pixel tabstop positions. *
  618. * *
  619. * OUTPUT: none *
  620. * *
  621. * WARNINGS: none *
  622. * *
  623. * HISTORY: *
  624. * 01/21/1995 JLB : Created. *
  625. *=============================================================================================*/
  626. void Conquer_Clip_Text_Print(char const *text, unsigned x, unsigned y, unsigned fore, unsigned back, TextPrintType flag, unsigned width, int const * tabs)
  627. {
  628. char buffer[512];
  629. if (text) {
  630. strcpy(buffer, text);
  631. /*
  632. ** Set the font and spacing characteristics according to the flag
  633. ** value passed in.
  634. */
  635. Simple_Text_Print(TXT_NONE, 0, 0, TBLACK, TBLACK, flag);
  636. char * source = &buffer[0];
  637. unsigned offset = 0;
  638. int processing = true;
  639. while (processing && offset < width) {
  640. char * ptr = strchr(source, '\t');
  641. /*
  642. ** Zap the tab character. It will be processed later.
  643. */
  644. if (ptr) {
  645. *ptr = '\0';
  646. }
  647. if (*source) {
  648. /*
  649. ** Scan forward until the end of the string is reached or the
  650. ** maximum width, whichever comes first.
  651. */
  652. int w = 0;
  653. char * bptr = source;
  654. do {
  655. w += Char_Pixel_Width(*bptr++);
  656. } while(*bptr && offset+w < width);
  657. /*
  658. ** If the maximum width has been exceeded, then remove the last
  659. ** character and signal that further processing is not necessary.
  660. */
  661. if (offset+w >= width) {
  662. bptr--;
  663. w -= Char_Pixel_Width(*bptr);
  664. *bptr = '\0';
  665. processing = 0;
  666. }
  667. /*
  668. ** Print this text block and advance the offset accordingly.
  669. */
  670. Simple_Text_Print(source, x+offset, y, fore, back, flag);
  671. offset += w;
  672. }
  673. /*
  674. ** If a <TAB> was the terminator for this text block, then advance
  675. ** to the next tabstop.
  676. */
  677. if (ptr) {
  678. if (tabs) {
  679. while (offset > *tabs) {
  680. tabs++;
  681. }
  682. offset = *tabs;
  683. } else {
  684. offset = ((offset+1 / 50) + 1) * 50;
  685. }
  686. source = ptr+1;
  687. } else {
  688. break;
  689. }
  690. }
  691. }
  692. }