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.

Coding > Diagonal Scrolling with tile strip copying

#27805 - mr_square - Thu Oct 21, 2004 4:35 pm

Hi all. I've implemented a tile strip copying method into my code that lets me scroll around any size map, with just 256x256 actually stored on the GBA. The horizontal scroll works fine by itself, the vertical scroll works fine by itself, but combining them together to do a diagonal scroll just produces a mess.

The method itself is fairly large, but most of it is just spent calculating which tile strip is due to be replaced. The key lines are:

Code:


//......Code to choose tile strip to replace......//

//Vertical strip copier
for(yloop = 0; yloop < 32; yloop++)
{
mapData[(32*yloop)+ currentVStrip] = map[((yoffset + yloop)* mapWidth) + (xValue)];
}

//Horizontal strip copier
for(xloop = 0; xloop < 32; xloop++)
{
mapData[(32*currentHStrip)+ xloop] = map[((yValue)* mapWidth) + (xoffset + xloop)];
}

//.......Code to scroll map and update offsets........//



My viewing window shows a portion of the overall map that is xoffset across it and yoffset down it. The first loop is the horizontal scroller. It copies a vertical strip of offscreen tiles into the mapData area - these are then shown when the background wraps around. The other one copies horizontal strips to produce a vertical scroll.

Combining them both like that obviously isnt the way to scroll diagonally, but I'm not quite sure how else it should be done :(. Any help would be much appreciated - let me know if you need any furthur info on the method.

#27813 - Miked0801 - Thu Oct 21, 2004 6:46 pm

Welcome to the final step. Yes this will take you a bit to get working. You cna combine a horizontal and vertical scroll at the same time, but you have to be careful of the union tile between the 2 methods. I've yet to find a silver bullet method to addressing this. Just keep playing with it until you get it.

#27847 - tepples - Fri Oct 22, 2004 1:27 am

Silver bullet is to split scrolling into two separate steps: scroll horizontally, replacing the appropriate strips of tiles, and then scroll vertically, replacing the appropriate strips of tiles.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#27849 - sajiimori - Fri Oct 22, 2004 1:56 am

Got anything to burst that bubble, Mike? ;) (It's the solution I was thinking about...)

#27861 - poslundc - Fri Oct 22, 2004 2:06 pm

In my game, where it's possible for the camera to move at speeds faster than one row of tiles per frame, it's necessary to compute the intersection of the old camera bounding box with the new camera bounding box every frame and update both strips and columns as necessary. I optimized this by doing strips first, then the portion of the columns that remain (since I can copy strips directly using DMA and need a loop to copy columns). I also special-cased situations such as when the whole screen needs updating or only strips/columns need updating to take as little time as possible.

Then I threw it all out and just made an engine that updated (basically recentred) the entire map whenever a boundary of the current map was encountered. This ultimately proved to be the most efficient way of doing things. :P

Dan.

#27866 - ScottLininger - Fri Oct 22, 2004 5:17 pm

I also went with the "copy the entire map every frame" approach, though now that I've seen this example I realize that this is kind of stupid if you're not scrolling more than 8 pixels per frame.

What's more, I'm updating two maps per frame, which eats up a good chunk of my processing time. Maybe I'll play with implementing the "one strip at a time" approach (after the compo ;)

-Scott

#27873 - sajiimori - Fri Oct 22, 2004 7:18 pm

I bet the full-screen redraw method would start to hurt a bit if you want to dynamically load chars. Even if you have a method of checking whether a char is already loaded, it would mean you have to check every char on the screen on every frame (and for each layer).

#27878 - poslundc - Fri Oct 22, 2004 7:51 pm

sajiimori wrote:
I bet the full-screen redraw method would start to hurt a bit if you want to dynamically load chars. Even if you have a method of checking whether a char is already loaded, it would mean you have to check every char on the screen on every frame (and for each layer).


You're right: I use a fixed tileset for each map. The tilesets are optimized at the point of content creation; I haven't had a problem with the 256-ceiling yet, though, and I even have some animated tiles loaded in. (It's Mode 7 so I'm limited to 256.)

Dan.