video

This module provides access to the entire GBA video hardware: registers, VRAM, PAL RAM and OAM.

I/O Registers

Display Control

type DisplayLayer = enum
  • lBg0Background 0 enabled.
  • lBg1Background 1 enabled.
  • lBg2Background 2 enabled.
  • lBg3Background 3 enabled.
  • lObjObjects (sprites) enabled.
type DisplayLayers = set[DisplayLayer]
type DispCnt = distinct uint16

Display control type, as used by dispcnt.

Field

Type

Bits

Description

mode

uint16

0-2

Video mode, may have one of the following values:

  • 0 – Tile mode (BG 0,1,2,3 = text)

  • 1 – Tile mode (BG 0,1 = text; BG 2 = affine)

  • 2 – Tile mode (BG 2 = affine; BG 3 = affine)

  • 3 – Bitmap mode (BG 2 = 240x160 direct color)

  • 4 – Bitmap mode (BG 2 = 240x160 8bpp indexed)

  • 5 – Bitmap mode (BG 2 = 160x128 direct color)

Note that in bitmap modes, the first half of Obj-VRAM is not usable.

gb

bool

3

True if cartridge is a GBC game. Read-only.

page

bool

4

Page select. Modes 4 and 5 can use page flipping for smoother animation. This bit selects the displayed page (allowing the other one to be drawn on without artifacts).

oamHbl

bool

5

This speeds up access to Obj-VRAM and OAM during HBlank, at the cost of reducing the number of sprite pixels that can be rendered per scanline.

obj1d

bool

6

Determines whether Obj-VRAM is treated like an array or a matrix when drawing sprites. Usually you want to set this to true.

blank

bool

7

Forced Blank: When set, the GBA will display a white screen. This allows fast access to VRAM, PAL RAM, OAM.

bg0

bool

8

Enables background layer 0.

bg1

bool

9

Enables background layer 1.

bg2

bool

10

Enables background layer 2.

bg3

bool

11

Enables background layer 3.

obj

bool

12

Enables sprites (a.k.a. objects).

win0

bool

13

Enables window 0.

win1

bool

14

Enables window 1.

winObj

bool

15

Enables the object window.

layers

DisplayLayers

8-12

A convenient way to enable several layers at once. e.g. dispcnt.layers = { lBg0, lBg1, lObj }

var dispcnt: DispCnt

Display control register

const allDisplayLayers = { lBg0, lBg1, lBg2, lBg3, lObj }

Display Status

type DispStat = distinct uint16

Display status type, as used by dispstat.

Field

Type

Bits

Description

inVBlank

bool

0

VBlank status, read only. True during VBlank, false during VDraw.

inHBlank

bool

1

HBlank status, read-only. True during HBlank.

inVCountTrigger

bool

2

VCount trigger status, read-only.

vblankIrq

bool

3

VBlank interrupt request. If set, an interrupt will be fired at VBlank.

hblankIrq

bool

4

HBlank interrupt request. If set, an interrupt will be fired at HBlank.

vcountIrq

bool

5

VCount interrupt request. If set, an interrupt will be fired when the current scanline matches the scanline trigger (vcount == dispstat.vcountTrigger)

vcountTrigger

uint16

8-15

VCount trigger value. If the current scanline is at this value, bit 2 is set and an interrupt is fired if requested.

var dispstat: DispStat

Display status register

let vcount: uint16

Scanline count register (read only)

BG Control

type BgSize = distinct uint16

Implicitly convertible from either RegBgSize or AffBgSize.

type RegBgSize = enum

Size of a regular background in tiles.

  • reg32x32
  • reg64x32
  • reg32x64
  • reg64x64
type AffBgSize = enum

Size of an affine background in tiles.

  • aff16x16
  • aff32x32
  • aff64x64
  • aff128x128
type BgCnt = distinct uint16

Background control type, as used by bgcnt[0..3].

Field

Type

Bits

Description

prio

uint16

0-1

Priority value (0..3) Lower priority BGs will be drawn on top of higher priority BGs.

cbb

uint16

2-3

Character Base Block (0..3) Determines the base block for tile pixel data

mos

bool

6

Enables mosaic effect.

is8bpp

bool

7

Specifies the color mode of the BG: 4bpp (16 colors) or 8bpp (256 colors) Has no effect on affine BGs, which are always 8bpp.

sbb

uint16

8-12

Screen Base Block (0..31) Determines the base block for the tilemap

wrap

bool

13

Affine Wrapping flag. If set, affine background wrap around at their edges. Has no effect on regular backgrounds as they wrap around by default.

size

BgSize

14-15

Value representing the size of the background in tiles. Regular and affine backgrounds have different sizes available to them, hence the two different types assignable to this field (RegBgSize, AffBgSize)

