3 * Daniel Nelson - 11/10/0
5 * Copyright (C) 2000 Daniel Nelson
6 * Copyright (C) 2004 Andrew Sayman
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 * Daniel Nelson - aluminumangel.org
26 * Holds string display utilities.
40 #include "TextureLoader.h"
42 #include "Displayer.h"
45 const char *String::letter_texture_files
[DC_FONT_NUMBER
][DC_LETTER_NUMBER
]
46 = { { GC_DATA_DIRECTORY
"font0_0.tga",
47 GC_DATA_DIRECTORY
"font0_1.tga",
48 GC_DATA_DIRECTORY
"font0_2.tga",
49 GC_DATA_DIRECTORY
"font0_3.tga",
50 GC_DATA_DIRECTORY
"font0_4.tga",
51 GC_DATA_DIRECTORY
"font0_5.tga",
52 GC_DATA_DIRECTORY
"font0_6.tga",
53 GC_DATA_DIRECTORY
"font0_7.tga",
54 GC_DATA_DIRECTORY
"font0_8.tga",
55 GC_DATA_DIRECTORY
"font0_9.tga",
56 GC_DATA_DIRECTORY
"font0_ca.tga",
57 GC_DATA_DIRECTORY
"font0_cb.tga",
58 GC_DATA_DIRECTORY
"font0_cc.tga",
59 GC_DATA_DIRECTORY
"font0_cd.tga",
60 GC_DATA_DIRECTORY
"font0_ce.tga",
61 GC_DATA_DIRECTORY
"font0_cf.tga",
62 GC_DATA_DIRECTORY
"font0_cg.tga",
63 GC_DATA_DIRECTORY
"font0_ch.tga",
64 GC_DATA_DIRECTORY
"font0_ci.tga",
65 GC_DATA_DIRECTORY
"font0_cj.tga",
66 GC_DATA_DIRECTORY
"font0_ck.tga",
67 GC_DATA_DIRECTORY
"font0_cl.tga",
68 GC_DATA_DIRECTORY
"font0_cm.tga",
69 GC_DATA_DIRECTORY
"font0_cn.tga",
70 GC_DATA_DIRECTORY
"font0_co.tga",
71 GC_DATA_DIRECTORY
"font0_cp.tga",
72 GC_DATA_DIRECTORY
"font0_cq.tga",
73 GC_DATA_DIRECTORY
"font0_cr.tga",
74 GC_DATA_DIRECTORY
"font0_cs.tga",
75 GC_DATA_DIRECTORY
"font0_ct.tga",
76 GC_DATA_DIRECTORY
"font0_cu.tga",
77 GC_DATA_DIRECTORY
"font0_cv.tga",
78 GC_DATA_DIRECTORY
"font0_cw.tga",
79 GC_DATA_DIRECTORY
"font0_cx.tga",
80 GC_DATA_DIRECTORY
"font0_cy.tga",
81 GC_DATA_DIRECTORY
"font0_cz.tga",
82 GC_DATA_DIRECTORY
"font0_a.tga",
83 GC_DATA_DIRECTORY
"font0_b.tga",
84 GC_DATA_DIRECTORY
"font0_c.tga",
85 GC_DATA_DIRECTORY
"font0_d.tga",
86 GC_DATA_DIRECTORY
"font0_e.tga",
87 GC_DATA_DIRECTORY
"font0_f.tga",
88 GC_DATA_DIRECTORY
"font0_g.tga",
89 GC_DATA_DIRECTORY
"font0_h.tga",
90 GC_DATA_DIRECTORY
"font0_i.tga",
91 GC_DATA_DIRECTORY
"font0_j.tga",
92 GC_DATA_DIRECTORY
"font0_k.tga",
93 GC_DATA_DIRECTORY
"font0_l.tga",
94 GC_DATA_DIRECTORY
"font0_m.tga",
95 GC_DATA_DIRECTORY
"font0_n.tga",
96 GC_DATA_DIRECTORY
"font0_o.tga",
97 GC_DATA_DIRECTORY
"font0_p.tga",
98 GC_DATA_DIRECTORY
"font0_q.tga",
99 GC_DATA_DIRECTORY
"font0_r.tga",
100 GC_DATA_DIRECTORY
"font0_s.tga",
101 GC_DATA_DIRECTORY
"font0_t.tga",
102 GC_DATA_DIRECTORY
"font0_u.tga",
103 GC_DATA_DIRECTORY
"font0_v.tga",
104 GC_DATA_DIRECTORY
"font0_w.tga",
105 GC_DATA_DIRECTORY
"font0_x.tga",
106 GC_DATA_DIRECTORY
"font0_y.tga",
107 GC_DATA_DIRECTORY
"font0_z.tga",
108 GC_DATA_DIRECTORY
"font0_mn.tga",
109 GC_DATA_DIRECTORY
"font0_cln.tga",
110 GC_DATA_DIRECTORY
"font0_pe.tga",
111 GC_DATA_DIRECTORY
"font0_cma.tga",
112 GC_DATA_DIRECTORY
"font0_ep.tga",
113 GC_DATA_DIRECTORY
"font0_at.tga",
114 GC_DATA_DIRECTORY
"font0_td.tga",
115 GC_DATA_DIRECTORY
"font0_pd.tga",
116 GC_DATA_DIRECTORY
"font0_ds.tga",
117 GC_DATA_DIRECTORY
"font0_ps.tga",
118 GC_DATA_DIRECTORY
"font0_and.tga",
119 GC_DATA_DIRECTORY
"font0_pl.tga",
120 GC_DATA_DIRECTORY
"font0_pr.tga",
121 GC_DATA_DIRECTORY
"font0_sl.tga",
122 GC_DATA_DIRECTORY
"font0_lt.tga",
123 GC_DATA_DIRECTORY
"font0_gt.tga",
124 GC_DATA_DIRECTORY
"font0_qm.tga",
125 GC_DATA_DIRECTORY
"font0_eq.tga",
126 GC_DATA_DIRECTORY
"font0_pu.tga",
127 GC_DATA_DIRECTORY
"font0_br.tga",
128 GC_DATA_DIRECTORY
"font0_za.tga",
129 GC_DATA_DIRECTORY
"font0_zb.tga",
130 GC_DATA_DIRECTORY
"font0_zc.tga",
131 GC_DATA_DIRECTORY
"font0_zd.tga" } };
133 const char String::letter_mapping
[DC_LETTER_NUMBER
]
134 = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
136 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
137 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
138 'U', 'V', 'W', 'X', 'Y', 'Z',
140 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
141 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
142 'u', 'v', 'w', 'x', 'y', 'z',
144 '-', ':', '.', ',', '!', '@', '~', '#', '$', '%',
145 '&', '(', ')', '/', '<', '>', '?', '=', '+', '|',
146 ';', '[', '*', ']' };
148 const int String::letter_widths
[DC_FONT_NUMBER
][DC_LETTER_NUMBER
]
149 = { { 20, 12, 17, 14, 16, 15, 16, 19, 17, 16,
151 28, 20, 17, 20, 18, 20, 20, 19, 11, 17,
152 19, 17, 30, 20, 20, 21, 22, 22, 16, 21,
153 20, 20, 30, 25, 22, 19,
155 19, 14, 13, 14, 13, 14, 15, 14, 8, 12,
156 14, 12, 22, 15, 14, 14, 16, 16, 12, 15,
157 14, 15, 22, 18, 17, 13,
159 20, 12, 11, 10, 11, 21, 23, 23, 18, 19,
160 20, 12, 13, 18, 16, 16, 17, 20, 23, 16,
164 const float String::colors
[DC_FONT_COLOR_NUMBER
][3]
165 = { { 0.2f
, 0.2f
, 1.0f
},
166 { 1.0f
, 0.1f
, 0.1f
},
167 { 0.1f
, 1.0f
, 0.1f
},
168 { 0.8f
, 0.8f
, 0.1f
},
169 { 0.9f
, 0.0f
, 0.9f
},
170 { 0.1f
, 0.8f
, 0.8f
},
171 { 0.9f
, 0.3f
, 0.1f
},
172 { 1.0f
, 0.5f
, 0.5f
},
173 { 0.4f
, 0.0f
, 1.0f
},
174 { 0.1f
, 0.1f
, 0.1f
} };
176 GLubyte
*String::letter_textures
[DC_FONT_NUMBER
][DC_LETTER_NUMBER
];
178 int String::mapCharToCode ( char c
)
181 for (int n
= DC_LETTER_NUMBER
; n
--; )
182 if (c
== letter_mapping
[n
]) {
189 int String::stringWidth ( const char *string
, int max_width
)
191 * Determines the pixel width of a string.
197 for (unsigned int n
= 0; n
< strlen(string
) && length
< max_width
; n
++) {
199 if (string
[n
] == '~') {
200 switch (string
[++n
]) {
202 if (length
>= DC_BACK_SPACE_WIDTH
) length
-= DC_BACK_SPACE_WIDTH
;
205 length
+= DC_BACK_SPACE_WIDTH
;
208 int c
= string
[n
] - 'a';
209 if (c
>= 0 && c
< DC_FONT_NUMBER
)
214 if (string
[n
] != '~') continue;
216 } else if (string
[n
] == ' ') {
217 length
+= DC_SPACE_WIDTH
;
221 int code
= mapCharToCode(string
[n
]);
223 if (length
+ letter_widths
[font
][code
] > max_width
) break;
224 length
+= letter_widths
[font
][code
];
231 void String::readyLetterTextures ( )
233 for (int n
= DC_FONT_NUMBER
; n
--; )
234 for (int m
= DC_LETTER_NUMBER
; m
--; )
235 letter_textures
[n
][m
]
236 = TextureLoader::loadAlphaTGA(letter_texture_files
[n
][m
],
237 DC_LETTER_TEX_LENGTH
, DC_LETTER_TEX_LENGTH
);
240 void String::freeLetterTextures ( )
242 for (int n
= DC_FONT_NUMBER
; n
--; )
243 for (int m
= DC_LETTER_NUMBER
; m
--; )
244 if (letter_textures
[n
][m
] != null
) {
245 delete [] letter_textures
[n
][m
];
246 letter_textures
[n
][m
] = null
;
251 void String::fillStringTexture ( const char *string
, GLubyte
*texture
,
252 int width
, bool use_alpha
, int texture_width
)
254 * Fills the memory space pointed to by texture with a string texture. The
255 * texture height must equal DC_LETTER_TEX_LENGTH. readyLetterTextures() must
256 * be called first, and freeLetterTextures() must be called after this
257 * function's final use.
260 if (texture_width
== 0)
261 texture_width
= width
;
263 // initialize texture
265 for (int t
= DC_LETTER_TEX_LENGTH
; t
--; )
266 for (int s
= width
; s
--; ) {
267 texture
[(t
* texture_width
+ s
) * 4 + 0] = 0;
268 texture
[(t
* texture_width
+ s
) * 4 + 1] = 0;
269 texture
[(t
* texture_width
+ s
) * 4 + 2] = 0;
270 texture
[(t
* texture_width
+ s
) * 4 + 3] = 255;
275 int base_color
= DC_DEFAULT_FONT_COLOR
;
276 for (unsigned int n
= 0; n
< strlen(string
) && cursor
< width
; n
++) {
279 if (string
[n
] == '~') {
280 switch (string
[++n
]) {
282 if (cursor
> DC_BACK_SPACE_WIDTH
)
283 cursor
-= DC_BACK_SPACE_WIDTH
;
288 cursor
+= DC_BACK_SPACE_WIDTH
;
292 if (isdigit(string
[n
])) {
293 int c
= string
[n
] - '0';
294 if (c
< DC_FONT_COLOR_NUMBER
)
299 int c
= string
[n
] - 'a';
300 if (c
>= 0 && c
< DC_FONT_NUMBER
)
306 if (string
[n
] != '~') continue;
308 } else if (string
[n
] == ' ') {
309 cursor
+= DC_SPACE_WIDTH
;
313 int code
= mapCharToCode(string
[n
]);
314 if (code
== -1) continue;
316 if (cursor
+ letter_widths
[font
][code
] > width
) break;
320 for (int t
= DC_LETTER_TEX_LENGTH
; t
--; )
321 for (int s
= DC_LETTER_TEX_LENGTH
; s
--; ) {
322 if (cursor
+ s
>= width
) continue;
324 float alpha
= letter_textures
[font
][code
][t
* DC_LETTER_TEX_LENGTH
325 + s
] * (1.0f
/ 255.0f
);
326 for (int c
= 3; c
--; ) {
327 float color
= colors
[base_color
][c
] + (1.0f
- colors
[base_color
][c
])
328 * (DC_LETTER_TEX_LENGTH
- t
+ (s
>= letter_widths
[font
][code
]
329 ? DC_LETTER_TEX_LENGTH
: s
+ (DC_LETTER_TEX_LENGTH
330 - letter_widths
[font
][code
])))
331 * (0.5f
/ (float) DC_LETTER_TEX_LENGTH
);
332 float result
= (255.0f
* color
* alpha
)
333 + texture
[(t
* texture_width
+ cursor
+ s
) * 4 + c
];
334 if (result
>= 255.0f
)
335 texture
[(t
* texture_width
+ cursor
+ s
) * 4 + c
] = (GLubyte
) 255;
337 texture
[(t
* texture_width
+ cursor
+ s
) * 4 + c
]
343 for (int t
= DC_LETTER_TEX_LENGTH
; t
--; )
344 for (int s
= DC_LETTER_TEX_LENGTH
; s
--; ) {
345 if (cursor
+ s
>= width
)
347 if (letter_textures
[font
][code
][t
* DC_LETTER_TEX_LENGTH
+ s
] == 0)
350 int old_alpha
= texture
[(t
* texture_width
+ cursor
+ s
) * 4 + 3];
351 int new_alpha
= letter_textures
[font
][code
][t
* DC_LETTER_TEX_LENGTH
353 if (new_alpha
+ old_alpha
>= 255)
354 texture
[(t
* texture_width
+ cursor
+ s
) * 4 + 3] = 255;
356 texture
[(t
* texture_width
+ cursor
+ s
) * 4 + 3]
357 = (GLubyte
) (new_alpha
+ old_alpha
);
359 for (int c
= 3; c
--; ) {
360 float color
= colors
[base_color
][c
] + (1.0f
- colors
[base_color
][c
])
361 * (DC_LETTER_TEX_LENGTH
- t
+ (s
>= letter_widths
[font
][code
]
362 ? DC_LETTER_TEX_LENGTH
: s
+ (DC_LETTER_TEX_LENGTH
363 - letter_widths
[font
][code
])))
364 * (0.5f
/ (float) DC_LETTER_TEX_LENGTH
);
365 float result
= (255.0f
* color
) + (old_alpha
* (1.0f
/ 255.0f
))
366 * texture
[(t
* texture_width
+ cursor
+ s
) * 4 + c
];
367 if (result
>= 255.0f
)
368 texture
[(t
* texture_width
+ cursor
+ s
) * 4 + c
] = 255;
370 texture
[(t
* texture_width
+ cursor
+ s
) * 4 + c
]
375 cursor
+= letter_widths
[font
][code
];