Gameboy Development Forum

Discussion about software development for the old-school Gameboys, ranging from the "Gray brick" to Gameboy Color
(Launched in 2008)

You are not logged in.

Ads

#1 2019-08-16 17:35:00

turboboy215
Member
Registered: 2015-07-30
Posts: 15

Easy-to-use code for custom fonts?

Hi,
I have lately been trying to work on learning C as well as the C used for the GBDK toolkit, after several failed attempts of learning. Now I have gotten farther than ever, and as I learn more, I am aiming to recreate an old game I made using C# and a pre-made engine DLL at a summer camp several years ago.

Right now, I've been working on displaying the intro from the original game, but I've hit a roadblock: text. GBDK has a built-in text function, but you can only select from several pre-defined fonts that always load from a specific tile address. I would like to use a custom font that doesn't have too many characters, and looks different from the standard ones, and is at a different tile address than the background tiles, unlike the default fonts. It looks like this:

https://drive.google.com/file/d/1ycRhFP … sp=sharing

I have successfully converted the font to a C array with GBTD, but I am unsure about how to use this as a font. I know that ZGB has a function that allows to use custom fonts somehow, but I don't want to just use ZGB for the project as I want to work on some of my own code as well. However, when I look at the ZGB source code, I am unable to find exactly how the function works or where it is located. Could any of you please show the code that is used for custom fonts, or provide another code that can load a custom font in the same way as this?

Also, one more thing, do you also know how to create a fade transition effect (preferably to/from black) in GBC mode? I found out how to do it in mono mode, but it doesn't work in GBC mode. I just get the ugly image of the correct map and palette but incorrect tiles (from the previous screen) loaded for a split second.

For those of you interested, here is the current source code to my project:
https://drive.google.com/file/d/1brCnVz … sp=sharing

Last edited by turboboy215 (2019-08-16 17:36:31)

Offline

 

#2 2019-08-18 12:59:35

bbbbbr
Member
Registered: 2019-03-04
Posts: 124

Re: Easy-to-use code for custom fonts?

Compiled GBDK fonts are stored in: gbdk/lib/small/asxxxx/gb
For example: "f_min.lst"

Here is a link to the source for that font, which demonstrates the format.
https://github.com/hschmitt/gbdk/blob/m … gb/f_min.s


You can also read more about the format, and how to only load smaller fonts here:
http://gbdk.sourceforge.net/doc/html/c0509.html

Note this comment in the page above:

One side effect is that the IBM-ASCII font is always linked in occuping 2.3k of ROM, even if it is not used. If the extra ROM is required, add the line:

UBYTE font_ibm_fixed[];
or
_font_ibm_fixed::

You could also try increasing the default value for "font_first_free_tile". It looks like it specifies the tile where font loading starts. Have not tested that though.


Alternately, here source for how I used a smaller font located at a different location (end of tile ram). I think this is similar to what you are asking to do.
Source here: https://github.com/bbbbbr/plutoscorner

This code was used within ZGB, but if you replace the InitScrollTiles() tile loading call with set_bkg_data() (or just copy the ZGB function) then the rest should be somewhat generic to GBDK. You would need to customize the character-to-tile printing to match what characters you have in your font.

The font tiles are attached to the end of the window HUD tileset ("font_and_win_tiles"). That tileset is loaded at the end of tile ram:

Code:

#define STATUS_WIN_TILE_COUNT 15 // WARNING: Needs to be manually updated
#define FONT_TILE_COUNT 30

#define WIN_TILES  255 - STATUS_WIN_TILE_COUNT
#define FONT_TILES WIN_TILES - FONT_TILE_COUNT
#define FONT_TILE_SPACE FONT_TILES + 33 // Space tile is part of window tile set

Then:

Code:

    InitScrollTiles(255 - FONT_TILE_COUNT - STATUS_WIN_TILE_COUNT, FONT_TILE_COUNT + STATUS_WIN_TILE_COUNT, font_and_win_tiles, 3);

In the header file(s):

Code:

UINT8 print_x = 0;
UINT8 print_y = 0;
UINT8 print_target = PRINT_BKG;

typedef enum {
    PRINT_BKG,
    PRINT_WIN
} PRINT_TARGET;

void print_text(const char* txt, unsigned char delay_time);
#define PRINT_POS(X, Y) print_x = X; print_y  = Y
#define PRINT(X, Y, TXT, DELAY) PRINT_POS(X,Y); print_text(TXT, DELAY)
#define SET_PRINT_TARGET(TARGET) print_target = TARGET
#define INIT_FONT(FONT_TILE_START, TARGET) print_target = TARGET

In the source file:

Code:

// Copied from ZGB Print
// Removed some code, removed some characters

UINT8 print_x  = 0;
UINT8 print_y  = 0;
UINT8 print_target = PRINT_BKG;

void print_text(const char* txt, unsigned char delay_time){
    UINT8 idx = 0;
    unsigned char c;
    unsigned char start_x;

    start_x = print_x; // Save start X for newline return

    while(*txt) {
        if (joypad())
            delay_time = 0;

        if(*txt == ' ') {
            c = FONT_TILE_SPACE;
        } else if(*txt >= 'A' && *txt <= 'Z'){
            c = FONT_TILES + *txt - 'A';
        } else if(*txt >= 'a' && *txt <= 'z') {
            c = FONT_TILES + *txt - 'a';
        } /* else if(*txt >= '0' && *txt <= '9') {
            c = font_idx + 27 + *txt - '0';
        } */ else {
            switch(*txt) {
                case  '?': c = FONT_TILES + 26; break;
                case  '!': c = FONT_TILES + 27; break;
                case  '.': c = FONT_TILES + 28; break;
                case '\'': c = FONT_TILES + 29; break;
                case '\n':
                    // Do a carriage return, no printing and skip to top of loop
                    print_x = start_x;
                    print_y++;
                    txt++;
                    if (delay_time)
                        delay(delay_time);
                    continue;
            }
        }

        if(print_target == PRINT_BKG)
            set_bkg_tiles(0x1F & (print_x), 0x1F & (print_y), 1, 1, &c);
        else
            set_win_tiles(print_x, print_y, 1, 1, &c);

        print_x++;
        txt++;
        if (delay_time)
            delay(delay_time);
            // OPTIONAL: enable or remove sounds while printing text
            // PlayFx(CHANNEL_1, 0,  0x20, 0x81, 0x43, 0x59, 0x86);
    }
}

Then to print (for example, to the window HUD):

Code:

    SET_PRINT_TARGET(PRINT_WIN);
    PRINT(0,0, "Hello", 0);

Last edited by bbbbbr (2019-08-18 13:14:01)

Offline

 

Board footer

Powered by PunBB
© Copyright 2002–2005 Rickard Andersson