var bgcnt: array[4, BgCnt]

BG control registers

converter toBgSize(r: RegBgSize): BgSize
converter toBgSize(a: AffBgSize): BgSize

BG Scrolling & Transforms

type Point16 = object

    Field    

    Type    

x int16
y int16
type BgPoint = Point16
type BgOfs = BgPoint
var bgofs: array[4, BgOfs]

BG scroll registers (write only!)

var bgaff: array[2..3, BgAffine]

Affine parameters (matrix and scroll offset) for BG2 and BG3. (write only!)

BG2 is transformable in display modes 1..5. Additionally, BG3 is transformable in mode 2.

See Affine Matrices for more info.

Windowing

type WinH = object

Defines the horizontal bounds of a window (left ..< right)

    Field    

    Type    

right uint8
left uint8
type WinV = object

Defines the vertical bounds of a window (top ..< bottom)

    Field    

    Type    

bottom uint8
top uint8
type WindowLayer = enum
  • wlBg0
  • wlBg1
  • wlBg2
  • wlBg3
  • wlObj
  • wlBlend
type WinCnt = set[WindowLayer]

Allows to make changes to one half of a window control register.

const allWindowLayers = { wlBg0, wlBg1, wlBg2, wlBg3, wlObj, wlBlend }
var winh: array[2, WinH]

Sets the left and right bounds of a window (write only!)

var winv: array[2, WinV]

Sets the upper and lower bounds of a window (write only!)

var win0cnt: WinCnt

Window 0 control

var win1cnt: WinCnt

Window 1 control

var winoutcnt: WinCnt

Out window control

var winobjcnt: WinCnt

Object window control

proc setWindow(winId: range[0..1], bounds: Rect)

Apply a rectangular window to one of the window registers.

The rectangle is clamped to the bounds of the screen.

Mosaic

var mosaic: Mosaic

Mosaic size register (write only!)

Blending

type BldCnt = distinct uint16

Blend control register

Field

Type

Bits

Description

a

BlendLayers

0-5

The upper layers to opt-into color special effects.

mode

BlendMode

6-7

Color special effects mode.

b

BlendLayers

8-13

The lower layers to opt-into color special effects.

type BlendMode = enum

Color special effects modes:

  • bmOffBlending disabled
  • bmAlphaAlpha A against B using the weights from bldalpha
  • bmWhiteBlend A with white using the weight from bldy
  • bmBlackBlend A with black using the weight from bldy
type BlendLayer = enum
  • blBg0
  • blBg1
  • blBg2
  • blBg3
  • blObj
  • blBd
type BlendLayers = set[BlendLayer]
const allBlendLayers = { blBg0, blBg1, blBg2, blBg3, blObj, blBd }
type BlendAlpha = distinct uint16

Alpha blending levels. Features two coefficients: eva for layer a, evb for layer b.

Field

Type

Bits

Description

eva

uint16

0-4

Upper layer alpha blending coefficient. Values from 17..31 are treated the same as 16.

evb

uint16

8-12

Lower layer alpha blending coefficient. Values from 17..31 are treated the same as 16.

type BlendBrightness = distinct uint16

Brightness level (fade to black or white). Has a single coefficient evy.

Field

Type

Bits

Description

evy

uint16

0-4

Brightness coefficient (write-only!) Values from 17..31 are treated the same as 16.

var bldcnt: BldCnt

Blend control register

var bldalpha: BlendAlpha

Alpha blending fade coefficients

var bldy: BlendBrightness

Brightness (fade in/out) coefficient (write only!)

Colors

Types

type Color = distinct uint16

A 15bpp BGR color value.

The red, green and blue components can be accessed via the following fields:

Field

Type

Bits

Description

r

int

0-4

Red component

g

int

5-9

Green component

b

int

10-14

Blue component

type Palette = array[16, Color]

A 16-color palette.

The first element in a palette is irrelevant, except for bgPalMem[0][0] (i.e. bgColorMem[0]) which sets the backdrop color for the entire screen.

Constructors

proc rgb5(red, green, blue: int): Color

Create a 15-bit BGR color.

proc rgb5safe(red, green, blue: int): Color

Create a 15-bit BGR color, with proper masking of R,G,B components.

proc rgb8(red, green, blue: uint8): Color

Create a 15-bit BGR color, using 8-bit components

proc rgb8(rgb: int): Color

Create a 15-bit BGR color from a 24-bit RGB color of the form 0xRRGGBB

Color memory

var bgColorMem: array[256, Color]

Access to BG PAL RAM as a single array of colors.

This is useful when working with 8bpp backgrounds, or display mode 4.

