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 > Large sprite tile numbers, ie > 1023

#141708 - NeX - Fri Sep 28, 2007 7:39 pm

They don't seem to work... is this a limitation of the DS? If so, what's the point of 4096 16-colour sprite tiles? 1024 loops back to 0, 1025 to 1.
_________________
Strummer or Drummer?.
Or maybe you would rather play with sand? Sandscape is for you in that case.

#141716 - strager - Fri Sep 28, 2007 8:53 pm

NeX wrote:
They don't seem to work... is this a limitation of the DS? If so, what's the point of 4096 16-colour sprite tiles? 1024 loops back to 0, 1025 to 1.


See bits 20 and 21 of DISPLAY_CR. They specify the step of each index in an OAM sprite. This only works for 1D mode, AFAIK.

Basically, you can calculate the address of the tile based on the index with something like:
Code:
#define TILE_SIZE_BYTE (8 * 8 / 2) /* 16-color mode */
//#define TILE_SIZE_BYTE (8 * 8) /* 256-color mode */

int boundary = (DISPLAY_CR >> 20) & 3;
u16 *address = (u16 *)((u8 *)sprite_data_base + index * (TILE_SIZE_BYTE << boundary));


I *think*.

GBATEK wrote:
Code:
OBJ Tile Mapping (DISPCNT.4,20-21):

  Bit4  Bit20-21  Dimension Boundary Total ;Notes
  0     x         2D        32       32K   ;Same as GBA 2D Mapping
  1     0         1D        32       32K   ;Same as GBA 1D Mapping
  1     1         1D        64       64K
  1     2         1D        128      128K
  1     3         1D        256      256K  ;Engine B: 128K max

TileVramAddress = TileNumber * BoundaryValue
Even if the boundary gets changed, OBJs are kept composed of 8x8 tiles.

Bitmap OBJ Mapping (DISPCNT.6,5,22):
Bitmap OBJs are 15bit Direct Color data, plus 1bit Alpha flag (in bit15).

  Bit6 Bit5 Bit22 Dimension    Boundary   Total ;Notes
  0    0    x     2D/128 dots  8x8 dots   128K  ;Source Bitmap width 128 dots
  0    1    x     2D/256 dots  8x8 dots   128K  ;Source Bitmap width 256 dots
  1    0    0     1D           128 bytes  128K  ;Source Width = Target Width
  1    0    1     1D           256 bytes  256K  ;Engine A only
  1    1    x     Reserved

In 1D mapping mode, the Tile Number is simply multiplied by the boundary value.

  1D_BitmapVramAddress = TileNumber(0..3FFh) * BoundaryValue(128..256)
  2D_BitmapVramAddress = (TileNo AND MaskX)*10h + (TileNo AND NOT MaskX)*80h

In 2D mode, the Tile Number is split into X and Y indices, the X index is located in the LSBs (ie. MaskX=0Fh, or MaskX=1Fh, depending on DISPCNT.5).

#141717 - NeX - Fri Sep 28, 2007 8:56 pm

Goodness me, that's complicated. I think I'll just manage my memory more efficiently...
_________________
Strummer or Drummer?.
Or maybe you would rather play with sand? Sandscape is for you in that case.

#141724 - strager - Fri Sep 28, 2007 9:11 pm

NeX wrote:
Goodness me, that's complicated. I think I'll just manage my memory more efficiently...


It's actually not too complicated. If you only have 16x16 sized sprites, for example, you can set the boundary to 2 (which is * 4) so you can index them more easily without calculating the real index from the logical index. Similarly, you can use 1 for 16x8 or 8x16 and 3 for 32x16 or 16x32.

If you had proper sprite support functions this would be simple, assuming not everything is hard-coded.

#141737 - The_Perfection - Fri Sep 28, 2007 11:20 pm

This thread may be helpful.