gbadev.org forum archive

This is a read-only mirror of the content originally found on forum.gbadev.org (now offline), salvaged from Wayback machine copies. A new forum can be found here.

Graphics > Variable-width fonts

#13852 - Xax - Tue Dec 23, 2003 9:17 pm

Does anyone know of a good way to do variable-width fonts? Is there some source out there that might help? I'm thinking I'd have to use tiles instead of sprites, considering the limit of 128 sprites (and I'd be using around 90 of those just for numbers, upper- and lower-case letters, and punctuation).

There was a demo of variable-width fonts on gbadev.org posted in Oct, but apparently it's no longer available for download.

Thanks!

#13854 - poslundc - Tue Dec 23, 2003 10:13 pm

You can get around the limit of 128 sprites using a so-called "raster trick".

Basically what you do is use an HBlank interrupt to switch the OAM entries for the sprites that are displaying a line of text once that line is done rendering. You swap in the values for the next line of text, and then interrupt when at the end of that line of text, etc. Games like Golden Sun use this method.

There are only two problems with this system that I am aware of. One is that there is a limit to how many pixels-worth of sprites can be displayed per scanline, so your graphics may run into problems if your game is sprite-heavy. The other is that your font still consumes sprite VRAM, which is usually in higher demand than background VRAM.

For my game, I have written an engine that uses a text background to display my text by having one tile in VRAM for each tile of the background map. It then "paints" the text onto the actual tiles. This is an effective method that many games use (Zelda, FFTA and Sword of Mana all do, I believe), but it is typically pretty slow, because each character of the font may span multiple tiles. (Mine is written entirely in ARM assembly and it's still slow displaying large blocks of text.)

There is another thread that discusses this subject you might find informative.

Dan.

#13855 - tepples - Tue Dec 23, 2003 10:13 pm

Xax wrote:
I'm thinking I'd have to use tiles instead of sprites, considering the limit of 128 sprites

What limit? Many of e.g. Eurasia's intros draw text with sprites, but they only use enough hardware sprites for one or two lines of text, swapping the rest in with hblank DMA. If I'm not mistaken in my calculation, it's possible to swap in about 16 sprites per scanline using HDMA.

Metroid Fusion does use tiles for its proportional font. It's all a matter of bit shifting.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#13857 - sajiimori - Tue Dec 23, 2003 11:02 pm

Regarding the original character images for a variable-width font, is there any particular reason to store them in VRAM?

#13859 - poslundc - Wed Dec 24, 2003 12:28 am

I assume you're talking about the aforementioned sprite method?

The most obvious reason is to save loading ROM or EWRAM data into VRAM whenever you want to display a string. The algorithm is easier, too: it just becomes a simple matter of having the OAM point to whichever glyph in VRAM matches the glyph in the string.

Plus if you have your font loaded in VRAM, you may not be using all of your glyphs all the time, but at least you are consuming a constant amount of memory and don't have to worry about dynamics based on the size of your string.

That said, I suppose you could write a version where you DMA the necessary font glyphs into VRAM during VBlank. I suppose it depends on how you value the tradeoff between the extra VRAM you'd gain from it versus the additional processing burden of having to load your glyphs in during VBlank. It only increases in complexity if, for example, you decide to have it only load in one of each necessary glyph (so if I print the letter "b" twice, it references the same spot in VRAM). But you could save a lot of VRAM by doing it this way.

For me, though, going the background route was a no-brainer. I'm juggling sprite VRAM all the time, and I've got a ton of scaled and double-sized sprites out there just devouring my available pixels/scanline. Meanwhile I've got about of a third of the background VRAM sitting around doing nothing. May as well put it to good use.

Dan.