Bitmap Font

posted in Beals Software
Published April 13, 2006
Advertisement
Ok, I've been focusing on the bitmap font a little too much, but its got all the features that I want now, so I'm putting it a side and moving on.

Here's a little screenshot of it (the font that I used is the one provided by one of HGE's tutorials, 6 I think):

Full sized

Thats running the following string:
^This is a test of the ^2emergency^0 font ^1cast system^0.\nThis is only a test; had this been a real disaster, you would be dead.\nThat is all.


The first ^ is there to show that it will be printed if you don't supply a number. The ^# chooses which color to use, which is stored in a global array (so that the user can change the colors.) It also supports \t (4 spaces) and \n. \b is spit out, since its not really a character.

I'm thinking about allowing for the ^# in input, letting the user color his/her text (if I ever use it in a multiplayer game.)

On a side note, I've eliminated the texture pack and dot notation addressing because I can't quite settle on a way to implement it. So, for now its just going to be regular file names. I will probably include it in version 2 of the engine (once I'm done with my project.)

Another side note, the game project is being changed (I'm giving myself until monday to decide.) I tried my hand at making a side scrolling project, and I'm thinking about doing one of those instead (although I'd really like to do an RPG.) Come monday we'll know 1 of 2 things thats going to happen - either I'm changing the game or the deadline. We'll see (I'd really rather not change the deadline, but a month is a short time to learn everything and implement it.)

Maybe I'll skip scripting for this first project, since I think it will be the biggest hassle. I could just hard code the script parts, although that might be just as hard. I'll know more once I dive into it next week.

Anyway, enough updating, I've got some programming to do!

Edit: Also, for those that are interested, I am thinking about releasing this as a free module. It uses variable width fonts, mutliple colors, and I am going to be adding formatting to it (at the moment, it just tests for what was said above, you can't right align or center the text), and it also tests to see if it is visible (or atleast partially.)

Edit 2: I removed the manager classes because all of the functionality is wrapped into a templated class called ResourceManager. So, I just typedefed them (typedef ResourceManager TextureManager.) Works exactly the same, except instead of calling GetXXX(), you call GetResource().
Previous Entry OMFG!!!
Next Entry Update
0 likes 5 comments

Comments

Mushu
Wow, your font renderer is a hell of a lot more functional than mine. I've still got some work to do on it (eventually), but at this point I'm limited to a specific point-size of a specific font of a specific color, and no non-ASCII characters are handled. Well, tab might be handled, let me try...

Nope. It just comes out as that handy square character. I guess I need to keep working!

Yours looks great though :]
April 13, 2006 11:51 PM
Programmer16
Ok, Engine class is finished (doesn't do much, only contains an instance of each of the main types.)

Wow, I said I was going to get them done tonight, and I did (I think that may be the first time I've said that I was going to do something, and actually did it (in my journal anyway).)

You may notice that its kind of skimpy. The first few months of my next project is going to be spent recoding the engine. I'm going to add shader support, more advanced systems (batching, logging, GUI, 3D terrain, and scripting are going to be my main focus.) Speaking of device enumeration, there is none. I know, some people won't like it, but I'm sticking with one resolution (although you can modify it manually via the ini file.) I will provide some way to easily specify windowed or fullscreen mode.

I've got my 2 projects mapped out (not entirely, but a majority):

- 2D platformer
- Free movement (go back to the beginning of the level if you want)
- Tall maps
- Item attachments (mutliple levels; for example, later in the
game you might be able to attach the homing missle attachment
with the multi-missle attachment.)
- Upgradeable weapons
- Multiple NPCs you can control
- 3 month deadline (July 30th)


And

- RPG
- Large world map
- Deep item creation system
- (maybe)Spell creation system
- Create a character
- Item upgrades
- Control upto 6 characters at once
- Baldur's Gate style system (movement and battle)
- Skill mastering (as you use the skill, it gets more powerful. Graphics may also change.)
- 8 direction movement
- 3D terrain
- 5 months - 1 year (depending on the depth of some features.)


The deadline for project A is sticking. And theres not going to be a "if I don't get it done by then." The game will be done.

Since I have a habit of changing stories at the drop of a dime, I'm sticking to 2 basic things - the game is going to be a simulated online game (like .HACK) and the main character is part of the game's developer's anti-cheating team - Brimstone (the game developer) Anti-cheat Network.

Here is what I have so far.

There are 3 main characters:
Ban
Boot
KickHooker

The main storyline is that people are using hooks (kind of like hooking into a dll.) I decided to call it hooking for two reasons - it makes sense (the people are putting hooks into the game so that they can give themselves different items) and I can call my third character KickHooker (yea, I'm childish. So what?).

The game is going to be kind of megaman-ish. You can choose which hooker to go after, then (on most missions) choose which character to use. Then you play through the level, maybe some puzzles or something and then you fight the boss. Once the boss is beaten, you recieve whatever they had hooked (weapons.) Items are shared, so if one person gets it another can use it too, as well as upgrades and such.

As you play through the game you'll gain points for killing things/completing tasks and then level up, allowing you to upgrade a weapon.

Some attachments are recieved from mini-bosses or completing puzzles, as well as being hidden (some can't be gotten until later, of course.)

My list of weapons -
Plasma pistol (unlimited ammo, clip based; upgradeable)
Plasma grenade (can hold up to 100; area damage; upgradeable)
Plasma blade (unlimited ammo, energy based; upgradeable)
Plasma rifle (30 bullets per clip; more accurate; upgradeable)
Plasma cannon (1 bullet per clip; area damage; upgradeable)

These are going to be the only weapons the game. And you'll probably obtain them in that order (you start with pistols.) I'm going to be focusing on the attachment system, so hopefully you won't notice that there are only 5 weapons. The lowest clip size is 1 (of course, just clarifying for the next section.)

Planned attachments -
Explosive ammo (pistol and rifle; lowers fire rate and clip size)
Seeking bullets (pistol, rifle, cannon; lowers clip size; goes toward closest monster)
Extended clip (pistol, rifle, cannon; raises clip size)
Multi-missle (cannon; splits cannon bullet; locks clips size to 1)
Charge (any; charge the weapon for a more powerful attack)
Charge reserve (any; store a charged blast and fire it later)
Sight (pistol; improves accuracy)
Spring Adjustment (rifle; increases fire rate)
Blade Enhancers (blade; modify length or damage)
Blade Homing (blade; allows you to throw the blade and it comes back)

As you level up, your buddy will magically have made a new version of your equipment, allowing you to add more attachments (explosive, seeking, extended clip, sight enhanced pistol final boss battle anyone?)
The extended clip and multi-missle attachments are the only ones that I can think of that will be incompatible.

List of tools -
Hover boots (special item; gained after beating the game)
Plasma shield (you can't be hurt for a short while; eats energy)
Skeleton KeyCard (opens any door; unlimited uses; special item)
Cracking unit (ironic; used to open doors and override security)
Uplink cable (allows you to move through a computer jack)
Grappling hook (cling to anything; reach otherwise unreachable places)

The plasma shield will be obtained about midway through the game. The hover boots might be obtained in the last level, otherwise after you've beaten the game. Skeleton KeyCard might be hidden earlier in the game, but you will also get it after beating the game. The cracking unit and uplink cable will be used to solve puzzles. The grappling hook will be able to cling to anything, obtainable on the last level, but also recieved after beating the game.

This seems like a lot to get done in a few months, but programming is all I do. I just lost my last friend to drugs (not dead, but I'm not into that), I work 2 days a week at most, and I rarely watch TV or play games (sounds lonely and boring, but its what I like to do.) I also only sleep about 4-6 hours most of the time. So:

(7 days * 24 hours) = 168 hours - (8 hours of sleep * 7) = 112 - 10 hours of work per week = 102






So, I'd say I average at least 100 hours of programming weekly. Now that I'm focused and geared up (thanks to Raymond :D) I can focus all of that time programming/designing the game instead of reprogramming the same 3 classes every other day (seriously, for the last year or so I've written a Direct3D class, DirectInput class, and Window class at least eleventy million times. And it was always the same, nothing new.)

Heres a little pseudocode of my life before:

Programmer Donny = LoadProgrammer("Donny.life");
Day Today = GetCurrentDay();

if(Today.Ending() == "day")
{
    Donny.ProgramClass("Window");
    Donny.ProgramClass("Direct3D");
    Donny.ProgramClass("DirectInput");

    if(Random(0, 100) == 0)
        Donny.LearnSomethingNew();
<
April 14, 2006 01:39 AM
Programmer16
I have to sit up for a little while since I just took an antibiotic (they're finally all gone!) So, I made a little movie of the font system (edit: Sorry about the music in the background, I thought I had the music recording turned off.) Most of the following is just the font system. The only thing I had to add was handling the backspace key.

dftEngine_FontTest3.wmv

When the font turns red, all I did was type '^' and then 2. The font system detected this and removed it from the batch (well, didn't include it in the batch) and changed the color. In the backspace handling, if the '^' character is detected, 3 characters are removed (to remove the ^# and then the character the person was trying to remove.)

For anybody that is planning on including any sort of scripting like this in their game, I advise this method:

I have a Quad class. This contains a reference to a texture, a position, width, height, tint (color), and 6 vertices (tri list.)

In my bitmap print loop, I format the text. For example:

if(Text[nStringIndex] == '\t')
{
	RECT SrcRect;
	m_CharDescriptors[(int)' '].FillRect(&SrcRect, m_fLetterHeight);

	Quad SpaceQuad;
	SpaceQuad.Create(fCurrentX, fCurrentY, m_CharDescriptors[(int)' '].m_fWidth, m_fLetterHeight, nCurrentColor, &SrcRect, m_Texture);
	fCurrentX += m_CharDescriptors[(int)' '].m_fWidth;
	if(SpaceQuad.InRect(fX, fY, fWidth, fHeight, true))
	{
		Quads.push_back(SpaceQuad);
		SpaceQuad.MoveRel(m_CharDescriptors[(int)' '].m_fWidth, 0.0f);
		fCurrentX += m_CharDescriptors[(int)' '].m_fWidth;
		if(SpaceQuad.InRect(fX, fY, fWidth, fHeight, true))
		{
			Quads.push_back(SpaceQuad);
			SpaceQuad.MoveRel(m_CharDescriptors[(int)' '].m_fWidth, 0.0f);
			fCurrentX += m_CharDescriptors[(int)' '].m_fWidth;
			if(SpaceQuad.InRect(fX, fY, fWidth, fHeight, true))
			{
				Quads.push_back(SpaceQuad);
				SpaceQuad.MoveRel(m_CharDescriptors[(int)' '].m_fWidth, 0.0f);
				fCurrentX += m_CharDescriptors[(int)' '].m_fWidth;
				if(SpaceQuad.InRect(fX, fY, fWidth, fHeight, true))
					Quads.push_back(SpaceQuad);
			}
		}
	}
}




This checks to see if the current character is the tab character ('\t') and proceeds to push 4 quads filled with the information for the space character. All of my characters are handled in the same manner. Then, when it comes time to render:

Vertex*					pVertices;
IDirect3DVertexBuffer9*	pBuffer;

m_pGraphics->GetDeviceComPtr()->CreateVertexBuffer(Quads.size() * 6 * Vertex::SIZE, D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, Vertex::FVF, D3DPOOL_DEFAULT, &pBuffer, 0);
pBuffer->Lock(0, Quads.size() * 6 * Vertex::SIZE, (void**)&pVertices, D3DLOCK_DISCARD);

for(unsigned int nIndex = 0; nIndex < Quads.size(); ++nIndex)
memcpy(&pVertices[nIndex * 6], Quads.at(nIndex).GetVertices(), Vertex::SIZE * 6);

pBuffer->Unlock();




Now for speed stuff. Using ID3DXFont, my FPS stayed pretty much at 77.
Pros - no need for bitmaps or defintion files; More optimized; easy to implement; supports bold and italic (I believe);
Cons - Doesn't seem to support the tab character; 1 color; no scaling;

Using BmpFont, my FPS ranges from 74-77.
Pros - nicer looking fonts; multiple colors; extendable; scaleable; easy to implement;
Cons - Harder to code the system; generally slower; generally buggier; Horrible clipping;

Edit - Ok, update. I was laying down and I thinking about this and realized something, I wasn't using reserve() on my quad list. After setting the vector to reserve the number of characters in the string to start with (a good estimate, since thats what you stared with, and unless you have tons of tabs it should be high enough), the frame rate now pretty much stays steady at 77. Sometimes it goes upto 78, or down to 75, but thats the lowest that I'm seeing. SCORE!

At the moment, my biggest con is the clipping. I can get around it by specifying the area as multiples of the height and leaving myself 14 extra pixels on the right (thats the largest letter I have), but normal clipping would be awesome.

But, the biggest pro with a self-made system is that its extendable. I wanted keyword highlighting, so I added it. I can't do that with ID3DXFont. And that, in my opinion, majorly outweighs a 3 point difference in the framerate.

I also want to get your guys opinion on my screenshot. This is using the same program that I showed a few posts ago, but a different splatmap (everything else is the same, just a different splatmap.) I've been trying different techniques and I think that this one turned out pretty good:
MapScreeny.png

Ok, its bed time now. I have to get up in about 5 hours and work. Once I get home, I looking around about the clipping and then I am starting on the GUI. I've been looking forward to this.
April 14, 2006 02:49 AM
Rob Loach
That's pretty cool! IRC syntax for text colours [wink]....

I really need a font manager system.
April 14, 2006 08:56 AM
Programmer16
Thats good, then a lot of people should be used to it (I've never actually used IRC.)

If anybody is interested, I can post the relevant code (loading the file format and printing the characters.)
April 14, 2006 01:15 PM
You must log in to join the conversation.
Don't have a GameDev.net account? Sign up!
Advertisement
Advertisement