# The grid

The grid is a matrix of characters that represents what is seen on a screen. It
has a fixed number of columns (COLS) and lines (LINES) and maintains a current
position (pos) as a single number encoded as "y*COLS+x".

The grid API revolves around the "grid" value, around which all its words are
built. One creates a new grid through "newgrid" (or rather a grid implementation
"new" word) which yield a pointer to a struct compatible with the "grid" value.

The Grid API allows one to write a character at an arbitrary position in the
matrix, through for example "cell! ( c pos -- )". It also supplies
"gridemit ( c -- )" which can be hooked into "EMIT" to have a grid driven
console.

If a NL character ($0a) is emitted, the grid skips to the next line. If a BS
character ($08) is written to it, the cursor goes back one character.

In newline conditions (NL character or wrapping around the end of line), we
clear the next line and move the cursor there. If we're at the end of the
screen, we scroll if the underlying driver allows it. Otherwise, we wrap around
to the top.

This unit also supplies "gridstream ( -- stream )" which yields a struct
compatible with [io/stream] . This stream is write only. Writing to it is like
emitting, but it doesn't move the cursor (it advances "pos" though).

## API

Global fields (bound to "grid"):

COLS
  Width, in characters, of the grid.

LINES
  Height, in characters, of the grid.

pos
  Current position of the cursor

highlight
  Boolean flag indicating whether written cells should be "highlighted".
  Changing this flag doesn't affect existing contents on the screen, only newly
  written content.

Words:

newgrid ( 'newln 'cursor! 'cell! cols lines -- grid )
  Create a new grid with the specifield fields. The three first one are pointers
  to words implementing the words with the corresponding name, described below.

cell! ( c pos -- )
  Set content of the cell at "pos" to character "c". Should honor the
  "highlight" flag.

cursor! ( pos -- )
  Move cursor to "pos".

newln ( oldln -- newln )
  Prepare new line under line number "newln" and return the line number of that
  prepared line as "newln". Normally, "newln" is "oldln+1", but if scrolling is
  involved, then "newln" will be "oldln".

highlight! ( f -- )
  Set "highlight" field to "f".

pcell! ( c -- )
  Set content of the cell at current pos to character "c".

pos! ( pos -- )
  Set current pos to "pos" and update cursor position.

clrline ( ln -- )
  Set all cells in line number "ln" to spaces.

linefeed ( -- )
  Clear a new line below the current one, scrolling if needed, then set pos to
  the beginning of that line

dbgnum1! ( n -- )
  Spit "n", formatted with ".x", at the top right corner of the screen. Useful
  for debugging purposes. To debug live numbers, you can combine this with
  sys/loop.

dbgnum2! ( n -- )
  Same as dbgnum1!, but one slot to the left.

grid# ( -- )
  Check that a grid is setup and errors out if it's not.

gridtest ( -- )
  Fill the grid with characters between $20 and $60 by calling cell!
  repeatedly, alternating the "highlight" flag on each line.