var bgPalMem: array[16, Palette]

Access to BG PAL RAM as a table of 16-color palettes.

This is useful when working when 4bpp backgrounds.

Example:

# set all colors of the first palette in memory to white.
for color in bgPalMem[0].mitems:
  color = clrWhite
var objColorMem: array[256, Color]

Access to OBJ PAL RAM as a single array of colors.

This is useful when working with 8bpp sprites.

var objPalMem: array[16, Palette]

Access to OBJ PAL RAM as a table of 16-color palettes.

This is useful when working when 4bpp sprites.

Color Constants

const clrBlack = 0x0000.Color
const clrRed = 0x001F.Color
const clrLime = 0x03E0.Color
const clrYellow = 0x03FF.Color
const clrBlue = 0x7C00.Color
const clrMagenta = 0x7C1F.Color
const clrCyan = 0x7FE0.Color
const clrWhite = 0x7FFF.Color
const clrDead = 0xDEAD.Color
const clrMaroon = 0x0010.Color
const clrGreen = 0x0200.Color
const clrOlive = 0x0210.Color
const clrOrange = 0x021F.Color
const clrNavy = 0x4000.Color
const clrPurple = 0x4010.Color
const clrTeal = 0x4200.Color
const clrGray = 0x4210.Color
const clrMedGray = 0x5294.Color
const clrSilver = 0x6318.Color
const clrMoneyGreen = 0x6378.Color
const clrFuchsia = 0x7C1F.Color
const clrSkyBlue = 0x7B34.Color
const clrCream = 0x7BFF.Color

Bulk color manipulation

These functions are lifted straight from libtonc.

They’re unsafe as they deal with raw pointers.

proc clrRotate(clrs: ptr Color, nclrs: cint, ror: cint)

Rotate nclrs colors at clrs to the right by ror.

proc clrBlend(srca: ptr Color, srcb: ptr Color, dst: ptr Color, nclrs: cint, alpha: cint)

Blends color arrays srca and srcb into dst. Specific transitional blending effects can be created by making a ‘target’ color array with other routines, then using alpha to morph into it.

Srca:

Source array A.

Srcb:

Source array B.

Dst:

Destination array.

Nclrs:

Number of colors.

Alpha:

Blend weight (range: 0-32). 0 Means full srca

proc clrFade(src: ptr Color, clr: Color, dst: ptr Color, nclrs: cint, alpha: cint)

Fades color arrays srca to clr into dst.

Src:

Source array.

Clr:

Final color (at alpha=32).

Dst:

Destination array.

Nclrs:

Number of colors.

Alpha:

Blend weight (range: 0-32). 0 Means full srca

proc clrGrayscale(dst: ptr Color, src: ptr Color, nclrs: cint)

Transform colors to grayscale.

Dst:

Destination color array

Src:

Source color array.

Nclrs:

Number of colors.

proc clrRgbscale(dst: ptr Color, src: ptr Color, nclrs: cint, clr: Color)

Transform colors to an rgb-scale.

Note

clr indicates a color vector in RGB-space. Each source color is converted to a brightness value (i.e. grayscale) and then mapped onto that color vector. A grayscale is a special case of this, using a color with R=G=B.

Dst:

Destination color array

Src:

Source color array.

Nclrs:

Number of colors.

Clr:

Destination color vector.

proc clrAdjBrightness(dst: ptr Color, src: ptr Color, nclrs: cint, bright: Fixed)

Adjust brightness by bright.

Operation: color = color+dB

Dst:

Destination color array

Src:

Source color array.

Nclrs:

Number of colors.

Bright:

Brightness difference (dB)

proc clrAdjContrast(dst: ptr Color, src: ptr Color, nclrs: cint, contrast: Fixed)

Adjust contrast by contrast.

Operation: color = color*(1+dC) - MAX*dC/2

Dst:

Destination color array

Src:

Source color array.

Nclrs:

Number of colors.

Contrast:

Contrast difference (dC)

proc clrAdjIntensity(dst: ptr Color, src: ptr Color, nclrs: cint, intensity: Fixed)

Adjust intensity by intensity.

Operation: color = (1+dI)*color.

Dst:

Destination color array

Src:

Source color array.

Nclrs:

Number of colors.

Intensity:

Intensity difference (dI)

proc palGradient(pal: ptr Color, first: cint, last: cint)

Create a gradient between pal[first] and pal[last].

Pal:

Palette to work on.

First:

First index of gradient.

Last:

Last index of gradient.

proc palGradient(pal: ptr Color, first, last: cint, clrFirst, clrLast: Color)

Create a gradient between pal[first] and pal[last].

Pal:

Palette to work on.

First:

First index of gradient.

Last:

