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 2023-01-02 16:24:19

onHell
New member
Registered: 2023-01-02
Posts: 3

Loading random blank tile instead of proper tile

Whatsup gang. So I'm trying to get myself aquainted with the gbdk by creating a "Game of Life" program. For the past couple days I've been hung up on a problem where the the tile being loaded is not a part of the array of tiles I'm using to create the graphics. Compiling and running this code:

Code:

<...>
#define SCREEN_HEIGHT 18
#define SCREEN_WIDTH 20

#define ALIVE_INDEX 0
#define DEAD_INDEX 16


void main(void)
{
    //Loading in tiles. Tile set:
    //  1. [0] Black Tile - Alive
    //  2. [16] Small Dot Tile - Dead
    //  3. Blank Tile - ?????
    set_bkg_data(0, 2, LifeTileSet);

    // The gameboy screen is 160px wide by 144px tall
    // We deal with tiles that are 8px wide and 8px tall
    // 160/8 =  20, and 144/8 = 18    
    set_bkg_tiles(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, LifeBoard);

    SHOW_BKG;
    DISPLAY_ON;

    bool seperator = true;

    for (int i = 0; i < SCREEN_HEIGHT; i++) {
        for (int y = 0; y < SCREEN_WIDTH; y++) {

            seperator = !seperator;
            if (seperator) {
                set_bkg_tiles(y, i, 1, 1, (unsigned char*)LifeTileSet[ALIVE_INDEX]);
            }
        }
    }
}

produces this output. So, if this were working as intended, the blank columns should all be black instead. There is actually no "Blank" tile in my tileset. What's been interesting to me is that in VRAM there seems to be a blank tile loading into the address space immediately preceding the start of my tile array.

So my questions are:
1. Where is that blank tile coming from?
2. How do i adjust my code to make it so that my call to "set_bkg_tiles()" places the intended tile?

Thanks!

Offline

 

#2 2023-01-03 07:48:43

nitro2k01
Administrator
Registered: 2008-02-22
Posts: 249

Re: Loading random blank tile instead of proper tile

A couple of problems.

Code:

#define ALIVE_INDEX 0
#define DEAD_INDEX 16

You may have confused tile and map data. You're specifying the index for a dead cell to be 16. You're loading a tileset containing 2 tiles into VRAM. Those are tiles 0 and 1. Each tile is in tile RAM is 16 bytes big, so tile 1 is indeed placed 16 bytes into tile RAM. However the index for the tiles are still 0 and 1, so that's what you could write to the map.

Code:

set_bkg_tiles(y, i, 1, 1, (unsigned char*)LifeTileSet[ALIVE_INDEX]);

This does something completely different to what you might expect. LifeTileSet[ALIVE_INDEX] takes the first (well 0th since arrays start at 0) byte of the tile data (ie pixel data) and reads that as a number. Then it takes that number (which was meant to be pixel data, remember) and interprets that as a memory address. Then set_bkg_tiles takes this address and reads one byte of that data and writes into the tile map. Since the format of the data you're sending to set_bkg_tiles is incorrect, the result of the operation is undefined. Your guess is as good as mine what random data might be written to the tile map, but it might be this one tile left over from the Nintendo boot animation.

https://i.imgur.com/uvJs8lT.png

In BGB, you can drop into the debugger by pressing esc on your keyboard or right clicking, other, debugger. In the debugger, you can do a lot of useful things for debugging your program. One thing is to look at what tiles are actually in use. When the program is paused in the debugger, press F5 or click window, VRAM viewer. In the tiles tab (like above) tiles that are currently in use have a different color if "show paletted" is checked.

As for the solution, the correct way (or at least one correct way) to draw the separators is to use set_bkg_tile_xy instead of set_bkg_tiles. set_bkg_tiles takes a pointer to an array that you specify a size of. set_bkg_tile_xy takes a single number specifying the tile you want to draw. Also, usually x is the horizontal coordinate and y is the vertical coordinate. So your code finally might look something like this:

Code:

#define ALIVE_INDEX 0
#define DEAD_INDEX 1

...

    bool seperator = true;

    for (int y = 0; y < SCREEN_HEIGHT; y++) {
        for (int x = 0; x < SCREEN_WIDTH; x++) {

            seperator = !seperator;
            if (seperator) {
                set_bkg_tile_xy(x, y, ALIVE_INDEX);
            }
        }
    }

Oh and one last thing. It might be that the dot graphic actually comes from LifeBoard (the line set_bkg_tiles(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, LifeBoard); ) and that the later code actually manages to fill in empty tiles. This is something that you'd have to troubleshoot since I don't have access to the rest of your code.

And btw, are you the musical artist onhell, or is the name a coincidence?

Edit: I noticed the second screenshot, so the explanation about using BGB's debugger was redundant. Then my guess for that tile is that graphic is that the first byte of your tile data is read as a number. This number is probably 255 or hex 0xFF (which is the binary number with all bits set since all pixels are black in that row.

This then tells set_bkg_tiles to read from address 0xFF in ROM, which also happens to be 0xFF since it's usually the filler value for unused space. This then writes 0xFF to the tile map, which is the weird tile you see. If you hover it, you'll se the tile number is specified as FF.

Last edited by nitro2k01 (2023-01-03 07:55:51)


Blog: Gameboy Genius
"A journey of a thousand miles begins with one small step"
Old Chinese Proverb

Offline

 

#3 2023-01-03 16:03:54

onHell
New member
Registered: 2023-01-02
Posts: 3

Re: Loading random blank tile instead of proper tile

@nitro2k01 Incredible response, thank you!

As a follow up, is there somewhere I can read some documentation about the data format of the Tile arrays generated from the gameboy tile designer/map designer. I feel like theres a gap in information online as to how the C code we use translates into the native assembly. To clarify, there's alot of information on how the gameboys memory space is "fucked around with" in assembly, but little information about how to do this in C. Does that make sense?

And nah, I'm not the DJ. I didn't realize another artist was already using that handle! I borrowed it as a throwaway alias from one of my favorite books, "on_hell" by Johanna Hedva. Cool little chicano-futurist manifesto, would totally recommend!

Offline

 

#4 2023-01-04 02:19:16

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

Re: Loading random blank tile instead of proper tile

The C export format for GBTD should be pretty straightforward. For GBMB the export format depends a lot on how you configure the export dialog.

To understand the hardware tile data format itself:
https://gbdev.io/pandocs/Tile_Data.html

If you don't mind using a different tool with GBDK, the more modern workflow would be to use GBDK-2020's png2asset. There are a couple of examples included with the default install.
https://gbdk-2020.github.io/gbdk-2020/d … otoc_md124

Larold has some newer GBDK tutorials as well:
https://laroldsjubilantjunkyard.com/

The pandocs are a great asset for understanding the hardware.
https://gbdev.io/pandocs/

Offline

 

Board footer

Powered by PunBB
© Copyright 2002–2005 Rickard Andersson