I can't make this 8-bit font work
Julio Sepia

Hello. I'm coding this little Pong game, and I designed this 8-bit font to give it a retro style:

In my program, I import the font using load_bitmap(). I know I can use load_font(), but let me explain why I need the bitmap:

The game must be able to run at two different resolutions (320x240, 640x480). For each resolution, I must have three versions of the font: small, medium and big. To that effect, I declared an array of pointers to fonts: FONT *fonts[4];

The program takes the original .bmp, then resizes it to 2, 4 and 8 times, and finally uses grab_font_from_bitmap() to fill the fonts array with the resized fonts. Here's the function, it works very well:

1FONT *grab_font_from_bitmap_scaled(BITMAP *origin, BYTE scale){
2 BYTE i, j;
3 unsigned int char_w, char_h;
4 BITMAP *tmp;
5 FONT *ret;
7 /* An ASCII 8-bit font file has 14 rows and 16 columns */
8 char_w = (origin->w-1) / 16;
9 char_h = (origin->h-1) / 14;
11 /* We create an 8-bit bitmap */
12 tmp = create_bitmap_ex(8, 16 * char_w * escala + 1, 14 * char_h * escala + 1);
13 clear_to_color(tmp, makecol8(255, 255, 0));
15 for(i=0; i<16; i++){
16 for(j=0; j<14; j++){
17 stretch_blit(origin, tmp,
18 1+i*char_w, 1+j*char_h,
19 char_w, char_h,
20 1+i*char_w*scale-i, 1+j*char_h*scale-j,
21 char_w*scale, char_h*scale);
22 }
23 }
25 ret = grab_font_from_bitmap(tmp);
26 return ret;

The only problem is that I want to have them as mono fonts (to be able to change the text color in textprintf), but the resulting fonts always turn out to be truecolor, no matter how hard I try to make them 8-bit and mono. :'( Even if I apply grab_font_from_bitmap() on the original bitmap (without the resizing), I still get a truecolor font.

What am I doing wrong? Thank you for your help.


IIRC, your input bitmap needs to be 8-bit and contain exactly 3 colors in order to be monospace. You should use set_color_conversion(COLORCONV_NONE) to load the bitmap and keep it in 8-bit mode, then grab it. (Alternatively, set_color_depth(8), grab the fonts, then set the proper color depth).

Of course, your create_bitmap_ex probably makes it work. In that case, make sure the font has exactly 3 colors, I suppose.

Milan Mimica

The formating of your font bitmap is wrong. Use grabber to open a datafile containing mono font (unifont.dat in examples directory), and export the font as bitmap to see what it should look like. It should use only 2 or 3 colors.

Julio Sepia

I'm pretty sure it has three colors, I had Irfanview count them. ;)

I noticed something: everytime I apply the resizing function on the 8bpp bitmap, the program crashes. If I load a 32bpp version of it, it runs fine, but the fonts are considered truecolor (even though the bitmap only uses 3 colors). I get the same result with .pcx and .tga files. If I load a 32bpp image file converted to 8bpp with set_color_conversion(), the resizing function crashes anyway.

I tried using your suggestion of set_color_conversion() on loading, and set_color_depth() on resizing, but nothing changed, sorry. :( There must be something wrong with my resizing.

I don't use any palette routines anywhere. Could that be the problem? I don't know how to work with palettes.

EDIT: Milan is right, I was using the wrong colors. Now I made a BMP with the right colors (white-0 for the space between the characters, black for the background and full blue for the characters), but it still crashes. :'(

Milan Mimica

Note that stretch_blit() cannot handle different color depths.

Can't you just rescale the whole bitmap font instead of glyph per glyph?

Julio Sepia

Thank you for the suggestion, it does work fine if I just resize the bitmap itself. :) I was resizing it glyph by glyph because I thought there was supposed to be exactly 1 pixel between each row of characters, but I was obviously wrong.

As for the stretch_blit, you can see I'm already using 8-bit color both for the source and tmp bitmaps (thanks to create_bitmap_ex). Anyway, I'll try making a separate program to convert my .pcx to a suitable .bmp mono font, let's hope it works.

Andrei Ellman

If you want a function similar to textout() that can zoom the text, check out this snippet of code.


Julio Sepia

Thank you, it's the kind of effect I was looking for, but I have the impression that the zooming would be slow to do frame-by-frame, since my game already uses lots of special effects (mainly for interframe blending) despite being a simple Pong clone.

Andrei Ellman

If the special effects or the game-gfx do not cross the score, you only need to update the score onscreen when it changes. If they do, you can always zoom the score to a separate bitmap (that is only updated when the score is updated), and blit the zoomed score to the screen on each render-cycle. Alternatively, if the source-font is sufficiently small, it might be quicker to zoom the score to screen than to blit from a pre-zoomed bitmap (whichever of the two methods is faster depends on several things, but give both a try to see which one is faster).


Julio Sepia

Yep, that's exactly what I do for the score. However, since I can't change the color of the text using textprintf, I had to make a function to do it. It works for the score, but it wouldn't be practical to apply the same functions to recolor and/or resize text in the help screen or the GUI. :(

Thread #590946. Printed from Allegro.cc