Last index of gradient.

ClrFirst:

Color of first index.

ClrLast:

Color of last index.

proc clrBlendFast(srca: ptr Color, srcb: ptr Color, dst: ptr Color, nclrs: cint, alpha: cint)

Blends color arrays srca and srcb into dst.

Srca:

Source array A.

Srcb:

Source array B.

Dst:

Destination array.

Nclrs:

Number of colors.

Alpha:

Blend weight (range: 0-32).

Note

This is an ARM assembly routine placed in IWRAM, which makes it very fast, but keep in mind that IWRAM is a limited resource.

proc clrFadeFast(src: ptr Color, clr: Color, dst: ptr Color, nclrs: cint, alpha: cint)

Fades color arrays srca to clr into dst.

Src:

Source array.

Clr:

Final color (at alpha=32).

Dst:

Destination array.

Nclrs:

Number of colors.

Alpha:

Blend weight (range: 0-32).

Note

This is an ARM assembly routine placed in IWRAM, which makes it very fast, but keep in mind that IWRAM is a limited resource.

Tiled backgrounds

Tile data

type Tile = Tile4
type Tile4 = object

4bpp tile type, for easy indexing and copying of 16-color tiles

    Field    

    Type    

data array[8, uint32]
type Tile8 = object

8bpp tile type, for easy indexing and copying of 256-color tiles

    Field    

    Type    

data array[16, uint32]
type Charblock = array[CbbTiles, Tile]
type Charblock8 = array[CbbTiles div 2, Tile8]
type UnboundedCharblock = distinct array[CbbTiles, Tile]
type UnboundedCharblock8 = distinct array[CbbTiles div 2, Tile8]
var bgTileMem: array[4, UnboundedCharblock]

BG charblocks, 4bpp tiles.

Note

While bgTileMem[0] has 512 elements, it’s valid to reach across into the neighbouring charblock, for example bgTileMem[0][1000]. For this reason, bounds checking is not performed on tile memory even when compiling with --checks:on.

Example:

bgTileMem[i][j]   # Get image data from tile `j` in charblock `i`.
var bgTileMem8: array[4, UnboundedCharblock8]

BG charblocks, 8bpp tiles.

Example:

bgTileMem8[i][j]   # Get image data from tile `j` in charblock `i`.
var objTileMem: array[1024, Tile]

Object (sprite) image data, as 4bpp tiles.

This is 2 charblocks in size, and is separate from BG tile memory.

Example:

objTileMem[n] = Tile()   # Clear the image data for a sprite tile.
var objTileMem8: array[512, Tile8]

Object (sprite) tiles, 8bpp.

Screen entries

type ScrEntry = distinct uint16

Type for screen entries (i.e. the values that make up a tile map)

Each screen entry is a bitfield with the following attributes:

Field

Type

Bits

Description

tileId

int

0-9

Tile to display (relative to the background’s cbb × 512)

hflip

bool

10

Flip horizontally

vflip

bool

11

Flip vertically

palId

int

12-15

Palette to use (ignored for 8bpp backgrounds)

tid

int

0-9

Alias for tileId

pal

int

12-15

Alias for palId

type ScrAffEntry = uint8

Type for affine screen entries

type Screenline = array[32, ScrEntry]
type ScreenMat = array[32, Screenline]
type Screenblock = array[1024, ScrEntry]
var seMem: array[32, Screenblock]

Screenblocks as arrays.

Example:

seMem[i]       # screenblock i
seMem[i][j]    # screenblock i, entry j
seMem[i][x,y]  # screenblock i, entry x + y*32

Screen entry tile plotting

proc fill(sbb: var Screenblock, se: ScrEntry)

Fill screenblock sbb with se.

proc plot(sbb: var Screenblock, x, y: cint, se: ScrEntry)

Plot a screen entry at (x,`y`) of screenblock sbb.

proc hline(sbb: var Screenblock, x0, x1, y: cint, se: ScrEntry)

Draw a horizontal line on screenblock sbb with se.

proc vline(sbb: var Screenblock, x, y0, y1: cint, se: ScrEntry)

Draw a vertical line on screenblock sbb with se.

proc rect(sbb: var Screenblock, left, top, right, bottom: cint, se: ScrEntry)

Fill a rectangle on sbb with se.

proc frame(sbb: var Screenblock, left, top, right, bottom: cint, se: ScrEntry)

Create a border on sbb with se.

proc window(sbb: var Screenblock, left, top, right, bottom: cint, se0: ScrEntry)

Create a fancy rectangle.

In contrast to frame, this uses nine tiles starting at se0 for the frame, which indicate the borders and center for the window.

Note

The rectangle is not normalized. You should ensure that left < right and bottom < top.

