Hang Glider
By Ron Ridge
Big K, September 1984


Hang gliding in a city centre can be very hazardous to your health! On
the way down you can cream into flocks of birds or plough into buildings
- nasty.

Then, if you miss the green landing spot you can break a leg. All fun
stuff.

Use the 'Z' key to control your descent and hit the green spot as many
times as you can out of ten. Good luck, and don't break a leg!



Richard Taylor's Page
Don't Just Sit There - Move!
from Big K #5, August 1984

SINCLAIR'S ADVERTISING blurb proudly proclaims the Spectrum as a High
Resolution Micro offering a definition of 256 x 192. Even the small print
doesn't tell you that you can only PRINT in a rigidly defined grid of 32 x 22
character squares.

Okay, so you can use PLOT to produce static pictures with the full resolution
 but that's what they are, STATIC and uninteresting, at least from a games
viewpoint. As for the alternatives. Well, what alternatives? You could
conceivably construct the characters by plotting certain adjacent pixels on
the screen but that is appallingly slow. You could of course forget that
you've got a high resolution machine altogether and opt for low resolution
character movement in any games you write and watch characters make enormous
great jumps as they are transported around the screen. (A lot of very good,
mainly BASIC, games have been written in this way). Mind you, if you forget
about the High-Res you might as well forget all about colour, sound and all
the rest of the associated paraphernalia and replace your Spectrum with a
slightly less graphically advanced system  perhaps a ZX8O and a prehistoric
telly!

Fortunately the problem is not insurmountable and can be solved with a short
program although it does require us to dabble in that dreaded language,
machine code. A short machine code program to perform such a task is shown in
Listing 1. The machine code is tucked away above RAMTOP well away from the
danger of overwriting by BASIC. Since the address of RAMTOP differs on the
16K machine from the 48K it is necessary to have two versions of the program;
one for each memory size. If you own a 16K computer then type in listing 2
rather than the first listing. All the program does is to POKE the machine
code into memory. When you've finished keyboard bashing you're ready to RUN
it. The program incorporates a checksum to verify the accuracy of the data,
so if you've made a mistake it will tell you so and give you an idea of where
to look for it. Once the program has successfully RUN you can save your
machine code on tape using the commands below:

For 48K owners  SAVE "Hires Prnt" CODE 65116,252
For 16K owners  SAVE "Hires Prnt" CODE 32348,252

You can reload the program at any time by using:

For 48K owners  CLEAR 65115: LOAD "" CODE
For 16K owners  CLEAR 32347: LOAD "" CODE

It's a good idea to save and verify a couple of times in case any devastating
calamity should befall your first recording. All that the machine code does
is the equivalent of poking a character onto the screen but at a much more
respectable rate than BASIC can ever hope to do. The machine code also has to
do a bit of fiddling about with binary numbers when a graphic straddles two
or more character squares.

To print a character using this routine requires 3 POKEs followed by a
machine code USR call, not surprisingly. The locations which are POKEd
differ between the two versions of the program so remember to type in the
right ones or you could find your machine crashing on you. The first location
defines the x coordinate of the position where you want the character you
wish to print. To save any hassle with POKEs and USR statements it's a good
idea to have a small general purpose subroutine which you can call whenever
you want to print a Hi-Res character. Such a subroutine is listed below:

For 16K Machines:
9900 POKE 32350,CODE a$
9910 POKE 32348,x: POKE 32349,y
9920 RANDOMIZE USR 32351
9930 RETURN

For 48K Machines:
9900 POKE 65118,CODE a$
9910 POKE 65116,x: POKE 65117,y
9920 RANDOMIZE USR 65119
9930 RETURN

When the subroutine is called, using "GO SUB 9900", the variables a$, x and y
must hold certain parameters. A$ holds the character that is to be printed.
The program allows you to print any of the BASIC character set (with codes
32-127) plus user definable characters (with codes 144-164) but you're not
allowed to print tokens or the graphics characters available on the top row
of the keyboard when in graphics mode. X holds the x co-ordinate (0-255)
position of the top left hand corner of the character to be printed while y,
quite predictably, holds the y co-ordinate (0-175) of that point. Note that,
unlike PLOT and CIRCLE, etc., the y co-ordinate is numbered from the top rather
than from the bottom of the screen so that (0,0) is at the top left rather
than at the bottom left-hand corner of the screen. So for instance "LET
a$="A": LET x=128: LET y=88: GOSUB 9900" prints the letter A slap bang in the
middle of the screen. Try it and see. The listing below:

10 LET y=88
20 FOR a=1 TO 255
30 LET x=a-1: LET a$=" ": REM Space
40 GOSUB 9900
50 LET x=a: LET a$= "O"
60 GOSUB 9900
70 NEXT a
80 STOP
9900 (The Hi-Res Printing routine)

will smoothly move the letter O across the screen from left to right. Notice
that before a new 'O' can be printed the old one has to be erased by
overprinting it with a space. That awful flicker is a result of the fact that
the 'O is completely absent from the screen for a short period just after
the old version has been overprinted. In a later article I will explain how
to overcome this problem (to a large extent). If you add "STEP 2" to the end
of line 20 then the movement will be much faster although not quite as
smooth. You can arrange the x and y co-ordinates so that the movement is a
little more interesting. You can use some of the computer's trig and other
mathematical functions to produce some fascinating movement patterns. An
example is given in the following listing:

10 LET x=128: LETy=88
20 FOR z=0 TO 359
30 LET oldx=x: LET oldy=y
40 LET r=87*SIN (10*z/180*PI)
50 LET xx=128+r*COS (z/180*PI)
60 LET yy=88+r*SIN (z/180*PI)
70 LET x=oldx: LET y=oldy: LET a$=" ": REM Space
80 GOSUB 9900
90 LET x=xx: LET y=yy: LET a$="O"
100 GOSUB 9900
110 NEXTz
120 STOP
9900 (Hi-res Printing routine)

