gbadev.org forum archive

This is a read-only mirror of the content originally found on forum.gbadev.org (now offline), salvaged from Wayback machine copies. A new forum can be found here.

DS development > Horizontal scrolling using regular tiled backgrounds

#164150 - ZachG - Wed Oct 22, 2008 4:58 am

I have a 512x512 pixel (64x64 tile) background that I'm filling in with tiles. Because the screen on the DS is 256x192, I have to do some scrolling to move from different parts of my background.

The problem I'm having is conceptualizing (1) how to do buffering of tiles, and (2) how to copy over the tiles to be buffered.

Lets say my sprite is at a position where I want the buffering to begin. I use my BGx_X0 register to scroll the background to match the player's relative position on my tile array. If I want to begin buffering the next set of tiles, I see only two real options of how to alter my array:

My array:
0,0 0,1 0,2 ... 0,n
1,0
2,0
...
m,0

1) If I were to try to keep the buffer on the very right edge my array, which would be all of the [k*(n-1)] tiles where k is the "row" I'm currently on, I would have to copy over 0,1 to 0,0, 0,2 to 0,1, and so on. The problem with doing that is it seems that I won't be using the BGx_X0 register, which is integral to scrolling.

2) If I were to say that it should buffer lets say 10 tiles from the current position of the player in both directions (i.e. if my player in the 10th vertical column, it would load tiles for the 0 column and 20th column. If I moved to the 11th column, it would load tiles for the 1st and 21st column.), I would be able to alter my BGx_X0 kinda. I know the DS hardware does automatic looping of tiles (i.e. If my tiles are 256x256 pixels and I want to go right one pixel, it'll show the 256th pixels on the left side of my screen, followed by the 0, the 1, and the 255th on the right side), but it seems kinda weird that once I reach the point where it starts again (i.e. I'm on the 64th tile, I then want to loop back around to the 1st, so I set BGx_XO from 512 to 0.) I set it back to 0.

I'm just making a simple horizontal platformer. I haven't been able to find anything on the theory behind regular tiled backgrounds, aside from Tonc, and how to do buffering.

#164152 - mml - Wed Oct 22, 2008 5:54 am

At a very basic level, you could look at your screen as a matrix of 32 (horizontal) * 24 (vertical) tiles.

To move the screen across one tile to the left (ie if the player moved one tile to the right, and remained centred in the screen), you would move the columns from 1-31 into positions 0-30 and then load the new rightmost column into column 31.

This is pretty awkward though, since columns are usually your inner array dimension when working in C/C++.

A quick hack that comes to mind would be to invert your background maps and tile graphics into a vertical orientation, chuck it onto a rot/scale background, and rotate it all 90 degrees. Then you get to work with rows rather than columns, which is nice and simple.

The other difficulty here is that you're going to be needing to load data from somewhere every time you move a tile across, which may be unnecessarily inefficient if you're reading from your data store every time you change one column. And if you want to have sub-tile movement (which you probably will, sooner or later if you don't already), you're going to always need to have an extra column loaded (or row, if you use the rot/scale trick) so that one edge of the screen doesn't get a black stripe up it.

The next trick that comes to mind then would be breaking your level data down into chunks that are some multiple n of a tile wide, and having enough of these chunks loaded at a time that you always have at least one chunk more than is needed to cover the entire screen. Then, if you're scrolling consistently at say 1 tile per second, you only need to go out to data store for new level data 1/n times per second. In between tile loads, you use the BG positioning bits to position what's currently loaded on the screen (which gets you sub-tile movement for free, if you're paying attention).