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.

#1 2015-08-12 02:28:12

ek82
Member
Registered: 2015-08-12
Posts: 10

Changing tile data during main game loop

Hello. I recently started developing for GB using GBDK.

The game I'm writing requires a lot of blocks that can be pushed around. Due to the sprite limit, I got creative and used background tile data to display blocks. When you push them, I update the tile data in memory to simulate the movement by calling set_bkg_tiles() again.

This is working great on the emulator (BGB), but my question is, is this solution proper? Can tile data be changed while the display is on using an actual GB?

Thanks

Last edited by ek82 (2015-08-12 02:30:40)

Offline

 

#2 2015-08-12 02:45:55

Tauwasser
Member
Registered: 2010-10-23
Posts: 160

Re: Changing tile data during main game loop

Yes, a tile can be changed while the display is on while in vblank. The usual approach is to have a copy of the BG in WRAM, which is transferred in chunks inside the vblank interrupt service routine (ISR).
However, you can also just initialize the BG and have a queue memory structure of changes to perform. So in vblank, this queue is read and the changes are written to the BG in VRAM.

For instance, a memory structure might look like this:

struct bg_change {
    uint8_t x,
    uint8_t y,
    uint8_t tile_no
}

struct bg_change bg_changes[5];

Initialize so that every x is 255, every y and tile_no are don't cares. Inside the vblank ISR, loop through the list and applies the changes:

Code:

uint8_t i;
for (i = 0x00; i < ARRAY_SIZE(bg_changes); i++) {
    /* end of list */
    if (bg_changes[i].x == 0xFFu)
        break;
    /* write to screen */
    write_screen(bg_changes[i].x, bg_changes[i].y, bg_changes[i].tile_no);
    /* invalidate current entry, because it's done */
    bg_changes[i].x = 0xFFu;
}

I have seen this approach in games that don't update a whole lot of tiles on screen at once.

Your initial question: You can use bg tiles to do what you want. It's certainly a nice option.
Depending on the smoothness you require, it might be an option to do the following when a block is pushed:

-draw a sprite with the same tiles/color as the bg block right over the bg block
-erase the bg block
-animate the sprite moving to the new position as the block is being pushed
-draw a bg block under the sprite with same tiles/color
-erase sprite

cYa,

Tauwasser

Last edited by Tauwasser (2015-08-12 02:46:35)

Offline

 

#3 2015-08-12 03:04:22

ek82
Member
Registered: 2015-08-12
Posts: 10

Re: Changing tile data during main game loop

Thanks for the reply.


[EDIT]

I went the vbl interrupt route.

Code:

void vblCallback(){
    if(updateTileMap == TRUE){
        updateTileMap = FALSE;

        /* update memory here */
    }
}

.... then in init code


disable_interrupts();
DISPLAY_OFF;
  
/* set up interrupts */
add_VBL(vblCallback);
  
.... other init stuff

DISPLAY_ON;
enable_interrupts();
set_interrupts(VBL_IFLAG);

.... other init stuff

Thanks!

Last edited by ek82 (2015-08-12 03:45:30)

Offline

 

#4 2015-08-12 10:04:19

Scazon
Member
From: Boston, MA
Registered: 2015-06-14
Posts: 24
Website

Re: Changing tile data during main game loop

Should tile changes always be done on vblank interrupt? I call set_bkg_tiles all the time (for example, when printing text to the screen) and just do it on the fly. Is that bad? It seems to have worked so far.

Offline

 

#5 2015-08-12 16:32:14

Tauwasser
Member
Registered: 2010-10-23
Posts: 160

Re: Changing tile data during main game loop

Use the latest BGB and make sure "Emulate as in Reality" is checked in the Exceptions tab in the preferences menu. That way you'll know if you produce bad code.

As for set_bkg_tiles, it calls set_xy_btt, which checks if it is called in vblank. Thus, every few bytes, it will wait in a busy loop until the next vblank. This is very slow. If you develop for CGB consider HDMA. If you develop for DMG, consider putting your own routine inside the VBLANK ISR like I mentioned above. Drawing will be considerably faster that way.

cYa,

Tauwasser

Offline

 

#6 2015-08-12 21:43:05

Scazon
Member
From: Boston, MA
Registered: 2015-06-14
Posts: 24
Website

Re: Changing tile data during main game loop

Thanks for the tip!

Offline

 

Board footer

Powered by PunBB
© Copyright 2002–2005 Rickard Andersson