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.

Graphics > Huge backgrounds Help

#17876 - Justin2097 - Tue Mar 16, 2004 1:01 pm

My idea is, i think, a pretty simple one.

I am designing a map program for use alongside a PC game. So i can use my GBA as a map for the game i am playing.
Pointless i know, but this is for learning purposes only.

My tiles are 32*32 pixels, and there are about 3160 (81*39).
They take up much more room than the max 512*512 (8*8px) tiles allowed.
All in all i would need 6 of the 512*512 tile maps for the one map i'm trying to produce.

My question is how can i go about producing an array of tiles in my program that will update when i scroll around,
for example: -

When i scroll left, the tiles that disappear to the right, appear on the left and the new tile is loaded into its space.

The map itself does not rotate or scale. It just moves in 4 directions; Up, Down, Left, and Right. No diagonals either.

Are there any tutorials out there which show how to do this? or can someone explain how to do it. I've tired looking on the
pern project. and nothing is explained fully. I understand the theory, as i have a bit of experience with delphix games
development, i just don't know how to do it GBA.

Thanks in advance for any help offered.

#17887 - Nessie - Tue Mar 16, 2004 5:18 pm

One question is, are the 3160 tiles all unique tiles or do you have 3160 tiles, many of which are duplicates of other ones?

If you are dealing with the latter situation described, using a tool to dead-strip duplicated tiles may be enough to solve your problem.

Or had you already tried this approach and it won't work?

#17888 - Justin2097 - Tue Mar 16, 2004 5:25 pm

They are not all unique, no. I have 180 unique tiles. Each 32px*32px.

The map i want to display is the full size, what i wrote above I can't recall now.

I have the tiles in a bmp file and pcx file.

The thing is, i can create a map in an editor and scroll around it. But it's nowhere near big enough.

I need to know how to get the tiles on screen without using the map program. And then how to slice a section off one edge, change it and paste it on the other edge.

I hope thats a bit clearer :)

#17890 - ScottLininger - Tue Mar 16, 2004 6:11 pm

This is totally doable, but I can't say that I've seen a tutorial on it anywhere.

Here's some pseudocode... The idea is to produce your monster map as a single array, then copy in just the tiles you need onto a 256x256 background. (That's all you need to cover the whole screen.) Copying the entire set of tiles instead of just the "edge" tiles is much simpler.

Code:

void UpdateMap(u16* myHugeMap,int myHugeMapTileWidth,int originX,int originY) {

  // counter
  int row;

  // you only need 21 rows to cover your GBA screen (21*8 > 160)
  for(row = 0; row < 21; row++) {
      
    // copy a 32-tile-wide stripe of tiles into the current row
    // to cover the width of the screen (32 * 8 > 240)
    REG_DMA3SAD = &myHugeMap[originX + ((row + originY) * myHugeMapTileWidth)];
   
    // copy it into whichever BG you're using (1 in this example)
    REG_DMA3DAD = &bg1Pointer[y * 32];
   
    // start DMA xfer
    REG_DMA3CNT = 32 | DMA_16NOW;

  }

}


The originX,originY in this approach is the x,y offset in TILES, not pixels, but by combining the above with some background scrolling on the pixel level, you can make seamless scrolling over an arbitrarily large map.

Hope my gibberish makes sense. :)

The harder part is probably finding a map editor that handles huge maps. I can't help you there.

#17891 - Justin2097 - Tue Mar 16, 2004 6:24 pm

I'm not sure this is entirely what i meant. though it does spread some light.

What i want to achieve is a background that doesn't have to be created using a map editor (Because neither the programs or the GBA can handle maps of this size).

I want to be able to use my bmp with the tiles in, as a tile set. I'm not sure how to achieve this firstly, do you have to create a different file or can you just copy 32px*32px sections from the bmp onto the GBA screen.

Then i want to create a dynamic tile array (for the whole map), each contains reference to a tile in the bmp. Using this array i want to display a certain section of the whole map, say the center 35 tiles (7*5).

Then, when a certain direction is pressed, the map moves across. When it does this, the tiles that move off screen, are swapped for the next corresponding tile in the array, and is position of the other side of the screen.

#17894 - Nessie - Tue Mar 16, 2004 8:34 pm

That's not entirely true, there are map editors out there that will allow you to create a map of any size, regardless of whether it's a GBA hardware compatible size. Additionally, there is at least one map editor that will dead-strip any duplicated tiles and reduce it to the smallest possible set.

Most GBA games on the market with large areas have to implement the method that Scott described above.

I dunno, if you only have 180 unique (8 pixel x 8 pixel) tiles, writing any amount of code to handle your case of 3160 non-unique tiles loaded into vram at once seems like a waste of effort?

Not trying to be critical, just trying to understand the situation. :)

#17903 - tepples - Tue Mar 16, 2004 10:53 pm

You have 180 unique 32x32 pixel tiles. This translates into 2880 unique 8x8 pixel tiles. If you can make these 180 large tiles from 1024 or fewer small tiles (including horizontal or vertical reflection), you can use the "metatile" algorithm, which has been used since the NES. In the metatile algorithm, each large tile is defined as a rectangle of numbers of small tiles, in this case 4 tiles across and 4 tiles down. To learn about metatiles, read this.

To update a single space (x, y) of that map's display:
  1. Look at the map at location (x/4, y/4). This will give you what tile number is there.
  2. Look at the metatile data at (x mod 4, y mod 4, tileno). This will give you what hardware tile to draw.
  3. Draw this hardware tile at (x mod 32, y mod 32) in the map display.

To update the map each frame:
  1. Scroll in X.
  2. Update any newly uncovered display spaces.
  3. Scroll in Y.
  4. Update any newly uncovered display spaces.

_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#17909 - Miked0801 - Wed Mar 17, 2004 2:12 am

Scroll modules are one of the rights of passage on any piece of hardware. If you get this working, you can hold your head high and say that you understand the BG graphics system of the GBA well. Start with a full screen re-draw type scroller. It's slower, but much easier to code. Every time you detect that a new char/tile/meta title has entered the screen (note: in 256x256 mode, the biggest tile you'll be able to use is 2x2 due to contraints in X. Consider using 512x256 mode if you want to make your life easier at first.) redraw the with the current visible tiles. Enjoy.

#17913 - tepples - Wed Mar 17, 2004 5:24 am

The NES had a 248-pixel-wide display (no room for updating multiple tiles at once) and very little CPU->VRAM bandwidth (no time to update multiple tiles at once), and games managed to use large metatiles. Just make sure that you update only one HW map column or row at once; yes, this means you'll have partial metatiles on the seam.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.