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.
Hi all. I just started GB programming and am trying to make an 8-way scrolling map.
The idea is to update a 32x32 double buffer while the screen is drawn and copy it to vram during vblank. The code below writes the same top two tiles (4 and 6) every four rows, 5 and 7 don't even show up. It looks like the same few bytes in ntbl_buffer are repeated over and over. Any idea what might be wrong or is more info needed?
ntbl_buffer[0][0] = 4;
ntbl_buffer[1][0] = 5;
ntbl_buffer[0][1] = 6;
ntbl_buffer[1][1] = 7;
This is from the vblank handler
u8 r,c;
u8 * scrn = 0x9800;
for(r=0;r!=32;r++)
for(c=0;c!=32;c++)
*(scrn++) = ntbl_buffer[r][c];
Offline
This is a bug in the lcc compiler that comes with GBDK. It was up for discussion in the IRC channel long ago (#gbdev on EFNet) but I don't remember if anyone found a solution. It's either related to the double arrays or the nested for clauses. Try putting curly beackets around the fors even if you don't need to.
Try replacing the copy loop with a memcpy statement, something like:
memcpy(0x9800, ntbl_buffer, 32*32);
(i don't remember the correct pointer syntax from the top of my head. Add * as needed)
Or better yet, write an asm routine.
Offline
*squee*, memcpy worked. The same bug happened with 1D arrays, but no matter. I'll be writing asm code before long.
Offline
Advice: 2D Array access for a plain memory copy is way too slow. (Especially for a VBlank handler) It's actually not impossible it was so slow that VBlank ended before the copy was done. I'd even like to challenge the idea of buffering the whole tile map like that. I don't know what you've heard, but writing to VRAM isn't limited to VBlank, but it works in HBlank too. So all you need to do in reality is to wait for either BL or HBL, and then write your data directly to VRAM.
Here's a piece of code from my dark vault.
WAITVHBL:: .waithbl ldio A,[$FF41] ; STAT ; We want mode 0 or 1. Both these have bit 1 cleared ; Mode 2 can do too, but here it'll catch up on late cycles in 0 or 1 and $02 ; Test bit 1 ret z jr .waithbl
Here's my guess how it's supposed to look if you put it in a RGBDS .s file:
_WAITVHBL:: .waithbl ldh A,(0xFF41) ; STAT ; We want mode 0 or 1. Both these have bit 1 cleared ; Mode 2 can do too, but here it'll catch up on late cycles in 0 or 1 and 0x02 ; Test bit 1 ret z jr .waithbl
And then you'd need to add
void WAITVHBL();
or something to a relevant .h include file. (I'm not too used to C )
Offline
I got an 8 way scroller working on GBA. On there I double buffered the map just to use a 2D array. You can make a 1d array point directly to an address with some #define trickery, but it doesn't seem to work with 2d.
Lately I tried writing a calculator program for GB in asm. It doesn't do math yet but you can move a cursor over a keypad-like interface and enter numbers. One thing's for sure, anything more ambitious is not getting done without a healthy dose of C.
I'll think about doing it with hblank updates, and in fact would like to cut out the double buffer. If that works maybe I can migrate the method to GBA.
Offline