Chris Collins

Tools · retro

Amiga sprites and BOBs

Draw Amiga hardware sprites (3 colours, or 15 as an attached pair) and blitter objects of any depth, animate them frame by frame, import a PNG onto the palette, and export the data words with SPRxPOS/SPRxCTL, or the BOB's planes, mask and cookie-cut blitter set-up, as assembler or C.

Added

How to use it

Two editors, one per tab, work the same way: pick a colour from the palette and draw on the grid (drag to paint; right-click or the transparent swatch erases). Fill floods an area, Pick takes a colour from the picture. ⇆ and ⇅ flip the frame. Every colour is a 12-bit OCS value: choose a swatch, then set it with the colour box beside the palette (it is rounded to 4 bits per channel). The red lines mark 16-pixel words.

Frames — Duplicate or Blank adds a frame after the current one; ◀ ▶ move it; Onion skin shows the previous frame faintly under the one you are drawing. Play runs the animation in the preview at the frames per second you set.

Import PNG… scales a picture to the editor (16 pixels wide for a sprite) and maps every pixel to the nearest palette colour; transparent pixels stay transparent. Import with its colours… first fills the palette with the picture’s most common colours.

Hardware sprite

A sprite is 16 pixels wide and any number of lines high, with two bits per pixel: three colours plus transparent. Sprites 0/1, 2/3, 4/5 and 6/7 share their colours — COLOR17–19, 21–23, 25–27 and 29–31. Tick Attached pair to combine an even and odd sprite into one 15-colour sprite using COLOR17–31; the odd sprite holds bits 2 and 3 and has the attach bit set in its CTL word.

Set the sprite number, height and the position as HSTART (lowres pixels) and VSTART (lines). The panel shows SPRxPOS and SPRxCTL, the colour registers used, and where the sprite can be shown again lower on the screen. The export is the sprite’s DMA list — POS, CTL, a DATA/DATB word pair per line, then two zero words — as dc.w or a C UWORD __chip array, one per frame (two per frame for an attached pair), with the colour values as a comment.

BOB

A BOB is a picture of any width and depth drawn with the blitter. Colour 0 is the background: the mask is the OR of all planes, so only non-zero pixels are drawn. Set Blit at x, y, the screen’s bytes per row (40 for 320 pixels), and whether the screen’s planes are interleaved. The panel gives the cookie-cut set-up: BLTCON0/BLTCON1 with the shift, the first/last word masks, the four modulos, BLTSIZE and the destination offset. The export has the planes (interleaved row by row, or one array per plane) and the mask — repeated for every plane when interleaved, so a single blit draws all planes.

⛶ Full screen (or F) gives the pixel editor the whole screen — the browser’s full screen where it is allowed, otherwise a full-window layer (iPhone) — with the settings and export beside it on a wide screen; ◫ Panels hides them. Escape leaves.

Notes

From the Amiga Hardware Reference Manual (3rd edition), chapters 4 and 6:

  • SPRxPOS = VSTART[7:0] << 8 | HSTART[8:1]; SPRxCTL = VSTOP[7:0] << 8 | ATT << 7 | VSTART[8] << 2 | VSTOP[8] << 1 | HSTART[0]. VSTOP is the first line after the sprite. The manual’s example sprite at VSTART $6D, HSTART $C0, five lines high has the control words $6D60, $7200 (it is the HRM example preset).

  • Each line is two words: SPRxDATA (bit 0 of each pixel, leftmost pixel in bit 15) then SPRxDATB (bit 1).

  • Multiplexing: when a sprite ends, its DMA channel reads the next two words as new POS/CTL. Put another sprite’s control words there instead of 0, 0 and the same hardware sprite appears again further down — at least one line after the previous VSTOP. Games also rewrite the sprite pointers with the copper. Sprite DMA uses two slots per sprite per line; see DMA slot timing for why overscan costs sprites.

  • AGA: BPLCON4 bits ESPRM and OSPRM move the even and odd sprites' colours to any bank of 16 registers (COLOR16 + bank × 16); AGA sprites can also be 32 or 64 pixels wide (not drawn here).

  • Cookie-cut: A = mask, B = BOB, C and D = the screen, minterm D = AB + aC = LF $CA, so BLTCON0 = shift << 12 | $0FCA and BLTCON1 = shift << 12. Blitting one word wider than the BOB lets the shifted bits land; BLTALWM = 0 and source modulo −2 make the extra word read nothing. BLTSIZE = rows × 64 + words (rows = height × depth when interleaved).

Limits

  • The editor draws at most 320 × 256 pixels and 6 bitplanes for a BOB; sprites are 16 pixels wide (no AGA wide sprites).

  • The export is the data; it doesn’t write the copper list or the code that restores the background behind a BOB.

  • PNG import uses nearest-colour mapping without dithering; Import with its colours picks the most frequent 12-bit colours, which suits pixel art more than photos.

Related: DMA slot timing, copper and blitter playground (run the cookie-cut blit), custom chip registers (SPRxPOS, SPRxCTL, BPLCON4), IFF ILBM pictures, Amiga dev bench.

Linking to an example

Share link copies a link with both editors' drawings and settings (packed into ?s=), and the open tab in the #hash. Hand-written links can open a preset:

Parameter Meaning Example

example

arrow (pointer), hrm (the manual’s sprite), ball (attached, 4 frames), bob:ball (32 × 32 boing ball BOB, 8 frames — add #bob)

example=hrm

Runs entirely in your browser; nothing you type leaves this page.