Sprite graphics format

From NeoGeo Development Wiki
Jump to navigation Jump to search
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.
File:Spritegfx.png

The NeoGeo uses 16x16 pixels, 4bpp tiles for sprites.

They are stored as 4, 8x8 pixels blocks. Each row of these 8x8 blocks is stored backwards in a 4bit planar organization.

  • On cartridge systems, bitplanes 0 and 1 go in the odd C ROMs (C1, C3...), while bitplanes 2 and 3 go in the even ones (C2, C4...).
  • On CD systems, bitplanes follow a 1/0/3/2 order.

Size

One tile is 16 * 16 pixels * 4 bits per pixel = 1024 bits = 128 bytes.

Addressing

Bit # ...543210
      ...nCLLLL

n: Tile number (multiple bits)
C: Block column, 0 = blocks 1 & 2, 1 = blocks 3 & 4
L: Block line # (0~15)

CA4 is "C".

"Consolegfx"-style definition

Each group represents one byte.

  • t is the 8x8 block number (1 to 4) as shown above.
  • r is the row number in the block (0 to 7).
  • bp is the bitplane number (0 to 3).

Odd C ROMs

  [t1, r0, bp0], [t1, r0, bp1], [t1, r1, bp0], [t1, r1, bp1],
  [t1, r2, bp0], [t1, r2, bp1], [t1, r3, bp0], [t1, r3, bp1],
  [t1, r4, bp0], [t1, r4, bp1], [t1, r5, bp0], [t1, r5, bp1],
  [t1, r6, bp0], [t1, r6, bp1], [t1, r7, bp0], [t1, r7, bp1],

  [t2, r0, bp0], [t2, r0, bp1], [t2, r1, bp0], [t2, r1, bp1],
  [t2, r2, bp0], [t2, r2, bp1], [t2, r3, bp0], [t2, r3, bp1],
  [t2, r4, bp0], [t2, r4, bp1], [t2, r5, bp0], [t2, r5, bp1],
  [t2, r6, bp0], [t2, r6, bp1], [t2, r7, bp0], [t2, r7, bp1]

  [t3, r0, bp0], [t3, r0, bp1], [t3, r1, bp0], [t3, r1, bp1],
  [t3, r2, bp0], [t3, r2, bp1], [t3, r3, bp0], [t3, r3, bp1],
  [t3, r4, bp0], [t3, r4, bp1], [t3, r5, bp0], [t3, r5, bp1],
  [t3, r6, bp0], [t3, r6, bp1], [t3, r7, bp0], [t3, r7, bp1]

  [t4, r0, bp0], [t4, r0, bp1], [t4, r1, bp0], [t4, r1, bp1],
  [t4, r2, bp0], [t4, r2, bp1], [t4, r3, bp0], [t4, r3, bp1],
  [t4, r4, bp0], [t4, r4, bp1], [t4, r5, bp0], [t4, r5, bp1],
  [t4, r6, bp0], [t4, r6, bp1], [t4, r7, bp0], [t4, r7, bp1]

Even C ROMs

  [t1, r0, bp2], [t1, r0, bp3], [t1, r1, bp2], [t1, r1, bp3],
  [t1, r2, bp2], [t1, r2, bp3], [t1, r3, bp2], [t1, r3, bp3],
  [t1, r4, bp2], [t1, r4, bp3], [t1, r5, bp2], [t1, r5, bp3],
  [t1, r6, bp2], [t1, r6, bp3], [t1, r7, bp2], [t1, r7, bp3],

  [t2, r0, bp2], [t2, r0, bp3], [t2, r1, bp2], [t2, r1, bp3],
  [t2, r2, bp2], [t2, r2, bp3], [t2, r3, bp2], [t2, r3, bp3],
  [t2, r4, bp2], [t2, r4, bp3], [t2, r5, bp2], [t2, r5, bp3],
  [t2, r6, bp2], [t2, r6, bp3], [t2, r7, bp2], [t2, r7, bp3]

  [t3, r0, bp2], [t3, r0, bp3], [t3, r1, bp2], [t3, r1, bp3],
  [t3, r2, bp2], [t3, r2, bp3], [t3, r3, bp2], [t3, r3, bp3],
  [t3, r4, bp2], [t3, r4, bp3], [t3, r5, bp2], [t3, r5, bp3],
  [t3, r6, bp2], [t3, r6, bp3], [t3, r7, bp2], [t3, r7, bp3]

  [t4, r0, bp2], [t4, r0, bp3], [t4, r1, bp2], [t4, r1, bp3],
  [t4, r2, bp2], [t4, r2, bp3], [t4, r3, bp2], [t4, r3, bp3],
  [t4, r4, bp2], [t4, r4, bp3], [t4, r5, bp2], [t4, r5, bp3],
  [t4, r6, bp2], [t4, r6, bp3], [t4, r7, bp2], [t4, r7, bp3]

Decoding

Pseudocode:

for block = 0 to 3 {
    select block {
        case 0: xOfs = 8: yOfs = 0
        case 1: xOfs = 8: yOfs = 8
        case 2: xOfs = 0: yOfs = 0
        case 3: xOfs = 0: yOfs = 8
    }
    for row = 0 to 7 {
        BitPlane(0) = ReadByte(1)
        BitPlane(1) = ReadByte(1)
        BitPlane(2) = ReadByte(2)
        BitPlane(3) = ReadByte(2)
        for pixels = 0 to 7 {
            xPos = pixels + xOfs
            yPos = row + yOfs
            ColorIndex = 0
            for bitplanes = 0 to 3
                ColorIndex .= GetBit(BitPlane(3 - bitplanes)), 7 - pixels)
            PixelSet (xPos, yPos), Palette[ColorIndex]
        }
    }
}

Coding