proc clearRow(sbb: var Screenblock, row: range[0..31])

Bitmap Drawing

To use the bitmap drawing procedures, you have to set the appropriate bitmap mode and enable background layer 2.

e.g.

dispcnt.init(mode = 3, layers = {lBg2})

# draw a green pixel at x=100, y=100
m3mem.plot(100, 100, clrGreen)
var vidMem: array[240*160, Color]

Main mode 3/5 frame as an array

Example:

vidMem[i]    # Get pixel `i` as a Color.
var vidMemFront: array[160*128, uint16]

First page array

var vidMemBack: array[160*128, uint16]

Second page array

Mode 3

type M3Mem = array[160, array[240, Color]]
var m3Mem: M3Mem

Mode 3 frame as a matrix.

Example:

m3Mem[y][x]  # Get pixel (x, y) as a Color.
proc fill(m: var M3Mem, clr: Color)

Fill the mode 3 background with color clr.

proc plot(m: var M3Mem, x, y: cint, clr: Color)

Plot a single colored pixel in mode 3 at (x, y).

proc hline(m: var M3Mem, x1, y, x2: cint, clr: Color)

Draw a colored horizontal line in mode 3.

proc vline(m: var M3Mem, x, y1, y2: cint, clr: Color)

Draw a colored vertical line in mode 3.

proc line(m: var M3Mem, x1, y1, x2, y2: cint, clr: Color)

Draw a colored line in mode 3.

proc rect(m: var M3Mem, left, top, right, bottom: cint, clr: Color)

Draw a colored rectangle in mode 3.

Left:

Left side, inclusive.

Top:

Top size, inclusive.

Right:

Right size, exclusive.

Bottom:

Bottom size, exclusive.

Clr:

Color.

Note

The rectangle is normalized, but not clipped.

proc frame(m: var M3Mem, left, top, right, bottom: cint, clr: Color)

Draw a colored frame in mode 3.

Left:

Left side, inclusive.

Top:

Top size, inclusive.

Right:

Right size, exclusive.

Bottom:

Bottom size, exclusive.

Clr:

Color.

Note

The rectangle is normalized, but not clipped.

Mode 4

type M4Mem = array[160, array[240, uint8]]

Note

VRAM does not support 8-bit writes. Do not attempt to use this to write bytes directly to VRAM! (try one of the plot() procedures instead?)

var m4Mem: M4Mem

Mode 4 first page as a matrix.

Note

This is a byte-buffer, not to be used for writing.

Example:

m4Mem[y][x]  # Get pixel (x, y) as a uint8.
var m4MemBack: M4Mem

Mode 4 second page as a matrix.

This is a byte-buffer. Not to be used for writing.

Example:

m4MemBack[y][x]  # Get pixel (x, y) as a uint8.
proc fill(m: var M4Mem, clrid: uint8)

Fill the given mode 4 buffer with clrid.

proc plot(m: var M4Mem, x, y: cint, clrid: uint8)

Plot a clrid pixel on the given mode 4 buffer.

proc hline(m: var M4Mem, x1, y, x2: cint, clrid: uint8)

Draw a clrid colored horizontal line in mode 4.

proc vline(m: var M4Mem, x, y1, y2: cint, clrid: uint8)

Draw a clrid colored vertical line in mode 4.

proc line(m: var M4Mem, x1, y1, x2, y2: cint, clrid: uint8)

Draw a clrid colored line in mode 4.

proc rect(m: var M4Mem, left, top, right, bottom: cint, clrid: uint8)

Draw a clrid colored rectangle in mode 4.

Left:

Left side, inclusive.

Top:

Top size, inclusive.

Right:

Right size, exclusive.

Bottom:

Bottom size, exclusive.

Clrid:

Color index.

Note

The rectangle is normalized, but not clipped.

proc frame(m: var M4Mem, left, top, right, bottom: cint, clrid: uint8)

Draw a clrid colored frame in mode 4.

Left:

Left side, inclusive.

Top:

Top size, inclusive.

Right:

Right size, exclusive.

Bottom:

Bottom size, exclusive.

Clrid:

Color index.

Note

The rectangle is normalized, but not clipped.

Mode 5

type M5Mem = array[128, array[160, Color]]
var m5Mem: M5Mem

Mode 5 first page as a matrix.

Example:

m5Mem[y][x]  # Get pixel (x, y) as a Color.
var m5MemBack: M5Mem

Mode 5 second page as a matrix.

Example:

m5MemBack[y][x]  # Get pixel (x, y) as a Color.
proc fill(m: var M5Mem, clr: Color)

Fill the given mode 5 buffer with clr.

proc plot(m: var M5Mem, x, y: cint, clr: Color)

