W3DGameWindow.cpp 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663
  1. /*
  2. ** Command & Conquer Generals(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. // //
  20. // (c) 2001-2003 Electronic Arts Inc. //
  21. // //
  22. ////////////////////////////////////////////////////////////////////////////////
  23. // FILE: W3DGameWindow.cpp ////////////////////////////////////////////////////
  24. //-----------------------------------------------------------------------------
  25. //
  26. // Westwood Studios Pacific.
  27. //
  28. // Confidential Information
  29. // Copyright (C) 2001 - All Rights Reserved
  30. //
  31. //-----------------------------------------------------------------------------
  32. //
  33. // Project: RTS3
  34. //
  35. // File name: W3DGameWindow.cpp
  36. //
  37. // Created: Colin Day, June 2001
  38. //
  39. // Desc: W3D implementation of a game window
  40. //
  41. //-----------------------------------------------------------------------------
  42. ///////////////////////////////////////////////////////////////////////////////
  43. // SYSTEM INCLUDES ////////////////////////////////////////////////////////////
  44. #include <stdlib.h>
  45. // USER INCLUDES //////////////////////////////////////////////////////////////
  46. #include "GameClient/Gadget.h"
  47. #include "GameClient/GameWindowGlobal.h"
  48. #include "W3DDevice/GameClient/W3DGameWindow.h"
  49. #include "W3DDevice/GameClient/W3DGameWindowManager.h"
  50. #include "W3DDevice/GameClient/W3DDisplay.h"
  51. // DEFINES ////////////////////////////////////////////////////////////////////
  52. enum
  53. {
  54. BORDER_CORNER_SIZE = 15,
  55. BORDER_LINE_SIZE = 20,
  56. };
  57. // PRIVATE TYPES //////////////////////////////////////////////////////////////
  58. ///////////////////////////////////////////////////////////////////////////////
  59. // PRIVATE DATA ///////////////////////////////////////////////////////////////
  60. ///////////////////////////////////////////////////////////////////////////////
  61. static Bool bordersInit = FALSE;
  62. static const Image *borderPieces[NUM_BORDER_PIECES] = { 0 };
  63. // PUBLIC DATA ////////////////////////////////////////////////////////////////
  64. // PRIVATE PROTOTYPES /////////////////////////////////////////////////////////
  65. ///////////////////////////////////////////////////////////////////////////////
  66. // PRIVATE FUNCTIONS //////////////////////////////////////////////////////////
  67. ///////////////////////////////////////////////////////////////////////////////
  68. // initBorders ================================================================
  69. //=============================================================================
  70. static void initBorders( void )
  71. {
  72. borderPieces[ BORDER_CORNER_UL ] =
  73. TheMappedImageCollection->findImageByName( AsciiString( "BorderCornerUL" ) );
  74. borderPieces[ BORDER_CORNER_UR ] =
  75. TheMappedImageCollection->findImageByName( AsciiString( "BorderCornerUR" ) );
  76. borderPieces[ BORDER_CORNER_LL ] =
  77. TheMappedImageCollection->findImageByName( AsciiString( "BorderCornerLL" ) );
  78. borderPieces[ BORDER_CORNER_LR ] =
  79. TheMappedImageCollection->findImageByName( AsciiString( "BorderCornerLR" ) );
  80. borderPieces[ BORDER_VERTICAL_LEFT ] =
  81. TheMappedImageCollection->findImageByName( AsciiString( "BorderLeft" ) );
  82. borderPieces[ BORDER_VERTICAL_LEFT_SHORT ] =
  83. TheMappedImageCollection->findImageByName( AsciiString( "BorderLeftShort" ) );
  84. borderPieces[ BORDER_HORIZONTAL_TOP ] =
  85. TheMappedImageCollection->findImageByName( AsciiString( "BorderTop" ) );
  86. borderPieces[ BORDER_HORIZONTAL_TOP_SHORT ] =
  87. TheMappedImageCollection->findImageByName( AsciiString( "BorderTopShort" ) );
  88. borderPieces[ BORDER_VERTICAL_RIGHT ] =
  89. TheMappedImageCollection->findImageByName( AsciiString( "BorderRight" ) );
  90. borderPieces[ BORDER_VERTICAL_RIGHT_SHORT ] =
  91. TheMappedImageCollection->findImageByName( AsciiString( "BorderRightShort" ) );
  92. borderPieces[ BORDER_HORIZONTAL_BOTTOM ] =
  93. TheMappedImageCollection->findImageByName( AsciiString( "BorderBottom" ) );
  94. borderPieces[ BORDER_HORIZONTAL_BOTTOM_SHORT ] =
  95. TheMappedImageCollection->findImageByName( AsciiString( "BorderBottomShort" ) );
  96. bordersInit = TRUE;
  97. }
  98. // W3DGameWindow::blitBorderRect ==============================================
  99. //=============================================================================
  100. void W3DGameWindow::blitBorderRect( Int x, Int y, Int width, Int height )
  101. {
  102. Int Offset = 15;
  103. Int OffsetLower = 5;
  104. // init image loc if needed
  105. if( bordersInit == FALSE )
  106. initBorders();
  107. // save original x, y
  108. Int originalX = x;
  109. Int originalY = y;
  110. Int maxX = x + width;
  111. Int maxY = y + height;
  112. Int x2, y2; // used for simultaneous drawing of line pairs
  113. Int size = 20;
  114. Int halfSize = size / 2;
  115. // Draw Horizontal Lines
  116. // All border pieces are based on a 10 pixel offset from the centerline
  117. y = originalY - Offset;
  118. y2 = maxY - OffsetLower;
  119. x2 = maxX - (OffsetLower + BORDER_LINE_SIZE);
  120. for( x=(originalX + OffsetLower); x <= x2; x += BORDER_LINE_SIZE )
  121. {
  122. TheDisplay->drawImage( borderPieces[ BORDER_HORIZONTAL_TOP ],
  123. x, y, x + size, y + size );
  124. TheDisplay->drawImage( borderPieces[ BORDER_HORIZONTAL_BOTTOM ],
  125. x, y2, x + size, y2 + size );
  126. }
  127. x2 = maxX - 5;//BORDER_CORNER_SIZE;
  128. // x == place to draw remainder if any
  129. if( (x2 - x) >= (BORDER_LINE_SIZE / 2) )
  130. {
  131. //Blit Half piece
  132. TheDisplay->drawImage( borderPieces[ BORDER_HORIZONTAL_TOP_SHORT ],
  133. x, y, x + halfSize, y + size );
  134. TheDisplay->drawImage( borderPieces[ BORDER_HORIZONTAL_BOTTOM_SHORT ],
  135. x, y2, x + halfSize, y2 + size );
  136. x += (BORDER_LINE_SIZE / 2);
  137. }
  138. // x2 - x ... must now be less than a half piece
  139. // check for equals and if not blit an adjusted half piece border pieces have
  140. // a two pixel repeat so we will blit one pixel over if necessary to line up
  141. // the art, but we'll cover-up the overlap with the corners
  142. if( x < x2 )
  143. {
  144. x -= ((BORDER_LINE_SIZE / 2) - (((x2 - x) + 1) & ~1));
  145. //Blit Half piece
  146. TheDisplay->drawImage( borderPieces[ BORDER_HORIZONTAL_TOP_SHORT ],
  147. x, y, x + halfSize, y + size );
  148. TheDisplay->drawImage( borderPieces[ BORDER_HORIZONTAL_BOTTOM_SHORT ],
  149. x, y2, x + halfSize, y2 + size );
  150. }
  151. // Draw Vertical Lines
  152. // All border pieces are based on a 10 pixel offset from the centerline
  153. x = originalX - Offset;
  154. x2 = maxX - OffsetLower;
  155. y2 = maxY - (OffsetLower + BORDER_LINE_SIZE);
  156. for( y=(originalY + OffsetLower); y <= y2; y += BORDER_LINE_SIZE )
  157. {
  158. TheDisplay->drawImage( borderPieces[ BORDER_VERTICAL_LEFT ],
  159. x, y, x + size, y + size );
  160. TheDisplay->drawImage( borderPieces[ BORDER_VERTICAL_RIGHT ],
  161. x2, y, x2 + size, y + size );
  162. }
  163. y2 = maxY - OffsetLower;//BORDER_CORNER_SIZE;
  164. // y == place to draw remainder if any
  165. if( (y2 - y) >= (BORDER_LINE_SIZE / 2) )
  166. {
  167. //Blit Half piece
  168. TheDisplay->drawImage( borderPieces[ BORDER_VERTICAL_LEFT_SHORT ],
  169. x, y, x + size, y + halfSize );
  170. TheDisplay->drawImage( borderPieces[ BORDER_VERTICAL_RIGHT_SHORT ],
  171. x2, y, x2 + size, y + halfSize );
  172. y += (BORDER_LINE_SIZE / 2);
  173. }
  174. // y2 - y ... must now be less than a half piece
  175. // check for equals and if not blit an adjusted half piece border pieces have
  176. // a two pixel repeat so we will blit one pixel over if necessary to line up
  177. // the art, but we'll cover-up the overlap with the corners
  178. if( y < y2 )
  179. {
  180. y -= ((BORDER_LINE_SIZE / 2) - (((y2 - y) + 1) & ~1));
  181. //Blit Half piece
  182. TheDisplay->drawImage( borderPieces[ BORDER_VERTICAL_LEFT_SHORT ],
  183. x, y, x + size, y + halfSize );
  184. TheDisplay->drawImage( borderPieces[ BORDER_VERTICAL_RIGHT_SHORT ],
  185. x2, y, x2 + size, y + halfSize );
  186. }
  187. // Draw Corners
  188. x = originalX - BORDER_CORNER_SIZE ;
  189. y = originalY - BORDER_CORNER_SIZE;
  190. TheDisplay->drawImage( borderPieces[ BORDER_CORNER_UL ],
  191. x, y, x + size, y + size );
  192. x = maxX - 5;//BORDER_CORNER_SIZE;
  193. y = originalY - BORDER_CORNER_SIZE;
  194. TheDisplay->drawImage( borderPieces[ BORDER_CORNER_UR ],
  195. x, y, x + size, y + size );
  196. x = originalX - BORDER_CORNER_SIZE;
  197. y = maxY - 5;//BORDER_CORNER_SIZE;
  198. TheDisplay->drawImage( borderPieces[ BORDER_CORNER_LL ],
  199. x, y, x + size, y + size );
  200. x = maxX - 5;//BORDER_CORNER_SIZE;
  201. y = maxY - 5;//BORDER_CORNER_SIZE;
  202. TheDisplay->drawImage( borderPieces[ BORDER_CORNER_LR ],
  203. x, y, x + size, y + size );
  204. } // end blitBorderRect
  205. ///////////////////////////////////////////////////////////////////////////////
  206. // PUBLIC FUNCTIONS ///////////////////////////////////////////////////////////
  207. ///////////////////////////////////////////////////////////////////////////////
  208. // W3DGameWindow::W3DGameWindow ===============================================
  209. //=============================================================================
  210. W3DGameWindow::W3DGameWindow( void )
  211. {
  212. // override the default draw with our own default draw function for W3D
  213. winSetDrawFunc( TheWindowManager->getDefaultDraw() );
  214. m_textPos.x = m_textPos.y = 0;
  215. m_currTextColor = WIN_COLOR_UNDEFINED;
  216. m_needPolyDraw = FALSE;
  217. m_newTextPos = FALSE;
  218. } // end W3DGameWindow
  219. // W3DGameWindow::~W3DGameWindow ==============================================
  220. //=============================================================================
  221. W3DGameWindow::~W3DGameWindow( void )
  222. {
  223. } // end ~W3DGameWindow
  224. // W3DGameWinDefaultDraw ======================================================
  225. /** The default redraw callback. Draws the background using either
  226. * the drawData or the background color unless the background color
  227. * is set to -1 indicating that default drawing is turned off. */
  228. //=============================================================================
  229. void W3DGameWinDefaultDraw( GameWindow *window, WinInstanceData *instData )
  230. {
  231. Real borderWidth = 1.0f;
  232. ICoord2D origin;
  233. ICoord2D size;
  234. W3DGameWindow *w3dWindow = (W3DGameWindow *)window;
  235. /** @todo NOTE that we're making a W3DGameWindow cast here, it seems
  236. logical because we are in a W3D draw function so it's reasonable to assume
  237. that we have a W3DGameWindow. However, we may want to revisit this
  238. type of casting in the future, we have the same problems with the
  239. ObjectModules where we cast object modules for their individual methods.
  240. Also note that the other W3D implementations of GUI controls are making
  241. a similar cast for their device implementation functions */
  242. // get the window position in the screen coordinates
  243. w3dWindow->winGetScreenPosition( &origin.x, &origin.y );
  244. // get size of window
  245. w3dWindow->winGetSize( &size.x, &size.y );
  246. // image drawing vs color drawing
  247. if( BitTest( window->winGetStatus(), WIN_STATUS_IMAGE ) )
  248. {
  249. const Image *image;
  250. // get image
  251. if( BitTest( window->winGetStatus(), WIN_STATUS_ENABLED ) == FALSE )
  252. image = window->winGetDisabledImage( 0 );
  253. else if( BitTest( instData->getState(), WIN_STATE_HILITED ) )
  254. image = window->winGetHiliteImage( 0 );
  255. else
  256. image = window->winGetEnabledImage( 0 );
  257. if( image )
  258. {
  259. ICoord2D start, end;
  260. start.x = origin.x + instData->m_imageOffset.x;
  261. start.y = origin.y + instData->m_imageOffset.y;
  262. end.x = start.x + size.x;
  263. end.y = start.y + size.y;
  264. TheWindowManager->winDrawImage( image, start.x, start.y, end.x, end.y );
  265. } // end if
  266. } // end if
  267. else
  268. {
  269. Color color, borderColor;
  270. // get colors
  271. if( BitTest( window->winGetStatus(), WIN_STATUS_ENABLED ) == FALSE )
  272. {
  273. color = window->winGetDisabledColor( 0 );
  274. borderColor = window->winGetDisabledBorderColor( 0 );
  275. } // end if
  276. else if( BitTest( instData->getState(), WIN_STATE_HILITED ) )
  277. {
  278. color = window->winGetHiliteColor( 0 );
  279. borderColor = window->winGetHiliteBorderColor( 0 );
  280. } // end else if
  281. else
  282. {
  283. color = window->winGetEnabledColor( 0 );
  284. borderColor = window->winGetEnabledBorderColor( 0 );
  285. } // end else
  286. //
  287. // draw the border at the edges
  288. //
  289. if( borderColor != WIN_COLOR_UNDEFINED )
  290. TheWindowManager->winOpenRect( borderColor, borderWidth,
  291. origin.x, origin.y,
  292. origin.x + size.x, origin.y + size.y );
  293. // draw filled background
  294. if( color != WIN_COLOR_UNDEFINED )
  295. TheWindowManager->winFillRect( color, borderWidth,
  296. origin.x + borderWidth,
  297. origin.y + borderWidth,
  298. origin.x + size.x - borderWidth,
  299. origin.y + size.y - borderWidth );
  300. } // end else
  301. // if we have a video buffer, draw the video buffer
  302. if ( instData->m_videoBuffer )
  303. {
  304. ICoord2D pos, size;
  305. window->winGetScreenPosition( &pos.x, &pos.y );
  306. window->winGetSize( &size.x, &size.y );
  307. TheDisplay->drawVideoBuffer( instData->m_videoBuffer, pos.x, pos.y, pos.x + size.x, pos.y + size.y );
  308. }
  309. } // end W3DGameWinDefaultDraw
  310. // W3DGameWindow::winDrawBorder ===============================================
  311. //=============================================================================
  312. void W3DGameWindow::winDrawBorder( void )
  313. {
  314. Bool found = FALSE;
  315. Int originalX, originalY;
  316. Int x, y;
  317. Int width;
  318. Int i, bits;
  319. /** @todo this WinDrawBorder is the old Nox function for drawing the borders
  320. * on various windows and controls. We should derive classes of game
  321. * windows for the different GUI controls and move the specific pieces of
  322. * code that apply for those gadgets to those classes */
  323. // based on window class pass different regions to real draw
  324. winGetScreenPosition( &originalX, &originalY );
  325. for( i = 0; (i < (sizeof(UnsignedInt) * 8)) && (found == FALSE); i++ )
  326. {
  327. bits = (1 << i);
  328. if( m_instData.getStyle() & bits )
  329. {
  330. switch( m_instData.getStyle() & bits )
  331. {
  332. case GWS_CHECK_BOX:
  333. found = TRUE;
  334. break;
  335. case GWS_ENTRY_FIELD:
  336. {
  337. // EntryData *e = (EntryData *)m_userData;
  338. width = m_size.x;
  339. x = originalX;
  340. y = originalY;
  341. // Calculate space for Label
  342. if( m_instData.getTextLength() )
  343. {
  344. Int textWidth = 0;
  345. TheWindowManager->winGetTextSize( m_instData.getFont(),
  346. m_instData.getText(),
  347. &textWidth, NULL, 0 );
  348. width -= textWidth + 6;
  349. x += textWidth + 6;
  350. }
  351. /*
  352. // Colin: The very notion of entry width makes no sense to me since
  353. // we already have a gadget width, and the max characters for
  354. // an entry box so I am removing this.
  355. // Adjust entry box if an entryWidth is provided
  356. if( (e->entryWidth > 0) && (width > e->entryWidth) )
  357. {
  358. width = e->entryWidth;
  359. x = originalX + (m_size.x - e->entryWidth);
  360. }
  361. */
  362. blitBorderRect( x, y, width, m_size.y );
  363. found = TRUE;
  364. break;
  365. }
  366. // Sliders may need a bar for the button
  367. // it is assumed that the smaller size component (width, height)
  368. // is the axis of the slider
  369. case GWS_VERT_SLIDER:
  370. case GWS_HORZ_SLIDER:
  371. // blitBorderLine( originalX, originalY, window->size.x, window->size.y );
  372. found = TRUE;
  373. break;
  374. case GWS_SCROLL_LISTBOX:
  375. {
  376. ListboxData *list = (ListboxData *)m_userData;
  377. Int sliderAdjustment = 0;
  378. Int labelAdjustment = 0;
  379. if( list->scrollBar )
  380. {
  381. GameWindow *child = list->slider->winGetChild();
  382. ICoord2D size;
  383. child->winGetSize( &size.x, &size.y );
  384. sliderAdjustment = size.y;
  385. } // end if
  386. if( m_instData.getTextLength() )
  387. labelAdjustment = 4;
  388. blitBorderRect( (originalX - 3),
  389. (originalY - (3 + labelAdjustment)),
  390. (m_size.x + 3 - sliderAdjustment),
  391. (m_size.y + 6) );
  392. found = TRUE;
  393. break;
  394. }
  395. case GWS_RADIO_BUTTON:
  396. case GWS_STATIC_TEXT:
  397. case GWS_PROGRESS_BAR:
  398. case GWS_PUSH_BUTTON:
  399. case GWS_USER_WINDOW:
  400. case GWS_TAB_CONTROL:
  401. blitBorderRect( originalX, originalY, m_size.x, m_size.y );
  402. found = TRUE;
  403. break;
  404. } // end switch
  405. } // end if
  406. } // end for i
  407. } // end WinDrawBorder
  408. // W3DGameWindow::winSetFont ==================================================
  409. /** Set the font for a widow */
  410. //=============================================================================
  411. void W3DGameWindow::winSetFont( GameFont *font )
  412. {
  413. // extending functionality
  414. GameWindow::winSetFont( font );
  415. // assign font to text renderer
  416. m_textRenderer.Set_Font( static_cast<FontCharsClass *>(font->fontData) );
  417. // this is a visual change
  418. m_needPolyDraw = TRUE;
  419. } // end WinSetFont
  420. // W3DGameWindow::winSetText ==================================================
  421. /** Set the text for window */
  422. //=============================================================================
  423. Int W3DGameWindow::winSetText( UnicodeString newText )
  424. {
  425. // extending functionality
  426. GameWindow::winSetText( newText );
  427. // rebuild the sentence in our text renderer
  428. m_textRenderer.Build_Sentence( m_instData.getText().str(),NULL, NULL );
  429. // this is a visual change
  430. m_needPolyDraw = TRUE;
  431. return WIN_ERR_OK;
  432. } // end WinSetText
  433. // W3DGameWindow::winSetPosition ==============================================
  434. /** Set window position */
  435. //=============================================================================
  436. Int W3DGameWindow::winSetPosition( Int x, Int y )
  437. {
  438. ICoord2D prevPos;
  439. // get previous position
  440. prevPos.x = m_region.lo.x;
  441. prevPos.y = m_region.lo.y;
  442. // extending functionality
  443. GameWindow::winSetPosition( x, y );
  444. // update any text position change
  445. m_textPos.x += m_region.lo.x - prevPos.x;
  446. m_textPos.y += m_region.lo.y - prevPos.y;
  447. m_newTextPos = TRUE;
  448. return WIN_ERR_OK;
  449. } // end WinSetPosition
  450. // W3DGameWindow::getTextSize =================================================
  451. /** Get the size of the text in our inst data */
  452. //=============================================================================
  453. void W3DGameWindow::getTextSize( Int *width, Int *height )
  454. {
  455. Vector2 extents = m_textRenderer.Get_Text_Extents( m_instData.getText().str() );
  456. if( width )
  457. *width = extents.X;
  458. if( height )
  459. *height = extents.Y;
  460. } // end getTextSize
  461. // W3DGameWindow::getTextLoc ==================================================
  462. // Set our text rendering location */
  463. //=============================================================================
  464. void W3DGameWindow::setTextLoc( Int x, Int y )
  465. {
  466. if( m_textPos.x != x )
  467. {
  468. m_textPos.x = x;
  469. m_newTextPos = TRUE;
  470. }
  471. if( m_textPos.y != y )
  472. {
  473. m_textPos.y = y;
  474. m_newTextPos = TRUE;
  475. } // end if
  476. } // end setTextLoc
  477. // W3DGameWindow::drawText ====================================================
  478. /** Draw the text in our 2d sentence renderer */
  479. //=============================================================================
  480. void W3DGameWindow::drawText( Color color )
  481. {
  482. Bool needDraw = FALSE;
  483. // if new text pos we need to redraw
  484. if( m_newTextPos )
  485. {
  486. m_newTextPos = FALSE;
  487. needDraw = TRUE;
  488. } // end if
  489. // if color switch, set new color
  490. if( m_currTextColor != color )
  491. {
  492. m_currTextColor = color;
  493. needDraw = TRUE;
  494. } // end if
  495. // draw the quads if needed
  496. if( needDraw || m_needPolyDraw )
  497. {
  498. UnsignedInt outline = TheWindowManager->winMakeColor( 0, 0, 0, 255 );
  499. m_textRenderer.Reset_Polys();
  500. m_textRenderer.Set_Location( Vector2( m_textPos.x + 1, m_textPos.y + 1 ) );
  501. m_textRenderer.Draw_Sentence( outline );
  502. m_textRenderer.Set_Location( Vector2( m_textPos.x, m_textPos.y ) );
  503. m_textRenderer.Draw_Sentence( m_currTextColor );
  504. m_needPolyDraw = FALSE;
  505. } // end if
  506. // do the render
  507. m_textRenderer.Render();
  508. } // end drawText