txt2d.cpp 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  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. *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
  20. ***************************************************************************
  21. * *
  22. * Project Name : Commando/G *
  23. * *
  24. * $Archive:: /Commando/Code/ww3d2/txt2d.cpp $*
  25. * *
  26. * $Author:: Patrick $*
  27. * *
  28. * $Modtime:: 3/27/01 5:08p $*
  29. * *
  30. * $Revision:: 3 $*
  31. * *
  32. *-------------------------------------------------------------------------*
  33. * Functions: *
  34. * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  35. #include "txt2d.h"
  36. #include "font.h"
  37. #include "assetmgr.h"
  38. #include "ww3d.h"
  39. #include "pot.h"
  40. #include "bsurface.h"
  41. #include "texture.h"
  42. #include <stdio.h>
  43. #include <stdarg.h>
  44. #ifdef WW3D_DX8
  45. #include <srTextureMap.hpp>
  46. float Text2DObjClass::_LastWidth = 0.0f;
  47. float Text2DObjClass::_LastHeight = 0.0f;
  48. /**************************************************************************
  49. * T2DOC::Text2DObjClass -- Constructor for 2D text objects *
  50. * *
  51. * INPUT: *
  52. * *
  53. * OUTPUT: *
  54. * *
  55. * WARNINGS: *
  56. * *
  57. * HISTORY: *
  58. * 09/08/1997 PWG : Created. *
  59. *========================================================================*/
  60. Text2DObjClass::Text2DObjClass(FontClass &font, const char *str, float screen_x, float screen_y, int fore, int back, ConvertClass &conv, bool center, bool clamp, ...):
  61. DynamicScreenMeshClass(2, 4)
  62. {
  63. char text[255];
  64. // print the variable argument string into an argument list
  65. va_list args;
  66. va_start(args, clamp);
  67. vsprintf(text, str, args);
  68. va_end(args);
  69. Set_Text(font, text, screen_x, screen_y, fore, back, conv, center, clamp);
  70. }
  71. /**************************************************************************
  72. * T2DOC::Text2DObjClass -- Constructor for 2D text objects *
  73. * *
  74. * INPUT: *
  75. * *
  76. * OUTPUT: *
  77. * *
  78. * WARNINGS: *
  79. * *
  80. * HISTORY: *
  81. * 09/08/1997 PWG : Created. *
  82. * 01/28/2000 SKB : Dont' Set font width *
  83. *========================================================================*/
  84. void Text2DObjClass::Set_Text(FontClass &font, const char *str, float screen_x, float screen_y, int fore, int back, ConvertClass &conv, bool center, bool clamp, ...)
  85. {
  86. int resw, resh, resbits;
  87. bool windowed;
  88. // find the resolution (for centering and pixel to pixel translation)
  89. WW3D::Get_Device_Resolution(resw, resh, resbits, windowed);
  90. // print the variable argument string into an argument list
  91. char text[255];
  92. va_list args;
  93. va_start(args, clamp);
  94. vsprintf(text, str, args);
  95. va_end(args);
  96. // if we didn't build a new texture than all the polygons will be just
  97. // fine so we don't need to do anything.
  98. if (!TextTexture.Build_Texture(font, text, fore, back, conv))
  99. return;
  100. // cache the TextTexture elements we think are important on the local
  101. // stack.
  102. srTextureIFace *texture_map = TextTexture.Get_Texture();
  103. int tsize = TextTexture.Get_Texture_Size();
  104. // find the width and height of the text we want to display to the screen
  105. // note that the width could be more than the max width of a texture
  106. // so we must be prepared to break it down into blocks. Theoretically the
  107. // height could be greater than the texture max but lets not be ridiculous
  108. // SKB: 1/25/99 This should not be determined by this function, it
  109. // is up to the caller how he/she wants the font to look.
  110. //font.Set_XSpacing(-1);
  111. int fw = font.String_Pixel_Width(text)+1;
  112. int fh = font.Get_Height()+1;
  113. int mw = (fw & (tsize - 1)) ? (fw / tsize)+1 : (fw /tsize);
  114. // if we requested the text to be centered around a point adjust the
  115. // coordinates accordingly.
  116. float x_delta = 0.0f;
  117. float y_delta = 0.0f;
  118. if (center) {
  119. x_delta = -((float)fw / (float)resw) / 2.0f;
  120. y_delta = -((float)fh / (float)resh) / 2.0f;
  121. }
  122. // Set so user can know where end of string is printed.
  123. _LastWidth = ((float) fw / (float)resw);
  124. _LastHeight = ((float) fh / (float)resh);
  125. // if we requested that the coordinates be checked to ensure they are onscreen,
  126. // adjust the coordinates as neccessary.
  127. if (clamp) {
  128. if (screen_x < 0) screen_x = 0;
  129. if (screen_x + _LastWidth > 1.0f) {
  130. screen_x = 1.0f - _LastWidth;
  131. assert(screen_x >= 0.0f);
  132. }
  133. if (screen_y < 0) screen_y = 0;
  134. if (screen_y + _LastHeight > 1.0f) {
  135. screen_y = 1.0f - _LastHeight;
  136. assert(screen_y >= 0.0f);
  137. }
  138. }
  139. // for every square material it takes two triangles to represent it.
  140. Resize(mw * 2, mw * 4);
  141. // Set texture.
  142. Set_Texture(texture_map);
  143. // Set shader to 2d opaque preset.
  144. Set_Shader(ShaderClass::_PresetOpaque2DShader);
  145. // Sorting is always set on 2D objects so that sortbias can be used to
  146. // determine occlusion between them.
  147. Enable_Sort();
  148. // loop through the rows blocks of our text and make polygons mapped
  149. // with the correct section of our partial texture.
  150. for (int lp = 0; lp < mw; lp ++) {
  151. int pw = MIN(fw - (tsize *lp), tsize);
  152. int ph = fh;
  153. // calculate our actual texture coordinates based on the difference between
  154. // the width and height of the texture and the width and height the font
  155. // occupys.
  156. float tw = (float)pw / (float)tsize;
  157. float th = (float)ph / (float)tsize;
  158. float ty = ((float)fh * (float)lp) / (float)tsize;
  159. // figure out the screen space x and y positions of the object in question.
  160. float x = ((float)lp * (float)tsize) / (float)resw;
  161. // x += (0.5f /resw);
  162. float y = 0;
  163. // y += (0.5f /resh);
  164. // Adjust for centering if needed
  165. x += x_delta;
  166. y += y_delta;
  167. // convert image width and image height to normalized values
  168. float vw = (float)pw / (float)resw;
  169. float vh = (float)ph / (float)resh;
  170. Begin_Tri_Strip();
  171. Vertex( x, y, 0, 0, ty);
  172. Vertex( x + vw, y, 0, tw, ty);
  173. Vertex( x, y + vh, 0, 0, ty + th);
  174. Vertex( x + vw, y + vh, 0, tw, ty + th);
  175. End_Tri_Strip();
  176. }
  177. // fixup screen_x (align it with a pixel edge)
  178. float pixel_x, pixel_y;
  179. WW3D::Get_Pixel_Center(pixel_x, pixel_y);
  180. screen_x *= (float)resw;
  181. screen_x = floor(screen_x) + pixel_x;
  182. screen_x /= (float)resw;
  183. // fixup screen_y (align it with a pixel edge)
  184. screen_y *= (float)resh;
  185. screen_y = floor(screen_y) + pixel_y;
  186. screen_y /= (float)resh;
  187. Set_Position(Vector3(screen_x, screen_y, 0));
  188. Set_Dirty();
  189. }
  190. #endif //WW3D_DX8