Plot a clrid pixel on the given mode 5 buffer.

proc hline(m: var M5Mem, x1, y, x2: cint, clr: Color)

Draw a colored horizontal line in mode 5.

proc vline(m: var M5Mem, x, y1, y2: cint, clr: Color)

Draw a colored vertical line in mode 5.

proc line(m: var M5Mem, x1, y1, x2, y2: cint, clr: Color)

Draw a colored line in mode 5.

proc rect(m: var M5Mem, left, top, right, bottom: cint, clr: Color)

Draw a colored rectangle in mode 5.

Left:

Left side, inclusive.

Top:

Top size, inclusive.

Right:

Right size, exclusive.

Bottom:

Bottom size, exclusive.

Clr:

Color.

Note

The rectangle is normalized, but not clipped.

proc frame(m: var M5Mem, left, top, right, bottom: cint, clr: Color)

Draw a colored frame in mode 5.

Left:

Left side, inclusive.

Top:

Top size, inclusive.

Right:

Right size, exclusive.

Bottom:

Bottom size, exclusive.

Clr:

Color.

Note

The rectangle is normalized, but not clipped.

Objects Attribute Memory

Object Attributes

type ObjAttr = object

Object attributes are the parameters of a sprite.

The following accessors are available to work with them:

Field

Type

Description

x

int

X coordinate of the sprite’s top-left corner (0 .. 511)

y

int

Y coordinate of the sprite’s top-left corner (0 .. 255)

pos

Vec2i

Access the X and Y coordinates as a pair.

mode

ObjMode

One of omRegular, omAffine, omHidden, omAffineDouble.

fx

ObjFxMode

One of fxNone, fxBlend, fxWindow.

mos

bool

Enables mosaic effect.

hflip

bool

Horizontal flip (if mode is omRegular)

vflip

bool

Vertical flip (if mode is omRegular)

affId

int

Affine matrix to use (0 .. 31), if mode is omAffine or omAffineDouble.

is8bpp

bool

Display 8bpp tiles if true, 4bpp otherwise.

size

ObjSize

Determines the width and height of the sprite.

tileId

int

The base tile of the sprite (0 .. 1023), i.e. index into objTileMem.

palId

int

Which palette to use in 4bpp mode (0 .. 15), i.e. index into objPalMem.

prio

int

Priority value (0 = front, 3 = back)

tid

int

Alias for tileId.

pal

int

Alias for palId.

The raw underlying fields are as follows:

    Field    

    Type    

    Description    

attr0 uint16

Attribute 0

attr1 uint16

Attribute 1

attr2 uint16

Attribute 2

fill int16

Warning

Messing with fill could screw up scaling/rotation that you applied to other sprites!

Padding which exists because ObjAttr and ObjAffine are overlaid in memory.

This field will not be copied when assigning one ObjAttr to another. Therefore you may use it for any purpose if your object exists outside of OAM and you intend to copy it over later.

type ObjAttrPtr = ptr ObjAttr

Pointer to object attributes.

type ObjMode = enum
  • omRegularThe object is displayed normally, possibly with horizontal/vertical flipping.
  • omAffineThe object is transformed according to the matrix specified by affId.
  • omHiddenThe object is not displayed.
  • omAffineDoubleLike omAffine, but the sprite’s clipping rectangle is doubled in size.
    This has the side effect of moving the sprite’s center down and to-the-right by half its size.
type ObjFxMode = enum
  • fxNoneNormal object, no special effects.
  • fxBlendAlpha blending enabled. The object is effectively placed into the bldcnt.a layer to be blended with the bldcnt.b layer using the coefficients from bldalpha, regardless of the current bldcnt.mode setting.
  • fxWindowThe sprite becomes part of the object window.
type ObjSize = enum

Sprite size constants, high-level interface. Each corresponds to a pair of fields (size in attr0, shape in attr1)

  • s8x8
  • s16x16
  • s32x32
  • s64x64
  • s16x8
  • s32x8
  • s32x16
  • s64x32
  • s8x16
  • s8x32
  • s16x32
  • s32x64
var objMem: array[128, ObjAttr]

Object attribute memory (where sprite properties belong).

Example:

var myObj: ObjAttr

# Set up a sprite with some values:
myObj.init(
  pos = vec2i(x, y),
  tid = tid,
  pal = pal,
  size = s16x16,
  prio = 0,
)

# Later (during vblank) copy it into a slot in OAM:
objMem[i] = myObj
var objAffMem: array[32, ObjAffine]

Object affine matrix memory.

This is where the transformation matrices for sprites belong.

Example:

var myObj: ObjAttr
var affId = 0       # index of some matrix
var angle = 0x2000  # 45 degrees

