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 > 64x64 background maps becomes 4x32x32

#47764 - LOst? - Wed Jul 13, 2005 4:36 am

I have a big problem. I want to use 64x64 tiles backgrounds. But when I copy my map (which is a linear array) into BG_MAP_RAM (anything), the background seems to be divided into 4 sections, and I don't know why, or how to fix it without pro help.

So how do I do? Is there any limitations in the VRAM memory? Or is it Map Ed I shouldn't trust?
_________________
Exceptions are fun

#47767 - gladius - Wed Jul 13, 2005 5:02 am

The 64x64 backgrounds are stored as 4 32x32 contiguous sections in vram.

#47769 - tepples - Wed Jul 13, 2005 5:05 am

Gladius is correct. In text mode, a 64x64 tile map is divided into four 32x32 tile quadrants. This has been the case since the NES. In rotation mode, on the other hand, maps of all sizes are linear and have been so since the Super NES.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#47770 - dovoto - Wed Jul 13, 2005 5:18 am

Tile map width can not exeed 32 tiles in memory. This is a hardware limitation that also exists in GBA. So any background larger than 32x32 is actualy composed of 32x32 chunks.

To over come this you need to map your linear array onto this chunked array.

64x32 Map in VRAM

1, 2,......31 1024, 1025....1055
32, 33,....63 1056, 1057....1087
. .
. .
...........1024 ...................2048


not sure if this makes things any clearer...I have some simple code from an unfinished demo series i started a long while back.
http://rafb.net/paste/results/fk68mX95.html Line 74 or so is were the copy occurs.[/code]
_________________
www.drunkencoders.com

#47771 - dovoto - Wed Jul 13, 2005 5:21 am

Oh...and please dont use that method for actualy loading your maps :) It is ment only to supplement an explanation of the mapping. It is much better to either pre-compute your map or at least copy in 32 tiles at a time.
_________________
www.drunkencoders.com

#47781 - LOst? - Wed Jul 13, 2005 12:03 pm

dovoto wrote:
Oh...and please dont use that method for actualy loading your maps :) It is ment only to supplement an explanation of the mapping. It is much better to either pre-compute your map or at least copy in 32 tiles at a time.

Thanks. Do I have to change the MAP base after I have copied in 32x32 tiles? Or is it only the order of the map tiles I have to think about here?
_________________
Exceptions are fun

#47785 - rize - Wed Jul 13, 2005 3:07 pm

In the control register, you certainly dont' change the map base. Now your vram pointer, you might increment that to the base you're loading if it makes sense to decrease computation.

dovoto and company: As for precomputing the map's location, is that possible with a dynamic streaming tilemap into a 64x32 space? I suppose it is, but is it really worth precomputing the location (wastes space instead of cycles)? Right now I'm using a complex looking scheme in real-time that requires me to take the modulus of my "software" tilemap's index with the hardware space's dimensions to get a hardware mapping, and then further map that into the blocked tilemap memory using the computation below:

I'm using tilemaps larger than 64x64 and dynamically streaming the contents into a 64x32 space (64x32 being the smallest map large enough to display one full screen plus one additional row and column of tiles).

LOst: anyway, I'm calculating indexes like this: for indices x and y into a straightforwrd 64x32 tilemap, get the hardware indices like so:

if (x >= 32) index = 1024 + x-32 + y*32;
else index = x + y*32;

32x64 is similar:

if (y >= 32) index = 1024 + x + (y-32)*32;
else index = x + y*32;

For 64x64 you'd need to deal with four quadrants by combining the previous two if's like so:

offset = 0;

if (x >= 32) {
offset = 1024; //32x32, the size of one block
hx = x-32;
}
else hx = x;

if (y >= 32) {
offset += 2048; //add two blocks to the previous offset
hy = y-32;
}
else hy = y;

//offset jumps to the base, x and y index it
index = offset + x + y*32;
vram_map_base[index] = software_map[x][y];

Or something like that.