Page 1 of 1

Creating a bigchar.tga file

Posted: Wed Jul 16, 2008 8:57 pm
by jkoder
Hi,

Does anyone out there know how to create a "bigchars.tga" file to replace the
one in Quake III pak0.pk3 file?

For those of you that don't know it by file name it is basically an image that defines
all the characters available for Strings within the UI.

Also for a bonus point :)

How is the game able to read an image like this? I've seen the same technique used for
weapon model graphics. Does it map to the unique shape of the character?

Cheers

Mike

Re: Creating a bigchar.tga file

Posted: Wed Jul 16, 2008 9:05 pm
by dutchmeat
If you're talking about using a new font(.ttf) in your mod, I suggest to download this:
http://www.q3f.com/q3font.html

Re: Creating a bigchar.tga file

Posted: Wed Jul 16, 2008 9:13 pm
by AnthonyJ
jkoder wrote:How is the game able to read an image like this? I've seen the same technique used for
weapon model graphics. Does it map to the unique shape of the character?
Along with the image is a file which defines where the characters are. In the case of fonts, there is a .dat file which maps char->coordinates. In the case of model skins, this is a process known as "UV mapping", and the models contain the UV coordinates for each vertex.

Re: Creating a bigchar.tga file

Posted: Thu Jul 17, 2008 1:21 am
by Kaz
I'm glad you asked this question... I spent countless hours figuring this stuff out before I began actually learning C. In regard to the first part, I usually just open up Photoshop and manually place characters over the existing ones... it's tedious but it works.

The UI font drawing functions that you'll generally be concerned with are in ui_atoms.c, UI_DrawProportionalString and its variants. I've gone through and re-written them in my code, but the principle is the same.

Code: Select all

static int font1[128][3] = {
// { start, end, column }

{12, 20, 1},			//!
{40, 56, 1},			//"
{72, 88, 1},			//#
{104, 120, 1},			//$
{136, 152, 1},			//%
{168, 184, 1},			//&
{202, 214, 1},			//'
{234, 246, 1},			//(
{266, 278, 1},			//)
{296, 312, 1},			//*
{328, 344, 1},			//+
{362, 374, 1},			//,
{392, 408, 1},			//-
{428, 436, 1},			//.
{457, 469, 1},			///

{490, 502, 1},			//0
{12, 20, 2},			//1
{41, 55, 2},			//2
{72, 88, 2},			//3
{104, 120, 2},			//4
{136, 152, 2},			//5
{168, 184, 2},			//6
{200, 216, 2},			//7
{233, 247, 2},			//8
{264, 280, 2},			//9

{298, 310, 2},			//:
{330, 342, 2},			//;
{360, 376, 2},			//<
{392, 408, 2},			//=
{424, 440, 2},			//>
{456, 472, 2},			//?
{486, 506, 2},			//@

{8, 24, 3},				//A
{40, 56, 3},			//B
{72, 88, 3},			//C
{104, 120, 3},			//D
{136, 152, 3},			//E
{168, 182, 3},			//F
{200, 216, 3},			//G
{232, 248, 3},			//H
{266, 276, 3},			//I
{298, 310, 3},			//J
{328, 344, 3},			//K
{360, 374, 3},			//L
{390, 408, 3},			//M
{424, 440, 3},			//N
{456, 472, 3},			//O
{488, 504, 3},			//P
{8, 24, 4},				//Q
{40, 56, 4},			//R
{72, 88, 4},			//S
{104, 118, 4},			//T
{136, 152, 4},			//U
{168, 184, 4},			//V
{198, 218, 4},			//W
{232, 248, 4},			//X
{264, 280, 4},			//Y
{296, 312, 4},			//Z

{332, 340, 4},			//[
{360, 376, 4},			//'\'
{396, 404, 4},			//]
{428, 436, 4},			//^
{456, 472, 4},			//_
{494, 498, 4},			//`

{10, 20, 5},			//a
{43, 54, 5},			//b
{74, 86, 5},			//c
{106, 118, 5},			//d
{140, 148, 5},			//e
{170, 182, 5},			//f
{202, 214, 5},			//g
{234, 246, 5},			//h
{270, 274, 5},			//i
{298, 310, 5},			//j
{330, 342, 5},			//k
{364, 372, 5},			//l
{394, 406, 5},			//m
{426, 438, 5},			//n
{458, 470, 5},			//o
{490, 502, 5},			//p
{10, 22, 6},			//q
{42, 54, 6},			//r
{74, 86, 6},			//s
{107, 116, 6},			//t
{138, 150, 6},			//u
{170, 182, 6},			//v
{200, 216, 6},			//w
{234, 246, 6},			//x
{268, 277, 6},			//y
{300, 308, 6},			//z

{328, 342, 6},			//{
{366, 370, 6},			//|
{392, 406, 6},			//}
{422, 442, 6},			//~

};

