Pictures Are Pretty, How to Make a ZX81 Draw


Picture uses a simple line routine to draw a boat.

Picture ZX81 screen shot, Steven Reid 1984Sometimes one function can do a lot. For February’s program, picture uses a line drawing routine to draw a pretty picture. Okay, pretty is in the eye of the beholder. But, nonetheless, it is a picture. The fun, though, is in watching it draw.

A computer and a boat, together are art.
A like the way Picture draws its boat. Starting with a blank slate, it draws a serious of lines to build up to the final product. The process looks great, even if the resolution is low. Other games and programs of this era did something similar. Although, I didn’t learn of them until much later in life.

Coincidence? I doubt it. Using a drawing routine with points of data has some distinct advantages. In particular, it saves memory over storing a bitmap display, which can be quite large. Besides that, programs can also use it to generate many pictures.

Using a data structure, such as an array, would have made the programs more flexible. Want more complex images? Add a few more drawing functions, like circle or fill routines. Although Picture doesn’t do this, it could have.

I’ll add a final comment about the drawing function. It's slow. Related to the computing power of the ZX81, the picture takes time to build because of how slow the computer is. If you did this on a modern computer, the effect would break. For such a simple image, I expect it would take an instant. Yet, you could fix that with a delay routine if you wanted to replicate the effect.

Bunches of branches.
Digging into the code, you will find that it follows a strict pattern. Let’s look at the first few lines of the program.

 110 LET X=25
 111 LET Y=7
 112 LET X1=60
 113 LET Y1=Y
 114 GOSUB 8050
 120 GOSUB 9000

The first two lines set the starting point variables X and Y. The next two set the ending point variables X1 and Y1. Line 114 jumps to the routine that draws a line between those two points. At last, line 120 goes to the function that sets makes the end point the new starting location.

And that is it. Over and over again, some variation of these four actions take place to draw the boat. To do that, Picture needs to draw twenty lines. Evensun is a series of lines because there is no circle function. Simple and functional, it isn’t very efficient.

Looking at the program now, I could have eliminated all the GOSUB 9000 lines. Instead, I should have set the end point after drawing the line. Every place where I I didn’t use this, I set the X and Y variables anyway. A savings of fifteen lines of code in total.

I’m pretty sure the math function I use to draw the line I found in one of my books. The math makes sense to me now, having taken a graphic program course in college, I doubt I understood it at the time. It doesn’t matter though. It worked, and that was all I needed.

Yet, as good a job as it did, it was slow. Very slow. The ZX81 offers flexible math functions that allow it to be very versatile, much more so than some of its peers. But other limitations hurt it, as noted above. Writing these routines in assembly would be faster, but this program wouldn’t be the same.

Ideas and endings.
If you want a challenge, and like ZX81 BASIC, try rewriting Picture without the LET statements. I can think of a couple of ways to do it using arrays, as discussed before. Want more? How about without any GOSUB routines? This program is simple enough, it should be possible using FOR loops.

Even more challenging, it would be fun to create a game using these ideas. You could always use the ZX81’s FAST mode to speed up the drawing. I can think of a few ideas already. Man, I miss writing games on this little guy.

With that, I leave you with ideas and a boat.



2 Comments on this article:

The Picture

Written on Jun 20, 2017 by Jerome Savidan

Hi Steven,

Tanks for these interesting readings. I'm currently writing a compiler that compiles ZX81 Basic to bytecode (Java Virtual Machine), and I am quite often referring to your blog to find interesting tests to do. Interestingly, since this compiler produces graphics using unicode characters on a console output, it retains quite the slowness of the ZX81 (not THAT slow, but you can still see it draw).
I've tried my own version of "the picture" but could not exactly use your code as some statements and functions were still to be implemented (FOR.NEXT for example).
I must also say that I'm not very good in Maths, so, inspiring on some good practices of pixel art, I tried to produce "even lines" (see http://www.spriteland.com/tutorials/pixel-art-lines-tutorial.html) with simpler routines. For example, for a line going at 30° (a 3:1 line), I would increment my Y position of 0.33 at each occurence, with X incrementing of 1.
It means that I have for the moment one sub-routine per line type, which is far from being ideal.
Trying to optimize this with a more generic version is a nice exercise for the brain, since I need to balance between the memory taken for "argument" variables (one LET per variable used in a generic routine) versus the more easily predictable space taken in a strategy where each line type has its own routine (something like twelve routine of 5 code lines each should be enough).
I need also to test all these assumptions on a real ZX81 (I have a FPGA computer at hand to test that), because I have no clear idea on the amount of code you can produce before going out of memory.
Well, nice job anyway and thanks for the inspiration shared.

Jerome

re: The Picture

Written on Jun 22, 2017 by Steven

Hi Jerome,

I appreciate the kind comments. Thanks for the read and I look forward to seeing how your emulator turns out.

Thanks,

Steven


Write a comment:

Type The Letters You See.
[captcha image][captcha image][captcha image][captcha image][captcha image][captcha image]
not case sensitive