Listing 3 illustrates another aspect of movement  acceleration and
deceleration. You can move a dot around the screen using the cursor keys.
Upon pressing key 'm' the 'O', initially positioned at the screen's centre,
moves towards the dot. Its velocity is not constant; as the 'O' nears the dot
its speed gradually decreases. The hard work of the program is done by lines
1000 and 1010 which basically work out what one tenth of the distance is
between the dot and the 'O' and moves the 'O' that distance towards the dot.
As the 'O' nears the dot the jumps gradually get smaller so that the '0' moves
more slowly.



More Hi-Res Printing
... In which RICHARD TAYLOR continues his arcane and fearfully knowledegable
series on Hi-res programming tools for the Sinclair Spectrum
from Big K #6, September 1984

LAST MONTH I presented a high resolution printing program. This time I'm
going to continue (why not?) by listing an addition to the old routine which
improves it so that it can be used directly with PRINT statements  in stark
contrast to having to use unwieldy POKEs and machine code USR calls.

The augmentation to the original program will also give it some new
features, such as actually being able to define the colour the output is
printed in, a routine to help make the flicker eminent in the first version a
thing of the past and to allow you to Hi-Res print whole strings of
characters in one fell swoop.

As with the last program, this also is written in machine code. If, like the
majority of the computerised population, you've got an instinctive fear of
MC, then don't worry; the program comes nicely packaged in a BASIC format 
Listing 1 for 48K hackers or the second listing for relatively impoverished
hackers of the 16K variety. The loader prog also incorporates a checksum
routine, which should prevent any crashing machine code or hex hassles.

Before I continue, I feel I should warn you that you'll need to muster a copy
of last month's prog from somewhere. If you didn't type it in, or the version
you did possess was mis-laid/erased/savaged by a mad dog then you'll need to
either nick or cadge a copy. Failing that, you'll need last month's mag and
some finger power. Once you've sorted that out, you're ready to type in this
month's listing. After you have RUN the program (and waited a couple of
minutes), you'll get one of two messages: either one instructing you to load
the Hi-res printing program from last month and then save or, for the less
fortunate, a message informing you that there is an error in a certain DATA
statement. If you do get the latter message then I'm afraid that you'll have
to find the error in the offending line and correct it before trying your
luck at re-running. Once you're successful you can load the code from last
month's program with LOAD ""CODE and then make a couple of copies of the new
program with:

SAVE "HRES PRNT2"CODE 64717,651 (for 48K hackers)
SAVE "HRES PRNT2"CODE 31949,651 (for 16K hackers)

Remember to VERIFY  it's not hard to forget to connect the MIC lead up when
you save and end up with a blank tape.

Now for a description of your new program. First of all, you'll need to start
any program you write utilising the routine with a RANDOMIZE USR 64717 for
48K owners or RANDOMIZE USR 31949 for 16K owners. You'll no doubt be pleased
to know that this is the only machine code call you'll need as the rest can
be controlled with the more friendly PRINT statement. After using this call
you won't be able to use a ZX printer, if you're lucky (sic) enough to have
one, since any output that is usually directed to the printer, using LPRINT
or LLIST, is diverted to the Hi-res print routine. After that, you can output
to the Hi-res routine with a PRINT #3; command followed by ... what you want.

The syntax of the new style PRINT statement is much the same as a normal one
except, of course, everything is done in Hi-res. As usual, you can use the
normal colour directives to change colours but, although the program will
accept it, the INVERSE directive has no effect. You can use OVER, but its
function is somewhat different to normal. AT and TAB will work but they need
to be supplied with Hi-res co-ordinates to work on; ie. the range for row
numbers is 0 to 175 and 0 to 255 for column numbers. What you print is
defined in the usual way, either as strings or as numbers. There's no
restrictions on doing maths or doing a bit of string slicing in the
statements; you can even put something like 1/COS (SQR ((x 2*3))) if you're
mathematically minded.

A simple example. The program below will move an 'O' from the left to the
right hand side of the screen. With this, and any other programs, 16K hackers
will have to change any occurrence of USR 64717 to USR 31949.

10 RANDOMIZE USR 64717
20 FOR a=0 TO 248
30 PRINT #3; AT 100,a;"O"
40 NEXT a

Listing 3 is in a High-res version of the bouncing ball program.

When you print strings of characters, each successive character is printed 8
pixels to the right of the previous one, taking a new line if necessary, as
in normal PRINT statements.

Unlike normal PRINT statements, however, the Hi-res ones won't ask you if you
want to scroll when the printing reaches the bottom of the screen, they just
stop with a "5 Out of Screen" error report. The use of printing strings of
characters is illustrated below, with a short example which moves the word
"SPECTRUM" across the screen:

10 RANDOMIZE USR 64717
20 FOR a=0 TO 192
30 PRINT #3; INK RND*7; AT 99,a;"SPECTRUM"
40 NEXT a

The operation of OVER in Hi-res is somewhat different to its normal
operation. OVER is used to implement the anti-flicker device the program
possesses. What the anti-flicker routine does is simply allow you to
overprint a redundant character with a space and move it to a new position in
one command. However, it is assured that you'll never see the character in
the intermediary stage of being overprinted but not re-printed (the cause of
flicker). What you do is, in the PRINT #3 statement, put AT (where the space
is to be printed  ie. the character's old position); OVER 1; AT (the new
position); "(the character you want to print)". An example would be PRINT #3;
AT oldy, oldx; OVER 1; AT y,x;"O". This technique is used in listing 3 at
line 40.



