Richard Boegli's CnC_Generals_Zero_Hour Fork WIP
This is documentation of Richard Boegil's Zero Hour Fork
 
Loading...
Searching...
No Matches
textdraw.cpp
Go to the documentation of this file.
1/*
2** Command & Conquer Generals Zero Hour(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 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 : Commando *
24 * *
25 * $Archive:: /Commando/Code/ww3d2/textdraw.cpp $*
26 * *
27 * $Author:: Jani_p $*
28 * *
29 * $Modtime:: 3/22/01 8:03p $*
30 * *
31 * $Revision:: 7 $*
32 * *
33 *-------------------------------------------------------------------------*
34 * Functions: *
35 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
36
37#include "textdraw.h"
38#include "font3d.h"
39#include "simplevec.h"
40
41/***********************************************************************************************
42 * *
43 * TextDrawClass::TextDrawClass( int ) -- Constructor *
44 * *
45 * Creates a TextDrawClass object by creating and initializing a Dynamic Mesh, inserting it *
46 * into the given scene, and allocating space for the given number of maximum chars. *
47 * *
48 ***********************************************************************************************/
50 DynamicMeshClass( max_chars * 2, max_chars * 4 ),
51 TextColor( 1.0f, 1.0f, 1.0f )
52{
53 // Build the default Vertex Material
54 DefaultVertexMaterial = NEW_REF( VertexMaterialClass, () );
55 DefaultVertexMaterial->Set_Diffuse( 0, 0, 0 );
56 DefaultVertexMaterial->Set_Opacity(1);
57 DefaultVertexMaterial->Set_Emissive( 1, 1, 1 );
58 Set_Vertex_Material( DefaultVertexMaterial );
59
60 // Build the default Shader
61 DefaultShader.Set_Depth_Mask( ShaderClass::DEPTH_WRITE_DISABLE );
62 DefaultShader.Set_Depth_Compare( ShaderClass::PASS_ALWAYS );
63 DefaultShader.Set_Dst_Blend_Func( ShaderClass::DSTBLEND_ONE_MINUS_SRC_ALPHA );
64 DefaultShader.Set_Src_Blend_Func( ShaderClass::SRCBLEND_SRC_ALPHA );
65 DefaultShader.Set_Texturing( ShaderClass::TEXTURING_ENABLE );
66 DefaultShader.Set_Cull_Mode( ShaderClass::CULL_MODE_DISABLE );
67 Set_Shader( DefaultShader );
69
70 Set_Coordinate_Ranges( Vector2( 0,0 ), Vector2( 1,1 ), Vector2( -1,0.75f ), Vector2( 1,-0.75 ) );
71// Set_Coordinate_Ranges( Vector2( -320,240 ), Vector2( 320,-240 ), Vector2( -320,240 ), Vector2( 320,-240 ) );
72}
73
74/***********************************************************************************************
75 * *
76 * TextDrawClass::~TextDrawClass( void ) -- Destructor *
77 * *
78 ***********************************************************************************************/
80{
81 DefaultVertexMaterial->Release_Ref();
82}
83
84/***********************************************************************************************
85 * *
86 * TextDrawClass::Reset( void ) -- Flush the mesh
87 * *
88 ***********************************************************************************************/
90{
91 Reset_Flags();
93
94 // Reinstall the default vertex material and shader
96 Set_Vertex_Material( DefaultVertexMaterial );
97 Set_Shader( DefaultShader );
98}
99
100/*
101**
102*/
104 const Vector2 & src_ul, const Vector2 & src_lr,
105 const Vector2 & dest_ul, const Vector2 & dest_lr )
106{
107 TranslateScale.X = (dest_lr.X - dest_ul.X) / (src_lr.X - src_ul.X);
108 TranslateScale.Y = (dest_lr.Y - dest_ul.Y) / (src_lr.Y - src_ul.Y);
109 TranslateOffset.X = dest_ul.X - TranslateScale.X * src_ul.X;
110 TranslateOffset.Y = dest_ul.Y - TranslateScale.Y * src_ul.Y;
111
112 PixelSize.X = fabs((src_lr.X - src_ul.X) / 640.0f);
113 PixelSize.Y = fabs((src_lr.Y - src_ul.Y) / 480.0f);
114}
115
116
117/*
118**
119*/
120void TextDrawClass::Quad( float x0, float y0, float x1, float y1, float u0, float v0, float u1, float v1 )
121{
122 // Translate coordinates
123 x0 = x0 * TranslateScale.X + TranslateOffset.X;
124 x1 = x1 * TranslateScale.X + TranslateOffset.X;
125 y0 = y0 * TranslateScale.Y + TranslateOffset.Y;
126 y1 = y1 * TranslateScale.Y + TranslateOffset.Y;
127
128 bool flip_faces = ((x1-x0) * (y1-y0)) > 0;
129
131 Vertex( x0, y0, 0, u0, v0);
132 if ( flip_faces ) {
133 Vertex( x1, y0, 0, u1, v0);
134 Vertex( x0, y1, 0, u0, v1);
135 } else {
136 Vertex( x0, y1, 0, u0, v1);
137 Vertex( x1, y0, 0, u1, v0);
138 }
139 Vertex( x1, y1, 0, u1, v1);
141}
142
143void TextDrawClass::Quad( const RectClass & rect, const RectClass & uv )
144{
145 TextDrawClass::Quad( rect.Left, rect.Top, rect.Right, rect.Bottom, uv.Left, uv.Top, uv.Right, uv.Bottom );
146}
147
148void TextDrawClass::Line( const Vector2 & _a, const Vector2 & _b, float width )
149{
150 // Translate coordinates
151 Vector2 a;
152 Vector2 b;
153 a.X = _a.X * TranslateScale.X + TranslateOffset.X;
154 a.Y = _a.Y * TranslateScale.Y + TranslateOffset.Y;
155 b.X = _b.X * TranslateScale.X + TranslateOffset.X;
156 b.Y = _b.Y * TranslateScale.Y + TranslateOffset.Y;
157 width *= WWMath::Fabs(TranslateScale.X);
158
159 Vector2 corner_offset = a - b; // get line relative to b
160 float temp = corner_offset.X; // Rotate 90
161 corner_offset.X = corner_offset.Y;
162 corner_offset.Y = -temp;
163 corner_offset.Normalize(); // scale to length width/2
164 corner_offset *= width / 2;
165
167 Vertex( a + corner_offset );
168 Vertex( a - corner_offset );
169 Vertex( b + corner_offset );
170 Vertex( b - corner_offset );
172}
173
174void TextDrawClass::Line_Ends( const Vector2 & a, const Vector2 & b, float width, float end_percent )
175{
176 Vector2 a_ = b - a;
177 a_ *= end_percent;
178 a_ += a;
179 Line( a, a_, width );
180 Vector2 b_ = a - b;
181 b_ *= end_percent;
182 b_ += b;
183 Line( b, b_, width );
184}
185
186
187/***********************************************************************************************
188 * *
189 * float TextDrawClass::Get_Width( Font3DInstanceClass *, char * ) *
190 * *
191 * WARNING: Should not be used to draw characters which need to wrap or have embedded line *
192 * feeds. *
193 * *
194 * Returns the scaled string width in normalized screen unit *
195 * *
196 ***********************************************************************************************/
197float TextDrawClass::Get_Width( Font3DInstanceClass *font, const char *message )
198{
199 float total_width = 0.0f;
200
201 /*
202 ** for each character, get_width it
203 */
204 while (*message != 0) {
205 total_width += font->Char_Spacing( *message++ );
206 }
207
208 return total_width;
209}
210
212{
213 // Get rid of this...
214// return font->Get_Inter_Char_Spacing();
215 return 1;
216}
217
218float TextDrawClass::Get_Height( Font3DInstanceClass *font, const char *message )
219{
220 return font->Char_Height();
221}
222
223
224/***********************************************************************************************
225 * *
226 * float TextDrawClass::Print( Font3DInstanceClass *, char, float, float, float ) *
227 * *
228 * Draws (actually creates two trianlges to display) a character on the screen at the given *
229 * normalized screen unit coordinates at the current font scale. *
230 * *
231 * Returns the scaled character width in normalized screen unit *
232 * *
233 ***********************************************************************************************/
234float TextDrawClass::Print( Font3DInstanceClass *font, char ch, float screen_x, float screen_y )
235{
236 /*
237 ** Get the char width in scaled normalized screen units
238 */
239 float width = font->Char_Width( ch ); // in scaled normalized screen units
240 float spacing = font->Char_Spacing( ch ); // in scaled normalized screen units
241
242 /*
243 ** If asked to draw the space char (' '), don't add any triangles, just return the scaled spacing
244 */
245 if (ch == ' ' )
246 return spacing;
247
248 /*
249 ** Calculate the lower right edge of the displayed rectangle
250 */
251 // center each char in its spacing (in case mono spaced )
252 // also, round to the nearest 640x480 pixels (needs to change for other reses)
253 float screen_x0 = screen_x + spacing/2 - width/2;
254 screen_x0 = floor(screen_x0 / PixelSize.X + 0.5f) * PixelSize.X;
255 float screen_x1 = screen_x0 + width;
256 screen_x1 = floor(screen_x1 / PixelSize.X + 0.5f) * PixelSize.X;
257 float screen_y0 = screen_y;
258 screen_y0 = floor(screen_y0 / PixelSize.Y + 0.5f) * PixelSize.Y;
259 float screen_y1 = screen_y0 + (font->Char_Height() * WWMath::Sign( -TranslateScale.Y ));
260 screen_y1 = floor(screen_y1 / PixelSize.Y + 0.5f) * PixelSize.Y;
261
262 if ( WW3D::Is_Screen_UV_Biased() ) { // Global bais setting
263 screen_x0 += PixelSize.X / 2;
264 screen_x1 += PixelSize.X / 2;
265 screen_y0 += PixelSize.Y / 2;
266 screen_y1 += PixelSize.Y / 2;
267 }
268
269 /*
270 ** Get the font texture uv coordinate for teh upper right and lower left corners of the rect
271 */
272 RectClass font_uv = font->Char_UV( ch );
273
274 /*
275 ** Set the triangles' texture
276 */
277 Set_Texture( font->Peek_Texture( ch ) );
278
279 /*
280 ** Draw the quad
281 */
282 Quad( screen_x0, screen_y0, screen_x1, screen_y1, font_uv.Left, font_uv.Top, font_uv.Right, font_uv.Bottom );
283
284 /*
285 ** return the scaled spacing
286 */
287 return spacing;
288}
289
290
291/***********************************************************************************************
292 * *
293 * float TextDrawClass::Print( Font3DInstanceClass *, char *, float, float, float ) *
294 * *
295 * Draws the given string at the given pixel coordinates. Uses the given font and its current *
296 * scale. Passes each character to the above routine and moves the x-coordinate forward after *
297 * each char. * *
298 * *
299 * WARNING: Should not be used to draw characters which need to wrap or have embedded line *
300 * feeds. * *
301 * *
302 * Returns the string pixel width *
303 * *
304 ***********************************************************************************************/
305float TextDrawClass::Print( Font3DInstanceClass *font, const char *message, float screen_x, float screen_y )
306{
307 /*
308 ** Keep track of the total drawn width
309 */
310 float total_width = 0.0f;
311
312 /*
313 ** for each character, print it and moved screen_x forward
314 */
315 while (*message != 0) {
316 float width = Print( font, *message++, screen_x, screen_y );
317 screen_x += width;
318 total_width += width;
319 }
320
321 /*
322 ** return the total drawn width
323 */
324 return total_width;
325}
326
327
328/***********************************************************************************************
329 * *
330 * void TextDrawClass::Show_Font( Font3DInstanceClass *, float, float, float ) *
331 * *
332 * Dumps the font texture to the screen as two triangles. For debugging only. *
333 * *
334 ***********************************************************************************************/
335void TextDrawClass::Show_Font( Font3DInstanceClass *font, float screen_x, float screen_y )
336{
337 // normalize coordinates
338 float size_x = PixelSize.X * 256;
339 float size_y = PixelSize.Y * 256;
340
341 Set_Texture( font->Peek_Texture('A') );
342
343 Quad( screen_x, screen_y, screen_x + size_x, screen_y + size_y * WWMath::Sign( -TranslateScale.Y ) );
344}
DynamicMeshClass(int max_poly, int max_vert)
Definition dynamesh.cpp:521
void Reset_Mesh_Counters()
Definition dynamesh.h:210
bool Vertex(float x, float y, float z, float u, float v)
Definition dynamesh.h:325
void Reset_Flags()
Definition dynamesh.h:204
void Enable_Sort(void)
Definition dynamesh.h:387
int Set_Shader(const ShaderClass &shader, int pass=0)
Definition dynamesh.h:183
int Set_Texture(int idx, int pass=0)
Definition dynamesh.cpp:743
int Set_Vertex_Material(int idx, int pass=0)
Definition dynamesh.cpp:681
void Begin_Tri_Strip(void)
Definition dynamesh.h:240
void End_Tri_Strip(void)
Definition dynamesh.h:340
float Char_Spacing(WCHAR ch) const
Definition font3d.h:184
RectClass Char_UV(WCHAR ch)
Definition font3d.h:203
TextureClass * Peek_Texture(void)
Definition font3d.h:164
float Char_Width(WCHAR ch) const
Definition font3d.h:183
float Char_Height(void) const
Definition font3d.h:185
float Left
Definition rect.h:50
float Top
Definition rect.h:51
float Bottom
Definition rect.h:53
float Right
Definition rect.h:52
@ PASS_ALWAYS
Definition shader.h:110
@ TEXTURING_ENABLE
Definition shader.h:220
@ CULL_MODE_DISABLE
Definition shader.h:158
@ DEPTH_WRITE_DISABLE
Definition shader.h:116
@ SRCBLEND_SRC_ALPHA
Definition shader.h:212
@ DSTBLEND_ONE_MINUS_SRC_ALPHA
Definition shader.h:177
void Quad(float x0, float y0, float x1, float y1, float u0=0, float v0=0, float u1=1, float v1=1)
Definition textdraw.cpp:120
float Print(Font3DInstanceClass *font, char ch, float screen_x, float screen_y)
Definition textdraw.cpp:234
void Show_Font(Font3DInstanceClass *font, float screen_x, float screen_y)
Definition textdraw.cpp:335
virtual void Reset(void)
Definition textdraw.cpp:89
void Set_Coordinate_Ranges(const Vector2 &param_ul, const Vector2 &param_lr, const Vector2 &dest_ul, const Vector2 &dest_lr)
Definition textdraw.cpp:103
void Line(const Vector2 &a, const Vector2 &b, float width)
Definition textdraw.cpp:148
float Get_Width(Font3DInstanceClass *font, const char *message)
Definition textdraw.cpp:197
TextDrawClass(int max_chars)
Definition textdraw.cpp:49
float Get_Inter_Char_Width(Font3DInstanceClass *font)
Definition textdraw.cpp:211
float Get_Height(Font3DInstanceClass *font, const char *message="")
Definition textdraw.cpp:218
void Line_Ends(const Vector2 &a, const Vector2 &b, float width, float end_percent)
Definition textdraw.cpp:174
WWINLINE void Normalize(void)
Definition vector2.h:331
float Y
Definition vector2.h:79
float X
Definition vector2.h:74
static bool Is_Screen_UV_Biased(void)
Definition ww3d.h:223
static float Sign(float val)
Definition wwmath.h:182
static WWINLINE float Fabs(float val)
Definition wwmath.h:113
#define NEW_REF(C, P)
Definition refcount.h:62