trick/bgconvert

↩ back to overview

Types

SomeTile = Tile4 | Tile8 | Tile16
Typeclass representing all tiles.
Tile4 = array[32, uint8]
Data for an 8x8 pixel tile at 4bpp, where each pixel is a palette index (0 = transparent)
Tile8 = array[64, uint8]
Data for an 8x8 pixel tile at 8bpp, where each pixel is a palette index (0 = transparent)
Tile16 = array[64, GfxColor]
Data for an 8x8 pixel tile at 15bpp, where each pixel is a direct color
ScrEntry = distinct uint16

Screen entry. Map data is simply an array of these.

Each entry holds an index of a tile in the tileset, along with flipping flags and a palette index.

Properties:

Screenblock = array[1024, ScrEntry]

A 32x32 block of screen entries, which represents a 256x256 pixel region of a tiled background.

On the GBA, each background layer can consist of up to 4 screenblocks (in a 2x2 arrangement).

Within a screenblock, an individual entry can be indexed by sb[y*32 + x]

Bg16 = object
  w*, h*: int
  img*: seq[Tile16]
  map*: seq[ScrEntry]

A 15bpp (i.e. direct color, 5 bits per channel) tiled background.

This is not a real format that the GBA uses, but is useful as an intermediate representation before converting to 4bpp or 8bpp.

Bg8 = object
  w*, h*: int                ## Dimensions in tiles
  img*: seq[Tile8]           ## Tile/char image data
  map*: seq[ScrEntry]        ## Map entries
  pal*: GfxPalette           ## Palette with up to 256 colors
  
An 8bpp tiled background.
Bg4 = object
  w*, h*: int                ## Dimensions in tiles
  img*: seq[Tile4]           ## Tile/char image data
  map*: seq[ScrEntry]        ## Map entries
  pals*: seq[GfxPalette]     ## List of palettes
  
A 4bpp tiled background with a list of palettes.

Procs

proc hash(tile: ref SomeTile): Hash
Hashes a tile.
proc flipX[T: SomeTile](tile: T): T
Returns a copy of tile flipped horizontally.
proc flipY[T: SomeTile](tile: T): T
Returns a copy of tile flipped vertically.
proc reduce[T: SomeTile](data: seq[T] | View[T]; firstBlank = true): tuple[
    tiles: seq[T], map: seq[ScrEntry]]
Convert an array of tiles into a minimal tileset with duplicates removed (including horizontally/vertically flipped copies) and a map of tile indexes.
proc toScreenBlocks(map: seq[ScrEntry]; w: int): seq[Screenblock] {...}{.
    raises: [ValueError], tags: [].}

Arrange a map into screenblocks.

The width and height of the map should be multiples of 32.

Example:

let bg4 = loadBg4("myLevel.png")
writeFile("my_level.map.bin", toBytes(bg4.map.toScreenBlocks(bg4.w)))
writeFile("my_level.img.bin", toBytes(bg4.img))
writeFile("my_level.pal.bin", toBytes(joinPalettes(bg4.pals)))
proc clear(tile: var SomeTile)
Set all pixels in a tile to transparent.
  • For 4bpp and 8bpp (paletted) tiles, each pixel is set to zero.
  • For 15bpp (direct color) tiles, each pixel is set to clrEmpty.
proc getPalettesFromTiles(tiles16: seq[Tile16]): seq[IntSet] {...}{.raises: [],
    tags: [].}

Create a list containing one palette for each tile in a list of 15bpp direct color tiles.

Each palette is represented as IntSet for performance reasons. You can use reducePalettes to merge the result down to a lesser number of palettes.

Fails with AssertionError if there are more than 16 colors in any single tile (including clrEmpty).

proc loadBg16(filename: string; firstBlank = true): Bg16 {...}{.
    raises: [Exception, OSError, KeyError], tags: [ReadIOEffect, WriteIOEffect].}

Load a direct color 15bpp tiled background from a PNG file.

Note: this isn't a real format that the GBA uses, but is useful as an intermediate representation before converting to 4bpp or 8bpp.

proc toBg8(bg16: Bg16): Bg8 {...}{.raises: [], tags: [].}
Convert a direct color 15bpp background to a paletted 8bpp background.
proc toBg4(bg16: Bg16): Bg4 {...}{.raises: [], tags: [].}
Convert a direct color 15bpp background to a paletted 4bpp background.
proc loadBg8(filename: string; firstBlank = true): Bg8 {...}{.
    raises: [IOError, OSError, PNGError, NZError, Exception, KeyError],
    tags: [ReadIOEffect, WriteIOEffect].}
Load an 8bpp paletted tiled background from a PNG file.
proc toBg4(bg8: Bg8): Bg4 {...}{.raises: [ValueError], tags: [].}

Strict conversion from 8bpp background to 4bpp background.

If the 8bpp background has more than 16 colors, then it will be treated as having several palettes (0..15, 16..31, 32..47, ...).

Each tile in the image is only allowed to refer to colors from a single one of those palettes.

proc loadBg4(filename: string; indexed = false; firstBlank = true): Bg4 {...}{.raises: [
    IOError, OSError, PNGError, NZError, Exception, KeyError, ValueError],
    tags: [ReadIOEffect, WriteIOEffect].}

Load a 4bpp tiled background from a PNG file.

The resulting background is ideal for usage on the GBA.

Parameters:

filename
Path to PNG file.
indexed
If true, the palette of the input PNG will be preserved. Otherwise, the input PNG will be loaded as true color, and new palettes will be derived from it.

Templates

template tid(se: ScrEntry): int
template tid=(se: var ScrEntry; val: int)
Tile index. i.e. which tile in the tileset to use for this entry.
template hflip(se: ScrEntry): bool
template hflip=(se: var ScrEntry; val: bool)
If true, this tilemap entry is flipped horizontally.
template vflip(se: ScrEntry): bool
template vflip=(se: var ScrEntry; val: bool)
If true, this tilemap entry is flipped vertically.
template palbank(se: ScrEntry): int
template palbank=(se: var ScrEntry; val: int)
Which palette is used by this entry (when working with 4bpp tiles)