# Set up a sprite to use an affine matrix.
myObj.init(
  mode = omAffine,
  affId = affId,
  pos = vec2i(x, y),
  tid = tid,
  pal = pal,
  size = s16x16,
)

# Later (during vblank):
objMem[i] = myObj                      # copy object into OAM.
objAffMem[affId].setToRotation(angle)  # rotate by 45 degrees anticlockwise.
template initObj(args: varargs[untyped]): ObjAttr

Create a new ObjAttr value.

Example:

objMem[0] = initObj(
  pos = vec2i(100, 100),
  size = s32x32,
  tileId = 0,
  palId = 3
)
template init(obj: ObjAttrPtr | var ObjAttr, args: varargs[untyped])

Initialise an object in-place.

Omitted fields will default to zero.

Example:

objMem[0].init(
  pos = vec2i(100, 100),
  size = s32x32,
  tileId = 0,
  palId = 3
)
template edit(obj: ObjAttrPtr | var ObjAttr, args: varargs[untyped])

Change some fields of an object.

Like obj.init, but omitted fields will be left unchanged.

objMem[0].edit(
  pos = vec2i(100, 100),
  size = s32x32,
  tileId = 0,
  palId = 3
)
template dup(obj: ObjAttr, args: varargs[untyped]): ObjAttr

Duplicate an object, modifying some fields and returning the copy.

Example:

# Make a copy of Obj 0, but change some properties:
objMem[1] = objMem[0].dup(x = 100, hflip = true)

Obj Helpers

func hide(obj: var ObjAttr)

Hide an object.

Equivalent to obj.mode = omHidden

func unhide(obj: var ObjAttr, mode = omRegular)

Unhide an object.

Equivalent to obj.mode = mode

Parameters:

obj

Object to unhide.

mode

Object mode to unhide to. Necessary because this affects the affine-ness of the object.

func getSize(size: ObjSize): tuple[w, h: int]

Get the width and height in pixels of an ObjSize enum value.

func getWidth(size: ObjSize): int

Get the width in pixels of an ObjSize enum value.

func getHeight(size: ObjSize): int

Get the height in pixels of an ObjSize enum value.

func getSize(obj: ObjAttr | ObjAttrPtr): tuple[w, h: int]

Get the width and height of an object in pixels.

func getWidth(obj: ObjAttr | ObjAttrPtr): int

Get the width of an object in pixels.

func getHeight(obj: ObjAttr | ObjAttrPtr): int

Get the height of an object in pixels.

Affine Matrices

Types

type AffSrc = object

Simple scale-rotation source struct. This can be used with ObjAffineSet(), and several of Tonc’s affine functions.

    Field    

    Type    

    Description    

sx FixedT[int16, 8]

Horizontal zoom (8.8f)

sy FixedT[int16, 8]

Vertical zoom (8.8f)

alpha uint16

Counter-clockwise angle (range 0..0xffff)

type AffSrcEx = object

Extended scale-rotate source struct. This is used to scale/rotate around an arbitrary point. See Tonc for all the details.

    Field    

    Type    

    Description    

texX Fixed

Texture-space anchor, x coordinate (.8f)

texY Fixed

Texture-space anchor, y coordinate (.8f)

scrX int16

Screen-space anchor, x coordinate (.0f)

scrY int16

Screen-space anchor, y coordinate (.0f)

sx FixedT[int16, 8]

Horizontal zoom (8.8f)

sy FixedT[int16, 8]

Vertical zoom (8.8f)

alpha uint16

Counter-clockwise angle (range [0, 0xFFFF])

type AffDst = object

Simple scale-rotation destination struct. This is a P-matrix with contiguous elements, like the BG matrix. It can be used with ObjAffineSet().

    Field    

    Type    

pa FixedT[int16, 8]
pb FixedT[int16, 8]
pc FixedT[int16, 8]
pd FixedT[int16, 8]
type AffDstEx = object

Extended scale-rotate destination struct.

This contains the P-matrix and a fixed-point offset, the combination can be used to rotate around an arbitrary point.

Mainly intended for BgAffineSet(), but can be used for object transforms too.

    Field    

    Type    

pa FixedT[int16, 8]
pb FixedT[int16, 8]
pc FixedT[int16, 8]
pd FixedT[int16, 8]
dx int32
dy int32
type BgAffineSource = AffSrcEx
type BgAffineDest = AffDstEx
type ObjAffineSource = AffSrc
type ObjAffineDest = AffDst
type BgAffine = AffDstEx

Affine parameters for backgrounds, as used by bgaff[2..3].

type ObjAffine = object

Object affine parameters.

    Field    

    Type    

