DarkPlaces
Game engine based on the Quake 1 engine by id Software, developed by LadyHavoc
 
gl_draw.c
Go to the documentation of this file.
1/*
2Copyright (C) 1996-1997 Id Software, Inc.
3
4This program is free software; you can redistribute it and/or
5modify it under the terms of the GNU General Public License
6as published by the Free Software Foundation; either version 2
7of the License, or (at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
13See the GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with this program; if not, write to the Free Software
17Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
19*/
20
21#include "quakedef.h"
22#include "image.h"
23#include "wad.h"
24
25#include "cl_video.h"
26
27#include "ft2.h"
28#include "ft2_fontdefs.h"
29
31{
32 // size of pic
34 // this flag indicates that it should be loaded and unloaded on demand
36 // texture flags to upload with
38 // texture may be freed after a while
40 // renderable texture
42 // used for hash lookups
44 // flags - CACHEPICFLAG_NEWPIC for example
45 unsigned int flags;
46 // name of pic
48};
49
52
53cvar_t r_textshadow = {CF_CLIENT | CF_ARCHIVE, "r_textshadow", "0", "draws a shadow on all text to improve readability (note: value controls offset, 1 = 1 pixel, 1.5 = 1.5 pixels, etc)"};
54// these are also read by the dedicated server when sys_colortranslation > 1
55cvar_t r_textbrightness = {CF_SHARED | CF_ARCHIVE, "r_textbrightness", "0", "additional brightness for text color codes (0 keeps colors as is, 1 makes them all white)"};
56cvar_t r_textcontrast = {CF_SHARED | CF_ARCHIVE, "r_textcontrast", "1", "additional contrast for text color codes (1 keeps colors as is, 0 makes them all black)"};
57
58cvar_t r_font_postprocess_blur = {CF_CLIENT | CF_ARCHIVE, "r_font_postprocess_blur", "0", "font blur amount"};
59cvar_t r_font_postprocess_outline = {CF_CLIENT | CF_ARCHIVE, "r_font_postprocess_outline", "0", "font outline amount"};
60cvar_t r_font_postprocess_shadow_x = {CF_CLIENT | CF_ARCHIVE, "r_font_postprocess_shadow_x", "0", "font shadow X shift amount, applied during outlining"};
61cvar_t r_font_postprocess_shadow_y = {CF_CLIENT | CF_ARCHIVE, "r_font_postprocess_shadow_y", "0", "font shadow Y shift amount, applied during outlining"};
62cvar_t r_font_postprocess_shadow_z = {CF_CLIENT | CF_ARCHIVE, "r_font_postprocess_shadow_z", "0", "font shadow Z shift amount, applied during blurring"};
63cvar_t r_font_hinting = {CF_CLIENT | CF_ARCHIVE, "r_font_hinting", "3", "0 = no hinting, 1 = light autohinting, 2 = full autohinting, 3 = full hinting"};
64cvar_t r_font_antialias = {CF_CLIENT | CF_ARCHIVE, "r_font_antialias", "1", "0 = monochrome, 1 = grey" /* , 2 = rgb, 3 = bgr" */};
65cvar_t r_font_always_reload = {CF_CLIENT | CF_ARCHIVE, "r_font_always_reload", "0", "reload a font even given the same loadfont command. useful for trying out different versions of the same font file"};
66cvar_t r_nearest_2d = {CF_CLIENT | CF_ARCHIVE, "r_nearest_2d", "0", "use nearest filtering on all 2d textures (including conchars)"};
67cvar_t r_nearest_conchars = {CF_CLIENT | CF_ARCHIVE, "r_nearest_conchars", "0", "use nearest filtering on conchars texture"};
68
69//=============================================================================
70/* Support Routines */
71
72static cachepic_t *cachepichash[CACHEPICHASHSIZE];
73static cachepic_t cachepics[MAX_CACHED_PICS];
74static int numcachepics;
75
77
78int draw_frame = 1;
79
80/*
81================
82Draw_CachePic
83================
84*/
85// FIXME: move this to client somehow
86cachepic_t *Draw_CachePic_Flags(const char *path, unsigned int cachepicflags)
87{
88 int crc, hashkey;
89 cachepic_t *pic;
90 int texflags;
91
93 if (!(cachepicflags & CACHEPICFLAG_NOCLAMP))
95 if (cachepicflags & CACHEPICFLAG_MIPMAP)
99 if (cachepicflags & CACHEPICFLAG_LINEAR)
101 else if ((cachepicflags & CACHEPICFLAG_NEAREST) || r_nearest_2d.integer)
103
104 // check whether the picture has already been cached
105 crc = CRC_Block((unsigned char *)path, strlen(path));
106 hashkey = ((crc >> 8) ^ crc) % CACHEPICHASHSIZE;
107 for (pic = cachepichash[hashkey];pic;pic = pic->chain)
108 {
109 if (!strcmp(path, pic->name))
110 {
111 // if it was created (or replaced) by Draw_NewPic, just return it
112 if (!(pic->flags & CACHEPICFLAG_NEWPIC))
113 {
114 // reload the pic if texflags changed in important ways
115 // ignore TEXF_COMPRESS when comparing, because fallback pics remove the flag, and ignore TEXF_MIPMAP because QC specifies that
116 if ((pic->texflags ^ texflags) & ~(TEXF_COMPRESS | TEXF_MIPMAP))
117 {
118 Con_DPrintf("Draw_CachePic(\"%s\"): frame %i: reloading pic due to mismatch on flags\n", path, draw_frame);
119 goto reload;
120 }
121 if (!pic->skinframe || !pic->skinframe->base)
122 {
123 if (pic->flags & CACHEPICFLAG_FAILONMISSING)
124 return NULL;
125 Con_DPrintf("Draw_CachePic(\"%s\"): frame %i: reloading pic\n", path, draw_frame);
126 goto reload;
127 }
128 if (!(cachepicflags & CACHEPICFLAG_NOTPERSISTENT))
129 pic->autoload = false; // caller is making this pic persistent
130 }
131 if (pic->skinframe)
132 R_SkinFrame_MarkUsed(pic->skinframe);
133 pic->lastusedframe = draw_frame;
134 return pic;
135 }
136 }
137
139 {
140 Con_DPrintf ("Draw_CachePic(\"%s\"): frame %i: numcachepics == MAX_CACHED_PICS\n", path, draw_frame);
141 // FIXME: support NULL in callers?
142 return cachepics; // return the first one
143 }
144 Con_DPrintf("Draw_CachePic(\"%s\"): frame %i: loading pic%s\n", path, draw_frame, (cachepicflags & CACHEPICFLAG_NOTPERSISTENT) ? " notpersist" : "");
145 pic = cachepics + (numcachepics++);
146 memset(pic, 0, sizeof(*pic));
147 dp_strlcpy (pic->name, path, sizeof(pic->name));
148 // link into list
149 pic->chain = cachepichash[hashkey];
150 cachepichash[hashkey] = pic;
151
152reload:
153 if (pic->skinframe)
154 R_SkinFrame_PurgeSkinFrame(pic->skinframe);
155
156 pic->flags = cachepicflags;
157 pic->texflags = texflags;
158 pic->autoload = (cachepicflags & CACHEPICFLAG_NOTPERSISTENT) != 0;
159 pic->lastusedframe = draw_frame;
160
161 if (pic->skinframe)
162 {
163 // reload image after it was unloaded or texflags changed significantly
164 R_SkinFrame_LoadExternal_SkinFrame(pic->skinframe, pic->name, texflags | TEXF_FORCE_RELOAD, (cachepicflags & CACHEPICFLAG_QUIET) == 0, (cachepicflags & CACHEPICFLAG_FAILONMISSING) == 0);
165 }
166 else
167 {
168 // load high quality image (this falls back to low quality too)
169 pic->skinframe = R_SkinFrame_LoadExternal(pic->name, texflags | TEXF_FORCE_RELOAD, (cachepicflags & CACHEPICFLAG_QUIET) == 0, (cachepicflags & CACHEPICFLAG_FAILONMISSING) == 0);
170 }
171
172 // get the dimensions of the image we loaded (if it was successful)
173 if (pic->skinframe && pic->skinframe->base)
174 {
175 pic->width = R_TextureWidth(pic->skinframe->base);
176 pic->height = R_TextureHeight(pic->skinframe->base);
177 }
178
179 // check for a low quality version of the pic and use its size if possible, to match the stock hud
180 Image_GetStockPicSize(pic->name, &pic->width, &pic->height);
181
182 return pic;
183}
184
185cachepic_t *Draw_CachePic (const char *path)
186{
187 return Draw_CachePic_Flags (path, 0); // default to persistent!
188}
189
190const char *Draw_GetPicName(cachepic_t *pic)
191{
192 if (pic == NULL)
193 return "";
194 return pic->name;
195}
196
197int Draw_GetPicWidth(cachepic_t *pic)
198{
199 if (pic == NULL)
200 return 0;
201 return pic->width;
202}
203
204int Draw_GetPicHeight(cachepic_t *pic)
205{
206 if (pic == NULL)
207 return 0;
208 return pic->height;
209}
210
211qbool Draw_IsPicLoaded(cachepic_t *pic)
212{
213 if (pic == NULL)
214 return false;
215 if (pic->autoload && (!pic->skinframe || !pic->skinframe->base))
216 {
217 Con_DPrintf("Draw_IsPicLoaded(\"%s\"): Loading external skin\n", pic->name);
218 pic->skinframe = R_SkinFrame_LoadExternal(pic->name, pic->texflags | TEXF_FORCE_RELOAD, false, true);
219 }
220 // skinframe will only be NULL if the pic was created with CACHEPICFLAG_FAILONMISSING and not found
221 return pic->skinframe != NULL && pic->skinframe->base != NULL;
222}
223
225{
226 if (pic == NULL)
227 return NULL;
228 if (pic->autoload && (!pic->skinframe || !pic->skinframe->base))
229 {
230 Con_DPrintf("Draw_GetPicTexture(\"%s\"): Loading external skin\n", pic->name);
231 pic->skinframe = R_SkinFrame_LoadExternal(pic->name, pic->texflags | TEXF_FORCE_RELOAD, false, true);
232 }
233 pic->lastusedframe = draw_frame;
234 return pic->skinframe ? pic->skinframe->base : NULL;
235}
236
237void Draw_Frame(void)
238{
239 int i;
240 cachepic_t *pic;
241 static double nextpurgetime;
242 if (nextpurgetime > host.realtime)
243 return;
244 nextpurgetime = host.realtime + 0.05;
245 for (i = 0, pic = cachepics;i < numcachepics;i++, pic++)
246 {
247 if (pic->autoload && pic->skinframe && pic->skinframe->base && pic->lastusedframe < draw_frame - 3)
248 {
249 Con_DPrintf("Draw_Frame(%i): Unloading \"%s\"\n", draw_frame, pic->name);
250 R_SkinFrame_PurgeSkinFrame(pic->skinframe);
251 }
252 }
253 draw_frame++;
254}
255
256cachepic_t *Draw_NewPic(const char *picname, int width, int height, unsigned char *pixels_bgra, textype_t textype, int texflags)
257{
258 int crc, hashkey;
259 cachepic_t *pic;
260
261 crc = CRC_Block((unsigned char *)picname, strlen(picname));
262 hashkey = ((crc >> 8) ^ crc) % CACHEPICHASHSIZE;
263 for (pic = cachepichash[hashkey];pic;pic = pic->chain)
264 if (!strcmp (picname, pic->name))
265 break;
266
267 if (pic)
268 {
269 if (pic->flags & CACHEPICFLAG_NEWPIC && pic->skinframe && pic->skinframe->base && pic->width == width && pic->height == height)
270 {
271 Con_DPrintf("Draw_NewPic(\"%s\"): frame %i: updating texture\n", picname, draw_frame);
272 R_UpdateTexture(pic->skinframe->base, pixels_bgra, 0, 0, 0, width, height, 1, 0);
273 R_SkinFrame_MarkUsed(pic->skinframe);
274 pic->lastusedframe = draw_frame;
275 return pic;
276 }
277 Con_DPrintf("Draw_NewPic(\"%s\"): frame %i: reloading pic because flags/size changed\n", picname, draw_frame);
278 }
279 else
280 {
282 {
283 Con_DPrintf ("Draw_NewPic(\"%s\"): frame %i: numcachepics == MAX_CACHED_PICS\n", picname, draw_frame);
284 // FIXME: support NULL in callers?
285 return cachepics; // return the first one
286 }
287 Con_DPrintf("Draw_NewPic(\"%s\"): frame %i: creating new cachepic\n", picname, draw_frame);
288 pic = cachepics + (numcachepics++);
289 memset(pic, 0, sizeof(*pic));
290 dp_strlcpy (pic->name, picname, sizeof(pic->name));
291 // link into list
292 pic->chain = cachepichash[hashkey];
293 cachepichash[hashkey] = pic;
294 }
295
296 R_SkinFrame_PurgeSkinFrame(pic->skinframe);
297
298 pic->autoload = false;
299 pic->flags = CACHEPICFLAG_NEWPIC; // disable texflags checks in Draw_CachePic
300 pic->flags |= (texflags & TEXF_CLAMP) ? 0 : CACHEPICFLAG_NOCLAMP;
301 pic->flags |= (texflags & TEXF_FORCENEAREST) ? CACHEPICFLAG_NEAREST : 0;
302 pic->width = width;
303 pic->height = height;
304 pic->skinframe = R_SkinFrame_LoadInternalBGRA(picname, texflags | TEXF_FORCE_RELOAD, pixels_bgra, width, height, 0, 0, 0, vid.sRGB2D);
305 pic->lastusedframe = draw_frame;
306 return pic;
307}
308
309void Draw_FreePic(const char *picname)
310{
311 int crc;
312 int hashkey;
313 cachepic_t *pic;
314 // this doesn't really free the pic, but does free its texture
315 crc = CRC_Block((unsigned char *)picname, strlen(picname));
316 hashkey = ((crc >> 8) ^ crc) % CACHEPICHASHSIZE;
317 for (pic = cachepichash[hashkey];pic;pic = pic->chain)
318 {
319 if (!strcmp (picname, pic->name) && pic->skinframe)
320 {
321 Con_DPrintf("Draw_FreePic(\"%s\"): frame %i: freeing pic\n", picname, draw_frame);
322 R_SkinFrame_PurgeSkinFrame(pic->skinframe);
323 return;
324 }
325 }
326}
327
328static float snap_to_pixel_x(float x, float roundUpAt);
329extern int con_linewidth; // to force rewrapping
330void LoadFont(qbool override, const char *name, dp_font_t *fnt, float scale, float voffset)
331{
332 int i, ch;
333 float maxwidth;
334 char widthfile[MAX_QPATH];
335 char *widthbuf;
336 fs_offset_t widthbufsize;
337
338 if(override || !fnt->texpath[0])
339 {
340 dp_strlcpy(fnt->texpath, name, sizeof(fnt->texpath));
341 // load the cvars when the font is FIRST loader
342 fnt->settings.scale = scale;
343 fnt->settings.voffset = voffset;
351 }
352
353 // fix bad scale
354 if (fnt->settings.scale <= 0)
355 fnt->settings.scale = 1;
356
357 if(drawtexturepool == NULL)
358 return; // before gl_draw_start, so will be loaded later
359
360 if(fnt->ft2)
361 {
362 // we are going to reload. clear old ft2 data
363 Font_UnloadFont(fnt->ft2);
364 Mem_Free(fnt->ft2);
365 fnt->ft2 = NULL;
366 }
367
368 if(fnt->req_face != -1)
369 {
370 if(!Font_LoadFont(fnt->texpath, fnt))
371 Con_DPrintf("Failed to load font-file for '%s', it will not support as many characters.\n", fnt->texpath);
372 }
373
375 if(!Draw_IsPicLoaded(fnt->pic))
376 {
377 for (i = 0; i < MAX_FONT_FALLBACKS; ++i)
378 {
379 if (!fnt->fallbacks[i][0])
380 break;
382 if(Draw_IsPicLoaded(fnt->pic))
383 break;
384 }
385 if(!Draw_IsPicLoaded(fnt->pic))
386 {
388 dp_strlcpy(widthfile, "gfx/conchars.width", sizeof(widthfile));
389 }
390 else
391 dpsnprintf(widthfile, sizeof(widthfile), "%s.width", fnt->fallbacks[i]);
392 }
393 else
394 dpsnprintf(widthfile, sizeof(widthfile), "%s.width", fnt->texpath);
395
396 // unspecified width == 1 (base width)
397 for(ch = 0; ch < 256; ++ch)
398 fnt->width_of[ch] = 1;
399
400 // FIXME load "name.width", if it fails, fill all with 1
401 if((widthbuf = (char *) FS_LoadFile(widthfile, tempmempool, true, &widthbufsize)))
402 {
403 float extraspacing = 0;
404 const char *p = widthbuf;
405
406 ch = 0;
407 while(ch < 256)
408 {
409 if(!COM_ParseToken_Simple(&p, false, false, true))
410 return;
411
412 switch(*com_token)
413 {
414 case '0':
415 case '1':
416 case '2':
417 case '3':
418 case '4':
419 case '5':
420 case '6':
421 case '7':
422 case '8':
423 case '9':
424 case '+':
425 case '-':
426 case '.':
427 fnt->width_of[ch] = atof(com_token) + extraspacing;
428 ch++;
429 break;
430 default:
431 if(!strcmp(com_token, "extraspacing"))
432 {
433 if(!COM_ParseToken_Simple(&p, false, false, true))
434 return;
435 extraspacing = atof(com_token);
436 }
437 else if(!strcmp(com_token, "scale"))
438 {
439 if(!COM_ParseToken_Simple(&p, false, false, true))
440 return;
441 fnt->settings.scale = atof(com_token);
442 }
443 else
444 {
445 Con_DPrintf("Warning: skipped unknown font property %s\n", com_token);
446 if(!COM_ParseToken_Simple(&p, false, false, true))
447 return;
448 }
449 break;
450 }
451 }
452
453 Mem_Free(widthbuf);
454 }
455
456 if(fnt->ft2)
457 {
458 for (i = 0; i < MAX_FONT_SIZES; ++i)
459 {
460 ft2_font_map_t *map = Font_MapForIndex(fnt->ft2, i);
461 if (!map)
462 break;
463 for(ch = 0; ch < 256; ++ch)
464 fnt->width_of_ft2[i][ch] = Font_SnapTo(fnt->width_of[ch], 1/map->size);
465 }
466 }
467
468 maxwidth = fnt->width_of[0];
469 for(i = 1; i < 256; ++i)
470 maxwidth = max(maxwidth, fnt->width_of[i]);
471 fnt->maxwidth = maxwidth;
472
473 // fix up maxwidth for overlap
474 fnt->maxwidth *= fnt->settings.scale;
475
476 if(fnt == FONT_CONSOLE)
477 con_linewidth = -1; // rewrap console in next frame
478}
479
481dp_font_t *FindFont(const char *title, qbool allocate_new)
482{
483 int i, oldsize;
484
485 // find font
486 for(i = 0; i < dp_fonts.maxsize; ++i)
487 if(!strcmp(dp_fonts.f[i].title, title))
488 return &dp_fonts.f[i];
489 // if not found - try allocate
490 if (allocate_new)
491 {
492 // find any font with empty title
493 for(i = 0; i < dp_fonts.maxsize; ++i)
494 {
495 if(!strcmp(dp_fonts.f[i].title, ""))
496 {
497 dp_strlcpy(dp_fonts.f[i].title, title, sizeof(dp_fonts.f[i].title));
498 return &dp_fonts.f[i];
499 }
500 }
501 // if no any 'free' fonts - expand buffer
502 oldsize = dp_fonts.maxsize;
505 Con_Printf("FindFont: enlarging fonts buffer (%i -> %i)\n", oldsize, dp_fonts.maxsize);
507 // relink ft2 structures
508 for(i = 0; i < oldsize; ++i)
509 if (dp_fonts.f[i].ft2)
510 dp_fonts.f[i].ft2->settings = &dp_fonts.f[i].settings;
511 // register a font in first expanded slot
512 dp_strlcpy(dp_fonts.f[oldsize].title, title, sizeof(dp_fonts.f[oldsize].title));
513 return &dp_fonts.f[oldsize];
514 }
515 return NULL;
516}
517
518static float snap_to_pixel_x(float x, float roundUpAt)
519{
520 float pixelpos = x * vid.mode.width / vid_conwidth.value;
521 int snap = (int) pixelpos;
522 if (pixelpos - snap >= roundUpAt) ++snap;
523 return ((float)snap * vid_conwidth.value / vid.mode.width);
524 /*
525 x = (int)(x * vid.width / vid_conwidth.value);
526 x = (x * vid_conwidth.value / vid.width);
527 return x;
528 */
529}
530
531static float snap_to_pixel_y(float y, float roundUpAt)
532{
533 float pixelpos = y * vid.mode.height / vid_conheight.value;
534 int snap = (int) pixelpos;
535 if (pixelpos - snap > roundUpAt) ++snap;
536 return ((float)snap * vid_conheight.value / vid.mode.height);
537 /*
538 y = (int)(y * vid.height / vid_conheight.value);
539 y = (y * vid_conheight.value / vid.height);
540 return y;
541 */
542}
543
545{
546 dp_font_t *f;
547 int i, sizes;
548 const char *filelist, *c, *cm;
549 float sz, scale, voffset;
550 char mainfont[MAX_QPATH];
551
552 if(Cmd_Argc(cmd) < 2)
553 {
554 Con_Printf("Available font commands:\n");
555 for(i = 0; i < dp_fonts.maxsize; ++i)
556 if (dp_fonts.f[i].title[0])
557 Con_Printf(" loadfont %s gfx/tgafile[...] [custom switches] [sizes...]\n", dp_fonts.f[i].title);
558 Con_Printf("A font can simply be gfx/tgafile, or alternatively you\n"
559 "can specify multiple fonts and faces\n"
560 "Like this: gfx/vera-sans:2,gfx/fallback:1\n"
561 "to load face 2 of the font gfx/vera-sans and use face 1\n"
562 "of gfx/fallback as fallback font.\n"
563 "You can also specify a list of font sizes to load, like this:\n"
564 "loadfont console gfx/conchars,gfx/fallback 8 12 16 24 32\n"
565 "In many cases, 8 12 16 24 32 should be a good choice.\n"
566 "custom switches:\n"
567 " scale x : scale all characters by this amount when rendering (doesnt change line height)\n"
568 " voffset x : offset all chars vertical when rendering, this is multiplied to character height\n"
569 );
570 return;
571 }
572 f = FindFont(Cmd_Argv(cmd, 1), true);
573 if(f == NULL)
574 {
575 Con_Printf("font function not found\n");
576 return;
577 }
578 else
579 {
580 if (strcmp(cmd->cmdline, f->cmdline) != 0 || r_font_always_reload.integer)
581 dp_strlcpy(f->cmdline, cmd->cmdline, MAX_FONT_CMDLINE);
582 else
583 {
584 Con_DPrintf("LoadFont: font %s is unchanged\n", Cmd_Argv(cmd, 1));
585 return;
586 }
587 }
588
589 if(Cmd_Argc(cmd) < 3)
590 filelist = "gfx/conchars";
591 else
592 filelist = Cmd_Argv(cmd, 2);
593
594 memset(f->fallbacks, 0, sizeof(f->fallbacks));
595 memset(f->fallback_faces, 0, sizeof(f->fallback_faces));
596
597 // first font is handled "normally"
598 c = strchr(filelist, ':');
599 cm = strchr(filelist, ',');
600 if(c && (!cm || c < cm))
601 f->req_face = atoi(c+1);
602 else
603 {
604 f->req_face = 0;
605 c = cm;
606 }
607
608 if(!c || (c - filelist) >= MAX_QPATH)
609 dp_strlcpy(mainfont, filelist, sizeof(mainfont));
610 else
611 {
612 memcpy(mainfont, filelist, c - filelist);
613 mainfont[c - filelist] = 0;
614 }
615
616 for(i = 0; i < MAX_FONT_FALLBACKS; ++i)
617 {
618 c = strchr(filelist, ',');
619 if(!c)
620 break;
621 filelist = c + 1;
622 if(!*filelist)
623 break;
624 c = strchr(filelist, ':');
625 cm = strchr(filelist, ',');
626 if(c && (!cm || c < cm))
627 f->fallback_faces[i] = atoi(c+1);
628 else
629 {
630 f->fallback_faces[i] = 0; // f->req_face; could make it stick to the default-font's face index
631 c = cm;
632 }
633 if(!c || (c-filelist) >= MAX_QPATH)
634 {
635 dp_strlcpy(f->fallbacks[i], filelist, sizeof(mainfont));
636 }
637 else
638 {
639 memcpy(f->fallbacks[i], filelist, c - filelist);
640 f->fallbacks[i][c - filelist] = 0;
641 }
642 }
643
644 // for now: by default load only one size: the default size
645 f->req_sizes[0] = 0;
646 for(i = 1; i < MAX_FONT_SIZES; ++i)
647 f->req_sizes[i] = -1;
648
649 scale = 1;
650 voffset = 0;
651 if(Cmd_Argc(cmd) >= 4)
652 {
653 for(sizes = 0, i = 3; i < Cmd_Argc(cmd); ++i)
654 {
655 // special switches
656 if (!strcmp(Cmd_Argv(cmd, i), "scale"))
657 {
658 i++;
659 if (i < Cmd_Argc(cmd))
660 scale = atof(Cmd_Argv(cmd, i));
661 continue;
662 }
663 if (!strcmp(Cmd_Argv(cmd, i), "voffset"))
664 {
665 i++;
666 if (i < Cmd_Argc(cmd))
667 voffset = atof(Cmd_Argv(cmd, i));
668 continue;
669 }
670
671 if (sizes == -1)
672 continue; // no slot for other sizes
673
674 // parse one of sizes
675 sz = atof(Cmd_Argv(cmd, i));
676 if (sz > 0.001f && sz < 1000.0f) // do not use crap sizes
677 {
678 // search for duplicated sizes
679 int j;
680 for (j=0; j<sizes; j++)
681 if (f->req_sizes[j] == sz)
682 break;
683 if (j != sizes)
684 continue; // sz already in req_sizes, don't add it again
685
686 if (sizes == MAX_FONT_SIZES)
687 {
688 Con_Printf(CON_WARN "Warning: specified more than %i different font sizes, exceding ones are ignored\n", MAX_FONT_SIZES);
689 sizes = -1;
690 continue;
691 }
692 f->req_sizes[sizes] = sz;
693 sizes++;
694 }
695 }
696 }
697
698 LoadFont(true, mainfont, f, scale, voffset);
699}
700
701/*
702===============
703Draw_Init
704===============
705*/
706static void gl_draw_start(void)
707{
708 int i;
709 char vabuf[1024];
711
712 numcachepics = 0;
713 memset(cachepichash, 0, sizeof(cachepichash));
714
715 font_start();
716
717 // load default font textures
718 for(i = 0; i < dp_fonts.maxsize; ++i)
719 if (dp_fonts.f[i].title[0])
720 LoadFont(false, va(vabuf, sizeof(vabuf), "gfx/font_%s", dp_fonts.f[i].title), &dp_fonts.f[i], 1, 0);
721}
722
723static void gl_draw_shutdown(void)
724{
726
728
729 numcachepics = 0;
730 memset(cachepichash, 0, sizeof(cachepichash));
731}
732
733static void gl_draw_newmap(void)
734{
735 int i;
736 font_newmap();
737
738 // mark all of the persistent pics so they are not purged...
739 for (i = 0; i < numcachepics; i++)
740 {
741 cachepic_t *pic = cachepics + i;
742 if (!pic->autoload && pic->skinframe)
743 R_SkinFrame_MarkUsed(pic->skinframe);
744 }
745}
746
747void GL_Draw_Init (void)
748{
749 int i, j;
750
764
765 // allocate fonts storage
766 fonts_mempool = Mem_AllocPool("FONTS", 0, NULL);
769 memset(dp_fonts.f, 0, sizeof(dp_font_t) * dp_fonts.maxsize);
770
771 // assign starting font names
772 dp_strlcpy(FONT_DEFAULT->title, "default", sizeof(FONT_DEFAULT->title));
773 dp_strlcpy(FONT_DEFAULT->texpath, "gfx/conchars", sizeof(FONT_DEFAULT->texpath));
774 dp_strlcpy(FONT_CONSOLE->title, "console", sizeof(FONT_CONSOLE->title));
775 dp_strlcpy(FONT_SBAR->title, "sbar", sizeof(FONT_SBAR->title));
776 dp_strlcpy(FONT_NOTIFY->title, "notify", sizeof(FONT_NOTIFY->title));
777 dp_strlcpy(FONT_CHAT->title, "chat", sizeof(FONT_CHAT->title));
778 dp_strlcpy(FONT_CENTERPRINT->title, "centerprint", sizeof(FONT_CENTERPRINT->title));
779 dp_strlcpy(FONT_INFOBAR->title, "infobar", sizeof(FONT_INFOBAR->title));
780 dp_strlcpy(FONT_MENU->title, "menu", sizeof(FONT_MENU->title));
781 for(i = 0, j = 0; i < MAX_USERFONTS; ++i)
782 if(!FONT_USER(i)->title[0])
783 dpsnprintf(FONT_USER(i)->title, sizeof(FONT_USER(i)->title), "user%d", j++);
784
785 Cmd_AddCommand(CF_CLIENT, "loadfont", LoadFont_f, "loadfont function tganame loads a font; example: loadfont console gfx/veramono; loadfont without arguments lists the available functions");
787}
788
794
796
797void DrawQ_Pic(float x, float y, cachepic_t *pic, float width, float height, float red, float green, float blue, float alpha, int flags)
798{
800 msurface_t *surf;
801 int e0, e1, e2, e3;
802 if (!pic)
803 pic = Draw_CachePic("white");
804 // make sure pic is loaded - we don't use the texture here, Mod_Mesh_GetTexture looks up the skinframe by name
806 if (width == 0)
807 width = pic->width;
808 if (height == 0)
809 height = pic->height;
811 e0 = Mod_Mesh_IndexForVertex(mod, surf, x , y , 0, 0, 0, -1, 0, 0, 0, 0, red, green, blue, alpha);
812 e1 = Mod_Mesh_IndexForVertex(mod, surf, x + width, y , 0, 0, 0, -1, 1, 0, 0, 0, red, green, blue, alpha);
813 e2 = Mod_Mesh_IndexForVertex(mod, surf, x + width, y + height, 0, 0, 0, -1, 1, 1, 0, 0, red, green, blue, alpha);
814 e3 = Mod_Mesh_IndexForVertex(mod, surf, x , y + height, 0, 0, 0, -1, 0, 1, 0, 0, red, green, blue, alpha);
815 Mod_Mesh_AddTriangle(mod, surf, e0, e1, e2);
816 Mod_Mesh_AddTriangle(mod, surf, e0, e2, e3);
817}
818
819void DrawQ_RotPic(float x, float y, cachepic_t *pic, float width, float height, float org_x, float org_y, float angle, float red, float green, float blue, float alpha, int flags)
820{
821 float af = DEG2RAD(-angle); // forward
822 float ar = DEG2RAD(-angle + 90); // right
823 float sinaf = sin(af);
824 float cosaf = cos(af);
825 float sinar = sin(ar);
826 float cosar = cos(ar);
828 msurface_t *surf;
829 int e0, e1, e2, e3;
830 if (!pic)
831 pic = Draw_CachePic("white");
832 // make sure pic is loaded - we don't use the texture here, Mod_Mesh_GetTexture looks up the skinframe by name
834 if (width == 0)
835 width = pic->width;
836 if (height == 0)
837 height = pic->height;
839 e0 = Mod_Mesh_IndexForVertex(mod, surf, x - cosaf * org_x - cosar * org_y , y - sinaf * org_x - sinar * org_y , 0, 0, 0, -1, 0, 0, 0, 0, red, green, blue, alpha);
840 e1 = Mod_Mesh_IndexForVertex(mod, surf, x + cosaf * (width - org_x) - cosar * org_y , y + sinaf * (width - org_x) - sinar * org_y , 0, 0, 0, -1, 1, 0, 0, 0, red, green, blue, alpha);
841 e2 = Mod_Mesh_IndexForVertex(mod, surf, x + cosaf * (width - org_x) + cosar * (height - org_y), y + sinaf * (width - org_x) + sinar * (height - org_y), 0, 0, 0, -1, 1, 1, 0, 0, red, green, blue, alpha);
842 e3 = Mod_Mesh_IndexForVertex(mod, surf, x - cosaf * org_x + cosar * (height - org_y), y - sinaf * org_x + sinar * (height - org_y), 0, 0, 0, -1, 0, 1, 0, 0, red, green, blue, alpha);
843 Mod_Mesh_AddTriangle(mod, surf, e0, e1, e2);
844 Mod_Mesh_AddTriangle(mod, surf, e0, e2, e3);
845}
846
847void DrawQ_Fill(float x, float y, float width, float height, float red, float green, float blue, float alpha, int flags)
848{
849 DrawQ_Pic(x, y, Draw_CachePic("white"), width, height, red, green, blue, alpha, flags);
850}
851
854{
855 // Quake3 colors
856 // LadyHavoc: why on earth is cyan before magenta in Quake3?
857 // LadyHavoc: note: Doom3 uses white for [0] and [7]
858 {0.0, 0.0, 0.0, 1.0}, // black
859 {1.0, 0.0, 0.0, 1.0}, // red
860 {0.0, 1.0, 0.0, 1.0}, // green
861 {1.0, 1.0, 0.0, 1.0}, // yellow
862 //{0.0, 0.0, 1.0, 1.0}, // blue
863 {0.05, 0.15, 1.0, 1.0}, // lighter blue, readable unlike the above
864 {0.0, 1.0, 1.0, 1.0}, // cyan
865 {1.0, 0.0, 1.0, 1.0}, // magenta
866 {1.0, 1.0, 1.0, 1.0}, // white
867 // [515]'s BX_COLOREDTEXT extension
868 {1.0, 1.0, 1.0, 0.5}, // half transparent
869 {0.5, 0.5, 0.5, 1.0} // half brightness
870 // Black's color table
871 //{1.0, 1.0, 1.0, 1.0},
872 //{1.0, 0.0, 0.0, 1.0},
873 //{0.0, 1.0, 0.0, 1.0},
874 //{0.0, 0.0, 1.0, 1.0},
875 //{1.0, 1.0, 0.0, 1.0},
876 //{0.0, 1.0, 1.0, 1.0},
877 //{1.0, 0.0, 1.0, 1.0},
878 //{0.1, 0.1, 0.1, 1.0}
879};
880
881#define STRING_COLORS_COUNT (sizeof(string_colors) / sizeof(vec4_t))
882
883static void DrawQ_GetTextColor(float color[4], int colorindex, float r, float g, float b, float a, qbool shadow)
884{
885 float C = r_textcontrast.value;
886 float B = r_textbrightness.value;
887 if (colorindex & 0x10000) // that bit means RGB color
888 {
889 color[0] = ((colorindex >> 12) & 0xf) / 15.0;
890 color[1] = ((colorindex >> 8) & 0xf) / 15.0;
891 color[2] = ((colorindex >> 4) & 0xf) / 15.0;
892 color[3] = (colorindex & 0xf) / 15.0;
893 }
894 else
895 Vector4Copy(string_colors[colorindex], color);
896 Vector4Set(color, color[0] * r * C + B, color[1] * g * C + B, color[2] * b * C + B, color[3] * a);
897 if (shadow)
898 {
899 float shadowalpha = (color[0]+color[1]+color[2]) * 0.8;
900 Vector4Set(color, 0, 0, 0, color[3] * bound(0, shadowalpha, 1));
901 }
902}
903
904// returns a colorindex (format 0x1RGBA) if str is a valid RGB string
905// returns 0 otherwise
906static int RGBstring_to_colorindex(const char *str)
907{
908 Uchar ch;
909 int ind = 0x0001 << 4;
910 do {
911 if (*str <= '9' && *str >= '0')
912 ind |= (*str - '0');
913 else
914 {
915 ch = tolower(*str);
916 if (ch >= 'a' && ch <= 'f')
917 ind |= (ch - 87);
918 else
919 return 0;
920 }
921 ++str;
922 ind <<= 4;
923 } while(!(ind & 0x10000));
924 return ind | 0xf; // add costant alpha value
925}
926
927// NOTE: this function always draws exactly one character if maxwidth <= 0
928float DrawQ_TextWidth_UntilWidth_TrackColors_Scale(const char *text, size_t *maxlen, float w, float h, float sw, float sh, int *outcolor, qbool ignorecolorcodes, const dp_font_t *fnt, float maxwidth)
929{
930 const char *text_start = text;
931 int colorindex;
932 size_t i;
933 float x = 0;
934 Uchar ch, mapch, nextch;
935 Uchar prevch = 0; // used for kerning
936 float kx;
937 int map_index = 0;
938 size_t bytes_left;
939 ft2_font_map_t *fontmap = NULL;
940 ft2_font_map_t *map = NULL;
941 ft2_font_t *ft2 = fnt->ft2;
942 // float ftbase_x;
943 qbool snap = true;
944 qbool least_one = false;
945 float dw; // display w
946 //float dh; // display h
947 const float *width_of;
948
949 if (!h) h = w;
950 if (!h) {
951 w = h = 1;
952 snap = false;
953 }
954 // do this in the end
955 w *= fnt->settings.scale;
956 h *= fnt->settings.scale;
957
958 // find the most fitting size:
959 if (ft2 != NULL)
960 {
961 if (snap)
962 map_index = Font_IndexForSize(ft2, h, &w, &h);
963 else
964 map_index = Font_IndexForSize(ft2, h, NULL, NULL);
965 fontmap = Font_MapForIndex(ft2, map_index);
966 }
967
968 dw = w * sw;
969 //dh = h * sh;
970
971 if (*maxlen < 1)
972 *maxlen = 1<<30;
973
974 if (!outcolor || *outcolor == -1)
975 colorindex = STRING_COLOR_DEFAULT;
976 else
977 colorindex = *outcolor;
978
979 // maxwidth /= fnt->scale; // w and h are multiplied by it already
980 // ftbase_x = snap_to_pixel_x(0);
981
982 if(maxwidth <= 0)
983 {
984 least_one = true;
985 maxwidth = -maxwidth;
986 }
987
988 //if (snap)
989 // x = snap_to_pixel_x(x, 0.4); // haha, it's 0 anyway
990
991 if (fontmap)
992 width_of = fnt->width_of_ft2[map_index];
993 else
994 width_of = fnt->width_of;
995
996 i = 0;
997 while (((bytes_left = *maxlen - (text - text_start)) > 0) && *text)
998 {
999 size_t i0 = i;
1000 nextch = ch = u8_getnchar(text, &text, bytes_left);
1001 i = text - text_start;
1002 if (!ch)
1003 break;
1004 if (ch == ' ' && !fontmap)
1005 {
1006 if(!least_one || i0) // never skip the first character
1007 if(x + width_of[(int) ' '] * dw > maxwidth)
1008 {
1009 i = i0;
1010 break; // oops, can't draw this
1011 }
1012 x += width_of[(int) ' '] * dw;
1013 continue;
1014 }
1015 if (ch == STRING_COLOR_TAG && !ignorecolorcodes && i < *maxlen)
1016 {
1017 ch = *text; // colors are ascii, so no u8_ needed
1018 if (ch <= '9' && ch >= '0') // ^[0-9] found
1019 {
1020 colorindex = ch - '0';
1021 ++text;
1022 ++i;
1023 continue;
1024 }
1025 else if (ch == STRING_COLOR_RGB_TAG_CHAR && i + 3 < *maxlen ) // ^x found
1026 {
1027 const char *text_p = &text[1];
1028 int tempcolorindex = RGBstring_to_colorindex(text_p);
1029 if (tempcolorindex)
1030 {
1031 colorindex = tempcolorindex;
1032 i+=4;
1033 text += 4;
1034 continue;
1035 }
1036 }
1037 else if (ch == STRING_COLOR_TAG) // ^^ found
1038 {
1039 i++;
1040 text++;
1041 }
1042 i--;
1043 }
1044 ch = nextch;
1045
1046 if (!fontmap || (ch <= 0xFF && fontmap->glyphs[ch].image) || (ch >= 0xE000 && ch <= 0xE0FF))
1047 {
1048 if (ch > 0xE000)
1049 ch -= 0xE000;
1050 if (ch > 0xFF)
1051 continue;
1052 if (fontmap)
1053 map = ft2_oldstyle_map;
1054 prevch = 0;
1055 if(!least_one || i0) // never skip the first character
1056 if(x + width_of[ch] * dw > maxwidth)
1057 {
1058 i = i0;
1059 break; // oops, can't draw this
1060 }
1061 x += width_of[ch] * dw;
1062 } else {
1063 if (!map || map == ft2_oldstyle_map || ch != prevch)
1064 {
1065 Font_GetMapForChar(ft2, map_index, ch, &map, &mapch);
1066 if (!map)
1067 break;
1068 }
1069 if (prevch && Font_GetKerningForMap(ft2, map_index, w, h, prevch, ch, &kx, NULL))
1070 x += kx * dw;
1071 x += map->glyphs[mapch].advance_x * dw;
1072 prevch = ch;
1073 }
1074 }
1075
1076 *maxlen = i;
1077
1078 if (outcolor)
1079 *outcolor = colorindex;
1080
1081 return x;
1082}
1083
1085float DrawQ_String_Scale(float startx, float starty, const char *text, size_t maxlen, float w, float h, float sw, float sh, float basered, float basegreen, float baseblue, float basealpha, int flags, int *outcolor, qbool ignorecolorcodes, const dp_font_t *fnt)
1086{
1087 int shadow, colorindex = STRING_COLOR_DEFAULT;
1088 size_t i;
1089 float x = startx, y, s, t, u, v, thisw;
1090 Uchar ch, mapch, nextch;
1091 Uchar prevch = 0; // used for kerning
1092 int map_index = 0;
1093 ft2_font_map_t *map = NULL; // the currently used map
1094 ft2_font_map_t *fontmap = NULL; // the font map for the size
1095 float ftbase_y;
1096 const char *text_start = text;
1097 float kx, ky;
1098 ft2_font_t *ft2 = fnt->ft2;
1099 qbool snap = true;
1100 float pix_x, pix_y;
1101 size_t bytes_left;
1102 float dw, dh;
1103 const float *width_of;
1104 model_t *mod = CL_Mesh_UI();
1105 msurface_t *surf = NULL;
1106 int e0, e1, e2, e3;
1107 int tw, th;
1108 tw = Draw_GetPicWidth(fnt->pic);
1109 th = Draw_GetPicHeight(fnt->pic);
1110
1111 if (!h) h = w;
1112 if (!h) {
1113 h = w = 1;
1114 snap = false;
1115 }
1116
1117 starty -= (fnt->settings.scale - 1) * h * 0.5 - fnt->settings.voffset*h; // center & offset
1118 w *= fnt->settings.scale;
1119 h *= fnt->settings.scale;
1120
1121 if (ft2 != NULL)
1122 {
1123 if (snap)
1124 map_index = Font_IndexForSize(ft2, h, &w, &h);
1125 else
1126 map_index = Font_IndexForSize(ft2, h, NULL, NULL);
1127 fontmap = Font_MapForIndex(ft2, map_index);
1128 }
1129
1130 dw = w * sw;
1131 dh = h * sh;
1132
1133 // draw the font at its baseline when using freetype
1134 //ftbase_x = 0;
1135 ftbase_y = dh * (4.5/6.0);
1136
1137 if (maxlen < 1)
1138 maxlen = 1<<30;
1139
1141 return startx + DrawQ_TextWidth_UntilWidth_TrackColors_Scale(text, &maxlen, w, h, sw, sh, NULL, ignorecolorcodes, fnt, 1000000000);
1142
1143 //ftbase_x = snap_to_pixel_x(ftbase_x);
1144 if(snap)
1145 {
1146 startx = snap_to_pixel_x(startx, 0.4);
1147 starty = snap_to_pixel_y(starty, 0.4);
1148 ftbase_y = snap_to_pixel_y(ftbase_y, 0.3);
1149 }
1150
1151 pix_x = vid.mode.width / vid_conwidth.value;
1152 pix_y = vid.mode.height / vid_conheight.value;
1153
1154 if (fontmap)
1155 width_of = fnt->width_of_ft2[map_index];
1156 else
1157 width_of = fnt->width_of;
1158
1159 for (shadow = r_textshadow.value != 0 && basealpha > 0;shadow >= 0;shadow--)
1160 {
1161 prevch = 0;
1162 text = text_start;
1163
1164 if (!outcolor || *outcolor == -1)
1165 colorindex = STRING_COLOR_DEFAULT;
1166 else
1167 colorindex = *outcolor;
1168
1169 DrawQ_GetTextColor(DrawQ_Color, colorindex, basered, basegreen, baseblue, basealpha, shadow != 0);
1170
1171 x = startx;
1172 y = starty;
1173 /*
1174 if (shadow)
1175 {
1176 x += r_textshadow.value * vid.width / vid_conwidth.value;
1177 y += r_textshadow.value * vid.height / vid_conheight.value;
1178 }
1179 */
1180 while (((bytes_left = maxlen - (text - text_start)) > 0) && *text)
1181 {
1182 nextch = ch = u8_getnchar(text, &text, bytes_left);
1183 i = text - text_start;
1184 if (!ch)
1185 break;
1186 if (ch == ' ' && !fontmap)
1187 {
1188 x += width_of[(int) ' '] * dw;
1189 continue;
1190 }
1191 if (ch == STRING_COLOR_TAG && !ignorecolorcodes && i < maxlen)
1192 {
1193 ch = *text; // colors are ascii, so no u8_ needed
1194 if (ch <= '9' && ch >= '0') // ^[0-9] found
1195 {
1196 colorindex = ch - '0';
1197 DrawQ_GetTextColor(DrawQ_Color, colorindex, basered, basegreen, baseblue, basealpha, shadow != 0);
1198 ++text;
1199 ++i;
1200 continue;
1201 }
1202 else if (ch == STRING_COLOR_RGB_TAG_CHAR && i+3 < maxlen ) // ^x found
1203 {
1204 const char *text_p = &text[1];
1205 int tempcolorindex = RGBstring_to_colorindex(text_p);
1206 if(tempcolorindex)
1207 {
1208 colorindex = tempcolorindex;
1209 DrawQ_GetTextColor(DrawQ_Color, colorindex, basered, basegreen, baseblue, basealpha, shadow != 0);
1210 i+=4;
1211 text+=4;
1212 continue;
1213 }
1214 }
1215 else if (ch == STRING_COLOR_TAG)
1216 {
1217 i++;
1218 text++;
1219 }
1220 i--;
1221 }
1222 // get the backup
1223 ch = nextch;
1224 // using a value of -1 for the oldstyle map because NULL means uninitialized...
1225 // this way we don't need to rebind fnt->tex for every old-style character
1226 // E000..E0FF: emulate old-font characters (to still have smileys and such available)
1227 if (shadow)
1228 {
1229 x += 1.0/pix_x * r_textshadow.value;
1230 y += 1.0/pix_y * r_textshadow.value;
1231 }
1232 if (!fontmap || (ch <= 0xFF && fontmap->glyphs[ch].image) || (ch >= 0xE000 && ch <= 0xE0FF))
1233 {
1234 if (ch >= 0xE000)
1235 ch -= 0xE000;
1236 if (ch > 0xFF)
1237 goto out;
1238 if (fontmap)
1239 map = ft2_oldstyle_map;
1240 prevch = 0;
1241 //num = (unsigned char) text[i];
1242 //thisw = fnt->width_of[num];
1243 thisw = fnt->width_of[ch];
1244 // FIXME make these smaller to just include the occupied part of the character for slightly faster rendering
1246 {
1247 s = (ch & 15)*0.0625f;
1248 t = (ch >> 4)*0.0625f;
1249 u = 0.0625f * thisw;
1250 v = 0.0625f;
1251 }
1252 else
1253 {
1254 s = (ch & 15)*0.0625f + (0.5f / tw);
1255 t = (ch >> 4)*0.0625f + (0.5f / th);
1256 u = 0.0625f * thisw - (1.0f / tw);
1257 v = 0.0625f - (1.0f / th);
1258 }
1260 e0 = Mod_Mesh_IndexForVertex(mod, surf, x , y , 10, 0, 0, -1, s , t , 0, 0, DrawQ_Color[0], DrawQ_Color[1], DrawQ_Color[2], DrawQ_Color[3]);
1261 e1 = Mod_Mesh_IndexForVertex(mod, surf, x+dw*thisw, y , 10, 0, 0, -1, s+u, t , 0, 0, DrawQ_Color[0], DrawQ_Color[1], DrawQ_Color[2], DrawQ_Color[3]);
1262 e2 = Mod_Mesh_IndexForVertex(mod, surf, x+dw*thisw, y+dh, 10, 0, 0, -1, s+u, t+v, 0, 0, DrawQ_Color[0], DrawQ_Color[1], DrawQ_Color[2], DrawQ_Color[3]);
1263 e3 = Mod_Mesh_IndexForVertex(mod, surf, x , y+dh, 10, 0, 0, -1, s , t+v, 0, 0, DrawQ_Color[0], DrawQ_Color[1], DrawQ_Color[2], DrawQ_Color[3]);
1264 Mod_Mesh_AddTriangle(mod, surf, e0, e1, e2);
1265 Mod_Mesh_AddTriangle(mod, surf, e0, e2, e3);
1266 x += width_of[ch] * dw;
1267 } else {
1268 if (!map || map == ft2_oldstyle_map || ch != prevch)
1269 {
1270 Font_GetMapForChar(ft2, map_index, ch, &map, &mapch);
1271 if (!map)
1272 {
1273 shadow = -1;
1274 break;
1275 }
1276 }
1277
1278 thisw = map->glyphs[mapch].advance_x;
1279
1280 //x += ftbase_x;
1281 y += ftbase_y;
1282 if (prevch && Font_GetKerningForMap(ft2, map_index, w, h, prevch, ch, &kx, &ky))
1283 {
1284 x += kx * dw;
1285 y += ky * dh;
1286 }
1287 else
1288 kx = ky = 0;
1290 e0 = Mod_Mesh_IndexForVertex(mod, surf, x + dw * map->glyphs[mapch].vxmin, y + dh * map->glyphs[mapch].vymin, 10, 0, 0, -1, map->glyphs[mapch].txmin, map->glyphs[mapch].tymin, 0, 0, DrawQ_Color[0], DrawQ_Color[1], DrawQ_Color[2], DrawQ_Color[3]);
1291 e1 = Mod_Mesh_IndexForVertex(mod, surf, x + dw * map->glyphs[mapch].vxmax, y + dh * map->glyphs[mapch].vymin, 10, 0, 0, -1, map->glyphs[mapch].txmax, map->glyphs[mapch].tymin, 0, 0, DrawQ_Color[0], DrawQ_Color[1], DrawQ_Color[2], DrawQ_Color[3]);
1292 e2 = Mod_Mesh_IndexForVertex(mod, surf, x + dw * map->glyphs[mapch].vxmax, y + dh * map->glyphs[mapch].vymax, 10, 0, 0, -1, map->glyphs[mapch].txmax, map->glyphs[mapch].tymax, 0, 0, DrawQ_Color[0], DrawQ_Color[1], DrawQ_Color[2], DrawQ_Color[3]);
1293 e3 = Mod_Mesh_IndexForVertex(mod, surf, x + dw * map->glyphs[mapch].vxmin, y + dh * map->glyphs[mapch].vymax, 10, 0, 0, -1, map->glyphs[mapch].txmin, map->glyphs[mapch].tymax, 0, 0, DrawQ_Color[0], DrawQ_Color[1], DrawQ_Color[2], DrawQ_Color[3]);
1294 Mod_Mesh_AddTriangle(mod, surf, e0, e1, e2);
1295 Mod_Mesh_AddTriangle(mod, surf, e0, e2, e3);
1296 //x -= ftbase_x;
1297 y -= ftbase_y;
1298
1299 x += thisw * dw;
1300
1301 //prevmap = map;
1302 prevch = ch;
1303 }
1304out:
1305 if (shadow)
1306 {
1307 x -= 1.0/pix_x * r_textshadow.value;
1308 y -= 1.0/pix_y * r_textshadow.value;
1309 }
1310 }
1311 }
1312
1313 if (outcolor)
1314 *outcolor = colorindex;
1315
1316 // note: this relies on the proper text (not shadow) being drawn last
1317 return x;
1318}
1319
1320float DrawQ_String(float startx, float starty, const char *text, size_t maxlen, float w, float h, float basered, float basegreen, float baseblue, float basealpha, int flags, int *outcolor, qbool ignorecolorcodes, const dp_font_t *fnt)
1321{
1322 return DrawQ_String_Scale(startx, starty, text, maxlen, w, h, 1, 1, basered, basegreen, baseblue, basealpha, flags, outcolor, ignorecolorcodes, fnt);
1323}
1324
1325float DrawQ_TextWidth_UntilWidth_TrackColors(const char *text, size_t *maxlen, float w, float h, int *outcolor, qbool ignorecolorcodes, const dp_font_t *fnt, float maxwidth)
1326{
1327 return DrawQ_TextWidth_UntilWidth_TrackColors_Scale(text, maxlen, w, h, 1, 1, outcolor, ignorecolorcodes, fnt, maxwidth);
1328}
1329
1330float DrawQ_TextWidth(const char *text, size_t maxlen, float w, float h, qbool ignorecolorcodes, const dp_font_t *fnt)
1331{
1332 return DrawQ_TextWidth_UntilWidth(text, &maxlen, w, h, ignorecolorcodes, fnt, 1000000000);
1333}
1334
1335float DrawQ_TextWidth_UntilWidth(const char *text, size_t *maxlen, float w, float h, qbool ignorecolorcodes, const dp_font_t *fnt, float maxWidth)
1336{
1337 return DrawQ_TextWidth_UntilWidth_TrackColors(text, maxlen, w, h, NULL, ignorecolorcodes, fnt, maxWidth);
1338}
1339
1340#if 0
1341// not used
1342// no ^xrgb management
1343static int DrawQ_BuildColoredText(char *output2c, size_t maxoutchars, const char *text, int maxreadchars, qbool ignorecolorcodes, int *outcolor)
1344{
1345 int color, numchars = 0;
1346 char *outputend2c = output2c + maxoutchars - 2;
1347 if (!outcolor || *outcolor == -1)
1349 else
1350 color = *outcolor;
1351 if (!maxreadchars)
1352 maxreadchars = 1<<30;
1353 textend = text + maxreadchars;
1354 while (text != textend && *text)
1355 {
1356 if (*text == STRING_COLOR_TAG && !ignorecolorcodes && text + 1 != textend)
1357 {
1358 if (text[1] == STRING_COLOR_TAG)
1359 text++;
1360 else if (text[1] >= '0' && text[1] <= '9')
1361 {
1362 color = text[1] - '0';
1363 text += 2;
1364 continue;
1365 }
1366 }
1367 if (output2c >= outputend2c)
1368 break;
1369 *output2c++ = *text++;
1370 *output2c++ = color;
1371 numchars++;
1372 }
1373 output2c[0] = output2c[1] = 0;
1374 if (outcolor)
1375 *outcolor = color;
1376 return numchars;
1377}
1378#endif
1379
1380void DrawQ_SuperPic(float x, float y, cachepic_t *pic, float width, float height, float s1, float t1, float r1, float g1, float b1, float a1, float s2, float t2, float r2, float g2, float b2, float a2, float s3, float t3, float r3, float g3, float b3, float a3, float s4, float t4, float r4, float g4, float b4, float a4, int flags)
1381{
1382 model_t *mod = CL_Mesh_UI();
1383 msurface_t *surf;
1384 int e0, e1, e2, e3;
1385 if (!pic)
1386 pic = Draw_CachePic("white");
1387 // make sure pic is loaded - we don't use the texture here, Mod_Mesh_GetTexture looks up the skinframe by name
1388 Draw_GetPicTexture(pic);
1389 if (width == 0)
1390 width = pic->width;
1391 if (height == 0)
1392 height = pic->height;
1394 e0 = Mod_Mesh_IndexForVertex(mod, surf, x , y , 0, 0, 0, -1, s1, t1, 0, 0, r1, g1, b1, a1);
1395 e1 = Mod_Mesh_IndexForVertex(mod, surf, x + width, y , 0, 0, 0, -1, s2, t2, 0, 0, r2, g2, b2, a2);
1396 e2 = Mod_Mesh_IndexForVertex(mod, surf, x + width, y + height, 0, 0, 0, -1, s4, t4, 0, 0, r4, g4, b4, a4);
1397 e3 = Mod_Mesh_IndexForVertex(mod, surf, x , y + height, 0, 0, 0, -1, s3, t3, 0, 0, r3, g3, b3, a3);
1398 Mod_Mesh_AddTriangle(mod, surf, e0, e1, e2);
1399 Mod_Mesh_AddTriangle(mod, surf, e0, e2, e3);
1400}
1401
1402void DrawQ_Line (float width, float x1, float y1, float x2, float y2, float r, float g, float b, float alpha, int flags)
1403{
1404 model_t *mod = CL_Mesh_UI();
1405 msurface_t *surf;
1406 int e0, e1, e2, e3;
1407 float offsetx, offsety;
1408 // width is measured in real pixels
1409 if (fabs(x2 - x1) > fabs(y2 - y1))
1410 {
1411 offsetx = 0;
1412 offsety = 0.5f * width * vid_conheight.value / vid.mode.height;
1413 }
1414 else
1415 {
1416 offsetx = 0.5f * width * vid_conwidth.value / vid.mode.width;
1417 offsety = 0;
1418 }
1420 e0 = Mod_Mesh_IndexForVertex(mod, surf, x1 - offsetx, y1 - offsety, 10, 0, 0, -1, 0, 0, 0, 0, r, g, b, alpha);
1421 e1 = Mod_Mesh_IndexForVertex(mod, surf, x2 - offsetx, y2 - offsety, 10, 0, 0, -1, 0, 0, 0, 0, r, g, b, alpha);
1422 e2 = Mod_Mesh_IndexForVertex(mod, surf, x2 + offsetx, y2 + offsety, 10, 0, 0, -1, 0, 0, 0, 0, r, g, b, alpha);
1423 e3 = Mod_Mesh_IndexForVertex(mod, surf, x1 + offsetx, y1 + offsety, 10, 0, 0, -1, 0, 0, 0, 0, r, g, b, alpha);
1424 Mod_Mesh_AddTriangle(mod, surf, e0, e1, e2);
1425 Mod_Mesh_AddTriangle(mod, surf, e0, e2, e3);
1426}
1427
1428void DrawQ_SetClipArea(float x, float y, float width, float height)
1429{
1430 int ix, iy, iw, ih;
1431 DrawQ_FlushUI();
1432
1433 // We have to convert the con coords into real coords
1434 // OGL uses bottom to top (origin is in bottom left)
1435 ix = (int)(0.5 + x * ((float)r_refdef.view.width / vid_conwidth.integer)) + r_refdef.view.x;
1436 iy = (int)(0.5 + y * ((float)r_refdef.view.height / vid_conheight.integer)) + r_refdef.view.y;
1437 iw = (int)(0.5 + width * ((float)r_refdef.view.width / vid_conwidth.integer));
1438 ih = (int)(0.5 + height * ((float)r_refdef.view.height / vid_conheight.integer));
1439 switch(vid.renderpath)
1440 {
1441 case RENDERPATH_GL32:
1442 case RENDERPATH_GLES2:
1443 GL_Scissor(ix, vid.mode.height - iy - ih, iw, ih);
1444 break;
1445 }
1446
1447 GL_ScissorTest(true);
1448}
1449
1451{
1452 DrawQ_FlushUI();
1453 GL_ScissorTest(false);
1454}
1455
1457{
1458 DrawQ_FlushUI();
1460}
1461
1463{
1464 DrawQ_FlushUI();
1466 r_refdef.draw2dstage = -1; // next draw call will set viewport etc. again
1467}
1468
1470{
1471 model_t *mod = CL_Mesh_UI();
1472 if (mod->num_surfaces == 0)
1473 return;
1474
1476 {
1478 return;
1479 }
1480
1481 // this is roughly equivalent to R_Mod_Draw, so the UI can use full material feature set
1483 r_textureframe++; // used only by R_GetCurrentTexture
1484 GL_DepthMask(false);
1485
1487 R_DrawModelSurfaces(&cl_meshentities[MESH_UI].render, false, false, false, false, false, true);
1488
1490}
entity_t cl_meshentities[NUM_MESHENTITIES]
Definition cl_main.c:2513
cvar_t vid_conheight
Definition cl_screen.c:57
cvar_t vid_conwidth
Definition cl_screen.c:56
#define CL_Mesh_UI()
Definition client.h:1372
@ MESH_UI
Definition client.h:1365
void Cmd_AddCommand(unsigned flags, const char *cmd_name, xcommand_t function, const char *description)
called by the init functions of other parts of the program to register commands and functions to call...
Definition cmd.c:1661
#define CF_SHARED
Definition cmd.h:67
static int Cmd_Argc(cmd_state_t *cmd)
Definition cmd.h:249
static const char * Cmd_Argv(cmd_state_t *cmd, int arg)
Cmd_Argv(cmd, ) will return an empty string (not a NULL) if arg > argc, so string operations are alwa...
Definition cmd.h:254
#define CF_CLIENT
cvar/command that only the client can change/execute
Definition cmd.h:48
#define CF_ARCHIVE
cvar should have its set value saved to config.cfg and persist across sessions
Definition cmd.h:53
unsigned short CRC_Block(const unsigned char *data, size_t size)
Definition com_crc16.c:75
char com_token[MAX_INPUTLINE]
Definition common.c:39
char * va(char *buf, size_t buflen, const char *format,...)
Definition common.c:972
qbool COM_ParseToken_Simple(const char **datapointer, qbool returnnewline, qbool parsebackslash, qbool parsecomments)
Definition common.c:463
int dpsnprintf(char *buffer, size_t buffersize, const char *format,...)
Returns the number of printed characters, excluding the final '\0' or returns -1 if the buffer isn't ...
Definition common.c:997
#define dp_strlcpy(dst, src, dsize)
Definition common.h:303
void Con_DPrintf(const char *fmt,...)
A Con_Printf that only shows up if the "developer" cvar is set.
Definition console.c:1544
void Con_Printf(const char *fmt,...)
Prints to all appropriate console targets.
Definition console.c:1514
#define CON_WARN
Definition console.h:101
float flags
float mod(float dividend, float divisor)
void Cvar_RegisterVariable(cvar_t *variable)
registers a cvar that already has the name, string, and optionally the archive elements set.
Definition cvar.c:599
float scale
vector color
float alpha
#define FONTS_EXPAND
Definition draw.h:127
@ CACHEPICFLAG_FAILONMISSING
Definition draw.h:44
@ CACHEPICFLAG_NEAREST
Definition draw.h:42
@ CACHEPICFLAG_LINEAR
Definition draw.h:43
@ CACHEPICFLAG_QUIET
Definition draw.h:37
@ CACHEPICFLAG_NEWPIC
Definition draw.h:40
@ CACHEPICFLAG_NOTPERSISTENT
Definition draw.h:36
@ CACHEPICFLAG_NOCLAMP
Definition draw.h:39
@ CACHEPICFLAG_NOCOMPRESSION
Definition draw.h:38
@ CACHEPICFLAG_MIPMAP
Definition draw.h:41
#define MAX_USERFONTS
Definition draw.h:137
#define STRING_COLOR_RGB_TAG_CHAR
Definition draw.h:143
#define FONT_DEFAULT
Definition draw.h:128
#define MAX_FONT_CMDLINE
Definition draw.h:96
#define FONT_CHAT
Definition draw.h:132
#define FONT_CONSOLE
Definition draw.h:129
#define MAX_FONTS
Definition draw.h:126
#define FONT_INFOBAR
Definition draw.h:134
#define FONT_NOTIFY
Definition draw.h:131
#define FONT_USER(i)
Definition draw.h:136
#define FONT_MENU
Definition draw.h:135
#define STRING_COLOR_DEFAULT
Definition draw.h:141
#define MAX_FONT_FALLBACKS
Definition draw.h:95
#define FONT_SBAR
Definition draw.h:130
#define FONT_CENTERPRINT
Definition draw.h:133
#define MAX_FONT_SIZES
Definition draw.h:94
#define STRING_COLOR_TAG
Definition draw.h:140
unsigned char * FS_LoadFile(const char *path, mempool_t *pool, qbool quiet, fs_offset_t *filesizepointer)
Definition fs.c:3540
static int(ZEXPORT *qz_inflate)(z_stream *strm
int64_t fs_offset_t
Definition fs.h:37
void font_newmap(void)
Definition ft2.c:439
ft2_font_map_t * Font_MapForIndex(ft2_font_t *font, int index)
Definition ft2.c:1052
float Font_SnapTo(float val, float snapwidth)
Definition ft2.c:514
qbool Font_LoadFont(const char *name, dp_font_t *dpfnt)
Definition ft2.c:521
void font_start(void)
Definition ft2.c:404
qbool Font_GetKerningForMap(ft2_font_t *font, int map_index, float w, float h, Uchar left, Uchar right, float *outx, float *outy)
Definition ft2.c:1085
int Font_IndexForSize(ft2_font_t *font, float _fsize, float *outw, float *outh)
Definition ft2.c:999
qbool Font_GetMapForChar(ft2_font_t *font, int map_index, Uchar ch, ft2_font_map_t **outmap, int *outmapch)
Query for or load a font map for a character, with the character's place on it.
Definition ft2.c:1971
void font_shutdown(void)
Definition ft2.c:425
void Font_UnloadFont(ft2_font_t *font)
Definition ft2.c:1184
#define ft2_oldstyle_map
Definition ft2.h:30
void GL_DepthMask(int state)
void GL_Scissor(int x, int y, int width, int height)
void GL_ScissorTest(int state)
cachepic_t * Draw_CachePic(const char *path)
Definition gl_draw.c:185
static cachepic_t cachepics[MAX_CACHED_PICS]
Definition gl_draw.c:73
static cachepic_t * cachepichash[CACHEPICHASHSIZE]
Definition gl_draw.c:72
rtexturepool_t * drawtexturepool
Definition gl_draw.c:76
float DrawQ_TextWidth_UntilWidth_TrackColors(const char *text, size_t *maxlen, float w, float h, int *outcolor, qbool ignorecolorcodes, const dp_font_t *fnt, float maxwidth)
Definition gl_draw.c:1325
void DrawQ_Fill(float x, float y, float width, float height, float red, float green, float blue, float alpha, int flags)
Definition gl_draw.c:847
cvar_t r_textbrightness
Definition gl_draw.c:55
void Draw_FreePic(const char *picname)
Definition gl_draw.c:309
static void LoadFont_f(cmd_state_t *cmd)
Definition gl_draw.c:544
void DrawQ_FlushUI(void)
Definition gl_draw.c:1469
void DrawQ_Pic(float x, float y, cachepic_t *pic, float width, float height, float red, float green, float blue, float alpha, int flags)
Definition gl_draw.c:797
qbool r_draw2d_force
Definition gl_draw.c:795
void DrawQ_SuperPic(float x, float y, cachepic_t *pic, float width, float height, float s1, float t1, float r1, float g1, float b1, float a1, float s2, float t2, float r2, float g2, float b2, float a2, float s3, float t3, float r3, float g3, float b3, float a3, float s4, float t4, float r4, float g4, float b4, float a4, int flags)
Definition gl_draw.c:1380
cvar_t r_font_postprocess_shadow_x
Definition gl_draw.c:60
void Draw_Frame(void)
Definition gl_draw.c:237
cachepic_t * Draw_NewPic(const char *picname, int width, int height, unsigned char *pixels_bgra, textype_t textype, int texflags)
Definition gl_draw.c:256
void DrawQ_Start(void)
Definition gl_draw.c:789
void DrawQ_Finish(void)
Definition gl_draw.c:1456
cvar_t r_font_postprocess_outline
Definition gl_draw.c:59
static void gl_draw_start(void)
Definition gl_draw.c:706
static void DrawQ_GetTextColor(float color[4], int colorindex, float r, float g, float b, float a, qbool shadow)
Definition gl_draw.c:883
void DrawQ_RotPic(float x, float y, cachepic_t *pic, float width, float height, float org_x, float org_y, float angle, float red, float green, float blue, float alpha, int flags)
Definition gl_draw.c:819
void DrawQ_Line(float width, float x1, float y1, float x2, float y2, float r, float g, float b, float alpha, int flags)
Definition gl_draw.c:1402
float DrawQ_Color[4]
Definition gl_draw.c:1084
const char * Draw_GetPicName(cachepic_t *pic)
Definition gl_draw.c:190
cvar_t r_font_postprocess_shadow_z
Definition gl_draw.c:62
dp_fonts_t dp_fonts
Definition gl_draw.c:50
const vec4_t string_colors[]
color tag printing
Definition gl_draw.c:853
static void gl_draw_shutdown(void)
Definition gl_draw.c:723
static int RGBstring_to_colorindex(const char *str)
Definition gl_draw.c:906
cachepic_t * Draw_CachePic_Flags(const char *path, unsigned int cachepicflags)
Definition gl_draw.c:86
float DrawQ_String_Scale(float startx, float starty, const char *text, size_t maxlen, float w, float h, float sw, float sh, float basered, float basegreen, float baseblue, float basealpha, int flags, int *outcolor, qbool ignorecolorcodes, const dp_font_t *fnt)
Definition gl_draw.c:1085
cvar_t r_textshadow
Definition gl_draw.c:53
int Draw_GetPicWidth(cachepic_t *pic)
Definition gl_draw.c:197
static float snap_to_pixel_x(float x, float roundUpAt)
Definition gl_draw.c:518
float DrawQ_TextWidth(const char *text, size_t maxlen, float w, float h, qbool ignorecolorcodes, const dp_font_t *fnt)
Definition gl_draw.c:1330
static void gl_draw_newmap(void)
Definition gl_draw.c:733
cvar_t r_font_antialias
Definition gl_draw.c:64
cvar_t r_font_postprocess_shadow_y
Definition gl_draw.c:61
void GL_Draw_Init(void)
Definition gl_draw.c:747
cvar_t r_font_hinting
Definition gl_draw.c:63
cvar_t r_font_postprocess_blur
Definition gl_draw.c:58
float DrawQ_String(float startx, float starty, const char *text, size_t maxlen, float w, float h, float basered, float basegreen, float baseblue, float basealpha, int flags, int *outcolor, qbool ignorecolorcodes, const dp_font_t *fnt)
Definition gl_draw.c:1320
cvar_t r_font_always_reload
Definition gl_draw.c:65
rtexture_t * Draw_GetPicTexture(cachepic_t *pic)
Definition gl_draw.c:224
cvar_t r_textcontrast
Definition gl_draw.c:56
int draw_frame
Definition gl_draw.c:78
void DrawQ_SetClipArea(float x, float y, float width, float height)
Definition gl_draw.c:1428
float DrawQ_TextWidth_UntilWidth(const char *text, size_t *maxlen, float w, float h, qbool ignorecolorcodes, const dp_font_t *fnt, float maxWidth)
Definition gl_draw.c:1335
void LoadFont(qbool override, const char *name, dp_font_t *fnt, float scale, float voffset)
Definition gl_draw.c:330
void DrawQ_RecalcView(void)
Definition gl_draw.c:1462
cvar_t developer_font
Definition ft2.c:61
static float snap_to_pixel_y(float y, float roundUpAt)
Definition gl_draw.c:531
cvar_t r_nearest_2d
Definition gl_draw.c:66
cvar_t r_nearest_conchars
Definition gl_draw.c:67
int Draw_GetPicHeight(cachepic_t *pic)
Definition gl_draw.c:204
dp_font_t * FindFont(const char *title, qbool allocate_new)
Definition gl_draw.c:481
int con_linewidth
Definition console.c:94
float DrawQ_TextWidth_UntilWidth_TrackColors_Scale(const char *text, size_t *maxlen, float w, float h, float sw, float sh, int *outcolor, qbool ignorecolorcodes, const dp_font_t *fnt, float maxwidth)
Definition gl_draw.c:928
static int numcachepics
Definition gl_draw.c:74
qbool Draw_IsPicLoaded(cachepic_t *pic)
Definition gl_draw.c:211
void DrawQ_ResetClipArea(void)
Definition gl_draw.c:1450
static mempool_t * fonts_mempool
Definition gl_draw.c:51
cvar_t r_draw2d
Definition gl_rmain.c:97
int r_textureframe
used only by R_GetCurrentTexture, incremented per view and per UI render
Definition gl_rmain.c:45
skinframe_t * R_SkinFrame_LoadExternal(const char *name, int textureflags, qbool complain, qbool fallbacknotexture)
Definition gl_rmain.c:2314
skinframe_t * R_SkinFrame_LoadInternalBGRA(const char *name, int textureflags, const unsigned char *skindata, int width, int height, int comparewidth, int compareheight, int comparecrc, qbool sRGB)
Definition gl_rmain.c:2546
void R_ResetViewRendering2D_Common(int viewfbo, rtexture_t *viewdepthtexture, rtexture_t *viewcolortexture, int viewx, int viewy, int viewwidth, int viewheight, float x2, float y2)
Definition gl_rmain.c:4439
void R_DrawModelSurfaces(entity_render_t *ent, qbool skysurfaces, qbool writedepth, qbool depthonly, qbool debug, qbool prepass, qbool ui)
Definition gl_rmain.c:9970
void R_SkinFrame_PurgeSkinFrame(skinframe_t *s)
Definition gl_rmain.c:2184
skinframe_t * R_SkinFrame_LoadExternal_SkinFrame(skinframe_t *skinframe, const char *name, int textureflags, qbool complain, qbool fallbacknotexture)
Definition gl_rmain.c:2331
void R_SkinFrame_MarkUsed(skinframe_t *skinframe)
Definition gl_rmain.c:2176
r_refdef_t r_refdef
Definition gl_rmain.c:57
void R_FreeTexturePool(rtexturepool_t **rtexturepool)
cvar_t gl_texturecompression
Definition gl_textures.c:37
int R_TextureHeight(rtexture_t *rt)
void R_UpdateTexture(rtexture_t *rt, const unsigned char *data, int x, int y, int z, int width, int height, int depth, int combine)
int R_TextureWidth(rtexture_t *rt)
rtexturepool_t * R_AllocTexturePool(void)
cvar_t gl_texturecompression_2d
Definition gl_textures.c:42
GLenum GLsizei width
Definition glquake.h:622
GLenum GLsizei GLsizei height
Definition glquake.h:622
GLubyte GLubyte GLubyte GLubyte w
Definition glquake.h:782
const GLdouble * v
Definition glquake.h:762
GLint GLenum GLint GLint y
Definition glquake.h:651
GLint GLenum GLint x
Definition glquake.h:651
GLclampf GLclampf blue
Definition glquake.h:642
const GLchar * name
Definition glquake.h:601
GLclampf green
Definition glquake.h:642
host_static_t host
Definition host.c:41
qbool Image_GetStockPicSize(const char *filename, int *returnwidth, int *returnheight)
Definition image.c:1196
#define max(A, B)
Definition mathlib.h:38
#define DEG2RAD(a)
Definition mathlib.h:65
#define bound(min, num, max)
Definition mathlib.h:34
#define Vector4Set(vec, r, g, b, a)
Definition mathlib.h:86
#define Vector4Copy(in, out)
Definition mathlib.h:84
float strlen(string s)
float cos(float f)
void cmd(string command,...)
float sin(float f)
float fabs(float f)
#define MATERIALFLAG_VERTEXCOLOR
#define MATERIALFLAG_ALPHA
Definition model_brush.h:79
#define MATERIALFLAG_BLENDED
#define MATERIALFLAG_ALPHAGEN_VERTEX
#define MATERIALFLAG_WALL
Definition model_brush.h:89
#define MATERIALFLAG_NOSHADOW
void Mod_Mesh_Reset(model_t *mod)
msurface_t * Mod_Mesh_AddSurface(model_t *mod, texture_t *tex, qbool batchwithprevioussurface)
int Mod_Mesh_IndexForVertex(model_t *mod, msurface_t *surf, float x, float y, float z, float nx, float ny, float nz, float s, float t, float u, float v, float r, float g, float b, float a)
texture_t * Mod_Mesh_GetTexture(model_t *mod, const char *name, int defaultdrawflags, int defaulttexflags, int defaultmaterialflags)
void Mod_Mesh_AddTriangle(model_t *mod, msurface_t *surf, int e0, int e1, int e2)
void Mod_Mesh_Finalize(model_t *mod)
int i
#define MAX_CACHED_PICS
max number of 2D pics loaded at once
Definition qdefs.h:133
#define MAX_QPATH
max length of a quake game pathname
Definition qdefs.h:169
#define CACHEPICHASHSIZE
number of hash buckets for accelerating 2D pic name lookups
Definition qdefs.h:134
#define NULL
Definition qtypes.h:12
bool qbool
Definition qtypes.h:9
vec_t vec4_t[4]
Definition qtypes.h:72
void R_RegisterModule(const char *name, void(*start)(void), void(*shutdown)(void), void(*newmap)(void), void(*devicelost)(void), void(*devicerestored)(void))
Definition r_modules.c:25
#define TEXF_ALPHA
Definition r_textures.h:9
#define TEXF_FORCELINEAR
Definition r_textures.h:19
#define TEXF_MIPMAP
Definition r_textures.h:11
#define TEXF_FORCENEAREST
Definition r_textures.h:17
#define TEXF_COMPRESS
Definition r_textures.h:23
textype_t
Definition r_textures.h:44
#define TEXF_CLAMP
Definition r_textures.h:15
#define TEXF_FORCE_RELOAD
Definition r_textures.h:41
dp_FragColor r
dp_FragColor g
float f
vec3 y2
vec3 x2
dp_FragColor b
vec3 x1
vec4 sw
ret a
skinframe_t * skinframe
Definition gl_draw.c:41
unsigned int flags
Definition gl_draw.c:45
int lastusedframe
Definition gl_draw.c:39
int autoload
Definition gl_draw.c:35
int texflags
Definition gl_draw.c:37
char name[MAX_QPATH]
Definition gl_draw.c:47
int height
Definition gl_draw.c:33
int width
Definition gl_draw.c:33
struct cachepic_s * chain
Definition gl_draw.c:43
command interpreter state - the tokenizing and execution of commands, as well as pointers to which cv...
Definition cmd.h:127
Definition cvar.h:66
float value
Definition cvar.h:74
int integer
Definition cvar.h:73
struct ft2_font_s * ft2
Definition draw.h:110
int req_face
Definition draw.h:106
float maxwidth
Definition draw.h:102
char title[MAX_QPATH]
Definition draw.h:104
char texpath[MAX_QPATH]
Definition draw.h:103
float width_of[256]
Definition draw.h:100
ft2_settings_t settings
Definition draw.h:112
float width_of_ft2[MAX_FONT_SIZES][256]
Definition draw.h:101
char fallbacks[MAX_FONT_FALLBACKS][MAX_QPATH]
Definition draw.h:108
cachepic_t * pic
Definition draw.h:99
int maxsize
Definition draw.h:121
dp_font_t * f
Definition draw.h:120
float shadowy
Definition draw.h:91
float scale
Definition draw.h:88
float outline
Definition draw.h:91
int antialias
Definition draw.h:90
float voffset
Definition draw.h:88
float shadowz
Definition draw.h:91
int hinting
Definition draw.h:90
float shadowx
Definition draw.h:91
float blur
Definition draw.h:91
double realtime
the accumulated mainloop time since application started (with filtering), without any slowmo or clamp...
Definition host.h:46
describes the textures to use on a range of triangles in the model, and mins/maxs (AABB) for culling.
int draw2dstage
Definition render.h:452
r_refdef_view_t view
Definition render.h:406
float colorscale
global RGB color multiplier for rendering
Definition render.h:302
int width
Definition vid.h:60
int height
Definition vid.h:61
qbool sRGB2D
whether 2D rendering is sRGB corrected (based on sRGBcapable2D)
Definition vid.h:75
renderpath_t renderpath
Definition vid.h:80
viddef_mode_t mode
currently active video mode
Definition vid.h:73
#define u8_getnchar(c, e, n)
Definition utf8lib.h:74
int32_t Uchar
Definition utf8lib.h:35
@ RENDERPATH_GLES2
Definition vid.h:38
@ RENDERPATH_GL32
Definition vid.h:37
viddef_t vid
global video state
Definition vid_shared.c:64
mempool_t * tempmempool
Definition zone.c:794
#define Mem_Free(mem)
Definition zone.h:96
#define Mem_Alloc(pool, size)
Definition zone.h:92
#define Mem_AllocPool(name, flags, parent)
Definition zone.h:104
#define Mem_Realloc(pool, data, size)
Definition zone.h:94