ZXDRAW (16K ZX81)
by Spencer Collyer
from Your Computer (February 1984), pages 107-108

Become a computer artist with Spencer Collyer's simple graphics program.

ZXDRAW is a set of three graphics utilities for the ZX-81, allowing the
user to draw straight lines, circles, and triangles. All three can Plot or
Unplot the shapes onto the screen, and both circles and triangles may be
filled or unfilled.

The routine requires, five parameters to be Poked into memory before it is
called. These are, to draw a line from (a,b) to (c,d):

    POKE 16514,a
    POKE 16515,b
    POKE 16516,0
    POKE 16517,d
    POKE 16417,PLOT(=1)/Unplot(=0) flag.

Thus,

    POKE 16417,1

will plot lines to the screen, while

    POKE 16417,0

will unplot them.

Note that only 16514 and 16515 have their contents altered by this routine.
Thus, if you wish to use one point as the end point for several lines. Poke
16417 with the plot/unplot flag, and then Poke 16516,16517 with the x and y
co-ordinates of the point. Then you simply have to alter 16514,16515 each
time. Note also that the routine must be called with

    LET variable = USR 16527

as

    RAND USR 16527

for some unexplained reason produces an error code 4. Type

    RUN 10

to illustrate how the changing of just 16514,16515, instead of all five
locations, still produces the same result. This should half-fill the screen
with black in a triangle.

Now swap lines 20,30 with 50,60, and a very strange effect is produced,
which illustrates that on exit from the routine, 16514,16515 do not
necessarily equal 16516,16517, otherwise a straight line from (0,0) to
(63,0) would be drawn.

Now type RUN 90

to illustrate the patterns produced by alternatively plotting and
unplotting a moving line. Alternatively, add a step of 2 to line 90, change
line 100 to

    POKE 16417,1

and Run to see the interference pattern produced simply by plotting lines.

Further interesting results can be obtained by

    RUN 170

Other ideas will doubtless come to mind, and you only have to type them in
to see what they will do, remembering that within certain constraints,
off-screen drawing is possible. These limits are actually from c.-100 to
c.lOO for both X and y.

Now on to the circle routine. This routine draws the best possible circle,
or ellipse, given the limitations of the ZX-81 display. The routine
requires six parameters to be Poked into memory. These are, with their
respective addresses:

    16444 Radius of circle, or width of ellipse
    16445 Radius of circle, or height of ellipse
    16446 x co-ordinate of centre
    16447 y co-ordinate of centre
    16448 filled(=1)/Unfilled(=0) flag
    16417 Plot(=1)/Unplot(=0) flag

Note that if a circle is wanted, both 16444 and 16445 should hold the value
of the radius, which can range from 1 to c.100. However, for ellipses they
may both hold different values in the given range. A value of in either
will give very weird results indeed.

It should also be noted that none of these values are altered during
execution. The routine is called with:

    LET variable = USR 17065

Circles, especially unfilled ones, seem to work best when superimposed. For
instance, try

    RUN 290

which produces a shell-like pattern. Adding a step of 2 to line 320 can
make it seem as though you are looking down a tunnel.

    Type RUN 380

to see the advantages and disadvantages of the filled circle routine. It
can be seen that, although the filled circle is drawn faster than the
series of concentrically placed unfilled circles, and also has the central
point filled in, it is less effective at producing a complete fill. Note
that changing the For-Next loop in line 420, to

    FOR K = 0 TO 12

will simply result in the weird results already noted for a radius value of
0, and the central point will still not be filled in, in all likely hood.

Finally, on to the triangle routine. This will draw filled or unfilled
triangles as well as possible, using the vertices Poked into memory.
Assuming a triangle with vertices (a,b), (p,q), (x,y) the necessary Pokes
are:

    16444,a
    16445,b
    16446,p
    16447,q
    16448,x
    16449,y
    16463,Filled(=1)/Unfilled(=0} flag
    16417,Plot(=1)/Unplot(=0) flag

The routine is then called with

    LET variable = USR 17344

A point to note about the filled triangle routine is that it, in fact,
draws the triangle three times, once from each vertex. This is to ensure a
complete fill of the triangle, but it sometimes means that, although a
triangle appeals to be complete, in fact the routine has not finished
drawing. To see what would result if the routine drew lines from only one
vertex, type

    RUN 510

And now for a warning, or two, actually.

First, the plot routine used by these routines, while being much faster
than the Sinclair one, will bomb-out if you attempt to plot over writing,
or one of the grey character. This is not recommended anyway, as you lose
some of the information so carefully placed on the screen. Secondly, if you
use Print after using the routines, do not use it on its own, but use Print
At. This is because the plot routine resets the system variable DF_CC,
while leaving S_POSN alone. Thus the computer might think that it is at
(0,0), while in fact it could well be at (16,16). The end result of then
using a bare Print statement is to overwrite one of the NEWLINE characters.
Result: the computer crashes. However, using, say,

    PRINT AT 0,0;

even with nothing following the semi-colon, allows the computer to set its
house in order.