fill0 array[3, uint16]
pa int16
fill1 array[3, uint16]
pb int16
fill2 array[3, uint16]
pc int16
fill3 array[3, uint16]
pd int16

Obj Transforms

proc init(oaff: var ObjAffine, pa, pb, pc, pd: Fixed)

Set the elements of an object affine matrix.

proc setToIdentity(oaff: var ObjAffine)

Set an object affine matrix to the identity matrix.

proc setToScale(oa: var ObjAffine, sx: Fixed, sy = sx)

Set an object affine matrix for scaling.

proc setToShearX(oa: var ObjAffine, hx: Fixed)
proc setToShearY(oa: var ObjAffine, hy: Fixed)
proc setToRotation(oa: var ObjAffine, theta: uint16)

Set obj matrix to counter-clockwise rotation.

Oaff:

Object affine matrix to set.

Alpha:

CCW angle. full-circle is 0x10000.

proc setToScaleAndRotation(oa: var ObjAffine, sx, sy: Fixed, theta: uint16)

Set obj matrix to 2d scaling, then counter-clockwise rotation.

Oaff:

Object affine matrix to set.

Sx:

Horizontal scale (zoom). .8 fixed point.

Sy:

Vertical scale (zoom). .8 fixed point.

Alpha:

CCW angle. full-circle is 0x10000.

proc premul(dst: var ObjAffine, src: ObjAffine)

Pre-multiply the matrix dst by src. i.e.

dst = src * dst
proc postmul(dst: var ObjAffine, src: ObjAffine)

Post-multiply the matrix dst by src. i.e.

dst = dst * src
proc rotscaleEx(obj: var ObjAttr, oaff: var ObjAffine, asx: ptr AffSrcEx)

Rot/scale an object around an arbitrary point. Sets up obj and oaff for rot/scale transformation around an arbitrary point using the asx data.

Obj:

Object to set.

Oaff:

Object affine data to set.

Asx:

Affine source data: screen and texture origins, scales and angle.

proc setToScaleRaw(oaff: var ObjAffine, sx, sy: Fixed)

Mathematically correct version of setToScale, but does the opposite of what you’d expect (since the matrix maps from screen space to texture space).

proc setToRotationRaw(oaff: var ObjAffine, alpha: uint16)

Mathematically correct version of setToRotation, but does the opposite of what you’d expect (since the matrix maps from screen space to texture space).

proc setToShearXRaw(oaff: var ObjAffine, hx: Fixed)
proc setToShearYRaw(oaff: var ObjAffine, hy: Fixed)

BG Transforms

proc init(bgaff: var BgAffine, pa, pb, pc, pd: Fixed)

Set the elements of a bg affine matrix.

proc setToIdentity(bgaff: var BgAffine)

Set a bg affine matrix to the identity matrix

proc setToScale(bgaff: var BgAffine, sx: Fixed, sy = sx)

Set an bg affine matrix for scaling.

proc setToShearX(bgaff: var BgAffine, hx: Fixed)
proc setToShearY(bgaff: var BgAffine, hy: Fixed)
proc setToRotation(bgaff: var BgAffine, theta: uint16)

Set bg matrix to counter-clockwise rotation.

Bgaff:

BG affine struct to set.

Alpha:

CCW angle. full-circle is 0x10000.

proc setToScaleAndRotation(bgaff: var BgAffine, sx, sy: Fixed, theta: uint16)

Set bg matrix to 2d scaling, then counter-clockwise rotation.

Bgaff:

BG affine struct to set.

Sx:

Horizontal scale (zoom). 24.8 fixed point.

Sy:

Vertical scale (zoom). 24.8 fixed point.

Alpha:

CCW angle. full-circle is 0x10000.

proc premul(dst: var BgAffine, src: ptr BgAffine)

Pre-multiply the matrix dst by src

i.e. dst = src * dst

Warning

Don’t use this on bgaff registers directly, as they are write-only.

proc postmul(dst: var BgAffine, src: ptr BgAffine)

Post-multiply the matrix dst by src

i.e. dst = dst * src

Warning

Don’t use this on bgaff registers directly, as they are write-only.

proc rotscaleEx(bgaff: var BgAffine, asx: ptr AffSrcEx)

Set bg affine matrix to a rot/scale around an arbitrary point.

Bgaff:

BG affine data to set.

Asx:

Affine source data: screen and texture origins, scales and angle.

proc setToScaleRaw(bgaff: var BgAffine, sx, sy: Fixed)
proc setToRotationRaw(bgaff: var BgAffine, alpha: uint16)
proc setToShearXRaw(bgaff: var BgAffine, hx: Fixed)
proc setToShearYRaw(bgaff: var BgAffine, hy: Fixed)