static void UI_DrawFont_Ch(int x, int y, const char* str, vec4_t color, float scale, int style)
{
	const char*	s;
	unsigned char	ch;

	float			ax;
	float			ay;
	float			w;
	float			s1;
	float			s2;
	int			row;
	int			len;
	
	UI_SetColor(color);
	
	//Adjust to 640x480
	ax = x * uis.scalex;
	ay = y * uis.scaley;

	len = UI_Font_Width(str);

	switch (style & UI_FORMATMASK)
	{
		case UI_CENTER:
			//Center justify at x
			ax = ax - (len*scale*uis.scalex/2);
			break;

		case UI_RIGHT:
			//Right justify at x
			ax = ax - (len*scale*uis.scalex);
			break;

		default:
			//Left justify at x
			break;
	}

	s = str;

	while (*s)
	{
		//Remove extended ASCII characters
		ch = *s & 127;

		if (ch == ' ')
			ax += 10*scale*uis.scalex;
		else
		{
			ch -= '!';
			//ch[][0] = starting x
			//ch[][1] = end x
			//ch[][2] = row
			w = (font1[ch][1] - font1[ch][0]) * uis.scalex;
			s1 = (float)font1[ch][0] / 512;
			s2 = (float)font1[ch][1] / 512;
			row = font1[ch][2];
			trap_R_DrawStretchPic(	ax,								//x coord
									ay,						//y coord
									w*scale,					//Width
									FONTHEIGHT*scale*uis.scaley,	//Height
									s1,								
									((row*.0625)-0.0508),			
									s2,						
									((row*.0625)-0.0117),	
									uis.fontShader );				//Graphic to draw with
			ax += w*scale;
		}
		s++;
	}

	trap_R_SetColor(NULL);
}
font1 is a two-dimensional array which stores three values for each character, and is ordered according to the ASCII table. It stores beginning and ending X values, as well as which row the character appears on in the font graphic (an image similar to bigchars.tga). The while loop inside of DrawFont then iterates through each character in the string that it's passed, and uses the corresponding coordinates in font1 to calculate what values to give trap_R_DrawStretchPic, which draws the specific part of the image onto a small rectangle. If you turn on r_showtris, you can see it more clearly.

Hopefully that's mostly relevant to what you were asking, the UI is my favorite part of q3 because I actually comprehend most of it :D

Re: Creating a bigchar.tga file

Posted: Thu Jul 17, 2008 7:35 am
by jkoder
Thanks for all the really good replies.

Re: Creating a bigchar.tga file

Posted: Fri Jul 25, 2008 5:41 pm
by o'dium
This is all really good info, but the poor lad doesnt want this.

He wants to replace the simple font seen in the console ;) In which case the newer font support that TA added wont be much use to him.

Re: Creating a bigchar.tga file

Posted: Fri Jul 25, 2008 5:48 pm
by jkoder
o'dium wrote: He wants to replace the simple font seen in the console ;)
I do? :)

I was actually wanting to change the font in the menus and throughout the UI. It would be nice to change the the console font but thats not something that's really important for me.

Re: Creating a bigchar.tga file

Posted: Fri Jul 25, 2008 6:29 pm
by o'dium
Yeah, thats the one. See, you mentioned Quake 3's main pak file, which never had the advanced font files. In other words for what you want, everything above is wrong (But right, if you wanted a more flexible menu system).

The console font is the same font used in the menus, the text on the HUD etc etc.

Anyway, the font is rendered vis alpha masks which are stored in the .tga file, so open the .tga file and take a look at its mask. There are 256 squares, each one is 16x16 in resolution.

There are I believe some font editor programs out for this one. But the actual Font programs mentioned above will make font files and .dat files for the OTHER fonts, not the one you need.

Re: Creating a bigchar.tga file

Posted: Sat Jul 26, 2008 1:54 pm
by Kaz
My post deals only with the q3_ui module. (vq3)