Advanced Graphics Layer

Introduction

This article introduces a simple way to encode advanced graphics in the browser. It'll be inspired by the graphics of retro consoles like the NES and GameBoy. There will be two types of graphics, objects and tiled. Objects will be individually programmable. Tiles will be scrollable. Both objects and tiles will read from the same sprite sheet and palette table. Objects and tiles will be scrollable. There'll be one object layer. There'll be two tiled layers, a background and a window.

Example

Specification

  • Memory map
$0000-$0fff     $1000   Zero page
$1000-$1fff     $1000   System registers
$2000-$2fff     $1000   Sprite table A
$3000-$3fff     $1000   Sprite table B
$4000-$4fff     $1000   Sprite table C
$5000-$5fff     $1000   Sprite table D
$6000-$6fff     $1000   Object memory
$7000-$7fff     $1000   Background memory
$8000-$8fff     $1000   Window memory
$9000-$ffff     $7000   Unallocated

TODO - mouse selection
TODO - collision detection
  • System registers
CTRL        $1000   ---- ---M
STATUS      $1001   DDDD DDDD
OSCRLX      $1002   XXXX XXXX XXXX XXXX     Object scroll X
OSCRLY      $1004   YYYY YYYY YYYY YYYY     Object scroll Y
BSCRLX      $1006   XXXX XXXX XXXX XXXX     Background scroll X
BSCRLY      $1008   YYYY YYYY YYYY YYYY     Background scroll Y
WSCRLX      $100a   XXXX XXXX XXXX XXXX     Window scroll X
WSCRLY      $100c   YYYY YYYY YYYY YYYY     Window scroll Y
SWIDTH      $100e   WWWW WWWW WWWW WWWW     Screen width
SHIGHT      $1010   HHHH HHHH HHHH HHHH     Screen height
TICKKK      $1012   TTTT TTTT TTTT TTTT     Current tick, increments
MILLIS      $1014   MMMM MMMM MMMM MMMM     Last tick milliseconds
MOUSEX      $1016   XXXX XXXX XXXX XXXX     Mouse X position
MOUSEY      $1018   YYYY YYYY YYYY YYYY     Mouse Y position
KEYPRA      $101a   AAAA AAAA               Key press A
KEYPRB      $101b   BBBB BBBB               Key press B

PALET0      $1020   4 bytes ABCD            Palette 0 (sprite)
PALET1      $1024   4 bytes ABCD            Palette 1 (sprite)
PALET2      $1028   4 bytes ABCD            Palette 2 (sprite)
PALET3      $102c   4 bytes ABCD            Palette 3 (sprite)
PALET4      $1030   4 bytes ABCD            Palette 4 (sprite)
PALET5      $1034   4 bytes ABCD            Palette 5 (sprite)
PALET6      $1038   4 bytes ABCD            Palette 6 (sprite)
PALET7      $103c   4 bytes ABCD            Palette 7 (sprite)

PALET8      $1040   4 bytes ABCD            Palette 8 (background)
PALET9      $1044   4 bytes ABCD            Palette 9 (background)
PALETa      $1048   4 bytes ABCD            Palette a (background)
PALETb      $104c   4 bytes ABCD            Palette b (background)
PALETc      $1050   4 bytes ABCD            Palette c (background)
PALETd      $1054   4 bytes ABCD            Palette d (background)
PALETe      $1058   4 bytes ABCD            Palette e (background)
PALETf      $105c   4 bytes ABCD            Palette f (background)
  • Object memory

Object memory is 4096 bytes total, comprising of an array of 512 elements, 8 bytes in size. Each consecutive 8 bytes corresponds to an object. Objects are rendered in order of the array, later elements will overlap. The renderer will stop drawing when it receives an address of 0.

XPOS    0   2 bytes                 X position of the sprite
YPOS    2   2 bytes                 Y position of the sprite
ATTA    4   7654 3210               Attribute register A
            |||| ||||
            |||| ++++ Palette of sprite
            ||++----- Mode
            |+------- 2 colour mode (default 4 colours)
            +-------- Text mode
ATTB    5   7654 3210               Attribute register A
            |||| ||++ Priority
            |||| |+-- Flip sprite horizontally
            |||| +--- Flip sprite vertically
            ||++----- Scroll mode
            |+------- Transparency
            +-------- (Unused)
ADDR    6   2 bytes                 Sprite address / text address

Mode (default)

  • 00: 8x8
  • 01: 8x16
  • 10: 16x8
  • 11: 16x16

Mode (text)

  • 00: 4x8
  • 01: 8x8
  • 10: 8x16
  • 11: 16x16

Priority

  • 00: behind background
  • 01: in front of background
  • 10: in front of window
  • 11: in front of window

Scroll mode

  • 00: sprite scroll

  • 01: background scroll

  • 10: window scroll

  • 11: no scroll

  • Sprite table

The sprite table is 4096 bytes total. It's a 16x16 grid of 2x 8 byte chunks. Each byte represents a row of the sprite. The sprite table is used by both object memory and background memory.

0   1   2   3   4   5   6   7   8   9   a   b   c   d   e   f
00
10
20
30
40
50
60
70
80
90
a0
b0
c0
d0
e0
f0

The sprite itself is composed of 2x 8 byte rows. Each byte represents a row of the 8x8 sprite. The first 8 bytes represent the first bit in the palette table, the second bit represents the latter.

0   0000 0000       8   0000 0000
1   0000 0000       9   0000 0000
2   0000 0000       a   0000 0000
3   0000 0000       b   0000 0000
4   0000 0000       c   0000 0000
5   0000 0000       d   0000 0000
6   0000 0000       e   0000 0000
7   0000 0000       f   0000 0000
  • Background memory

The background memory is 4096 bytes in size. It is a 64x64 grid of sprites. It wraps around defined by the background scroll registers.

SPRITE  0   NNNN NNNN   Index of the sprite
ATTR    1   7654 3210               Attribute register (TODO - 2 bytes, for text, sprite sizes etc)
            |||| ||||
            |||| ||++ Sprite sheet selection
            |||+ ++-- Palette of sprite
            |||
            ||+------ TODO
            |+------- Flip sprite horizontally
            +-------- Flip sprite vertically
  • Window memory

Window memory is the exact same structure as the background memory. It sits on top of all sprites and is rendered last.

  • Palettes

A palette define the colours that are given to sprites. Each palette is a 4 byte sequence, where the first byte defines the brightness. If the brightness is 0, then all sprite values of 0 are considered transparent. There are 16 palettes, the first 8 are used for sprites, the second 8 are used for backgrounds.