RANDOM MEMORY
Clyde Bish with a utility for producing "Landscaped" graphics
from ZX Computing Jan.1987


[** WARNINGS **                                                      ]
[* The picture Assembler/Editor has NO ERROR CHECKING, so it is very ]
[  easy to crash the program by entering a number out of range or    ]
[  placing a picture element so that it won't fit on the screen.     ]
[* When using the Save option, do not enter "y" to the "Landscaping  ]
[  complete?" question unless *all* elements of the specified grid   ]
[  have been defined, as otherwise the Load option will crash with   ]
[  "Nonsense in BASIC" because undefined elements will be spaces, so ]
[  the VAL at line 305 fails.                                   JimG.]


Anyone who has watched the ever-changing landscapes of Lords of
Midnight must have a secret wish to have a similar facility in
their own adventure programs. This graphics utility can go a
long way to granting that wish. It can hold the data for a full
screen, hi-res illustration in only 30 bytes, so with it in the
top 32K of memory you can generate any of 1000 illustrations in
less than one second.

This means that you could have four views, looking north, south,
east and west, of each location on a 25x10 grid. The screen
copies shown in Fig.1 illustrate a range of the possible
landscapes you could produce.


Landscapes

If you have looked closely at Midnight's landscapes you will
have noticed that they are made up of a number of picture
elements (trees, mountains etc) drawn to different sizes. My
program uses the same idea but operates in Basic, making it
easier for most people to handle. Look at Program 1. Lines 10-19
hold the graphics for the picture elements (let's call them
picsubs). These include mountains, forest, hills, caverns,
hedges, monoliths, lakes, towers, keeps and castles, and can be
drawn in two sizes; lines 10-19 for distant views, and lines
20-29 for close views. Each can be PRINTed At a screen position
v, h; this marking the top left corner of the element block.
Line 9 sorts out what is to be printed where. The
multidimensional array L$() holds this information in a series
of strings, each made up of five groups of three, two-digit
numbers. The first pair in a triplet is the row on screen, the
second is the column, and the third is the program line number
where the picsub subroutine is located. The j loop operates five
times producing the five picsubs which make up the completed
landscape. Before these are printed INK and PAPER are both set
to black so nothing appears until a short machine code routine
is called which pokes all the attributes with 8, thus making the
illustration appear as white on black.

Obviously, now you know the method you could go off and do your
own thing. I've chosen to illustrate a Middle Earth type
landscape but by changing the UDGs you could produce a
futuristic, heroic, or just plain ordinary one. The dimensions
of each picsub is also a matter of choice. Large ones would
produce a "busier" screen but are more difficult to position.
You're also not limited to five picsubs per landscape. You could
use as many as you like by altering the loop limit value but you
must use the same number each time, so remember - the more
elements you use per picture the less number of pictures you can
squeeze in. A careful examination of Midnight showed five to be
about the right number but the choice is yours.


UDGs

[The instructions given in the next paragraph don't work with the  ]
[listing as printed, because:                                      ]
[a) Line 3 doesn't have a CLEAR 65350 to lower RAMTOP, so the POKEs]
[   overwrite the stack and the routine crashes; also:             ]
[b) Line 3 doesn't have a STOP at the end, so after entering the   ]
[   POKEs it drops through into the main program and crashes with  ]
[   "variable not found" (a$).                                     ]
[So I made some small changes to get it to work, and to provid some]
[visual feedback so I could verify the entries .              JimG.]

Assuming you're happy with my set-up type in Program 1. This is
the one you'll need to incorporate in your own adventure
programs to run the utility. When you've typed it in RUN and
enter the data given in Table A. This is the machine code and
UDG data. Delete line 3, then SAVE the program and code with:

SAVE "landscaper" LINE 9999:
SAVE "landcode" CODE 65351,185

and VERIFY. One very important point to remember: as you have
deleted line 3 the variables used to replace numbers and save
bytes are now only held in the variables area. All programs
using this utility must therefore autostart using LINE ... when
they are SAVEd. They must also be restarted using GO TO, not RUN
as this clears the variables area. You must, of course, not
reuse the variable names used in line 3 or the values would be
corrupted.

By now a ghastly thought may have crossed your mind. You've got
to a) think up 1000 landscapes and, b) work out the data for
each and get it into the data array I$()! I can offer advice on
the first problem and an Assembler/Editor to aid the second.

Let's leave the keying in of the Assembler 'til late and worry
first about the design and layout of the illustrations.


= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
TABLE A

33  0   88  1   192 2   22  7
114 35  11  120 177 32  249 201
62  3   28  32  64  64  64  128
128 128 64  64  36  26  2   2
4   192 56  4   2   2   2   1
1   1   2   2   36  88  64  64
32  56  68  68  130 130 108 16
16  131 68  68  40  40  198 1
1   128 64  64  32  32  192 0
0   3   4   4   8   8   6   1
1   128 96  28  2   1   0   0
0   0   0   0   0   192 56  4
3   3   4   56  192 0   0   0
0   0   0   0   0   7   24  96
128 128 96  16  8   8   6   1
1   0   1   2   2   12  16  32
192 128 64  64  32  16  16  16
8   8   8   4   4   4   2   2
1   1   1   1   2   4   4   8
8   16  16  32  32  32  32  64
128 16  16  16  16  16  16  16
16  128 128 128 128 128 128 128
128 0   0   0   0   255 0   0
0
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =


Map

You first need a good idea of what our adventure map looks like
overall. By way of example, Fig.2 gives a sample map for us to
use. It's only 3x3 locations - anyone who is clever enough to
start with the full 25x10 doesn't need my help! You will notice
that each location is subdivided into four. This makes it easier
to decide what is where, and what size for each landscape. The
letters appearing in each quarter square symbolise the picsubs
which are to appear. Table B gives a key for these.


= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
TABLE B

Key to map and picsub codes

[The Far/Near headings were the opposite way around in the printed]
[listing - the listing was wrong, so I've corrected it.      JimG.]

           Symbol    Far       Near
Mountain     M        10        20
Forest       F        11        21
Hills        H        12        22
Cavern       C        13        23
Monolith     Li       14        24
Lake         L        15        25
Henge        He       16        26
Tower        T        17        27
Keep         K        18        28
Castle       Ca       19        29
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =


In each location they are deemed to be standing in the centre
(where the dotted lines cross) and looking N, S, E, or W. So if
you were in square 1,1 (where the dot is) and looking east, you
would see a castle near right, and forest left, with another
area of forest in the right distance and hills leading up to
mountains in the left distance. This is the landscape shown in
Fig.1(a). It would be worth now trying to work out what the
views for the rest of that square, or other squares, would be to
get the hang of the system. What happens at the edge of the map
(eg. square 1,1 looking N or W) you must decide. You could
surround your lands with impassable mountains, or simply have a
no-go featureless horizon.

OK, so you think you know what each landscape is to look like,
but it would help to be able to see each one on screen and make
any necessary artistic adjustments. This is where the
Assembler/Editor comes in. LOAD in Program 1 if it's not already
in the machine and add to it Program 2. SAVE it to LINE 9999
plus the machine code/UDG data as before.

When LOADed normally it will autostart at LINE 9999, then jump
to the menu, but for the moment start it with GO TO (not RUN!)
900. This is also how you would restart the Assembler - if you
get an error message after a failed VERIFY perhaps.

The Menu lists the available options. Let's have a look at the
facilities available. If you get into any option by mistake,
pressing just ENTER will escape.

1. Assemble
This option displays each view as you build it up. The "width?"
prompt is the number of grid squares across your map. (Enter "c"
here if you are continuing with an unfinished landscape). Height
is the vertical number of grid squares. For each picsub of each
view enter row, column and picsub number (if you can't remember
the latter, enter "h" for a help page). Remember the views go
clockwise in the sequence North round to West, and across the
map columns, row by row. There are five picsubs to each view (if
you only need 4, repeat the last one twice!).

To exit this option before the landscape is complete press just
ENTER on the "row?" prompt.

2. Save
This option will allow you to save the data array complete, or
incomplete, for reloading later. In the former case press "y",
otherwise "n", and follow the normal SAVE prompts.

3. Load
First enter the width and height of your landscape map, then
follow the LOADing prompts ("" loads in the first array on the
tape). After the LOAD you will jump straight into the assembler
option at the next view to compose.

4. View/Edit
This allows you to move around your landscape, and make minor
alterations. The first view shown will be at grid 1,1 looking
north. Pressing the cursors will give you the view in that
direction, whilst pressing "m" will move you that way (if there
is no view there you will be told). Under each view is the
string that produced it.

To make alterations to a view press "c". You'll get an
information page plus the string in highlighted blocks. Remember
the sequence in each block is row, column, then the picsub that
you can identify from the details above. Use the left/right
cursors to move the arrow to the first number you wish to alter,
press SPACE, then move it to the last digit to alter and press
SPACE again. Now enter the correct number sequence for
replacement.


= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
TABLE C

[The term used for an individual picture element is "picsub" in the ]
[text, but "picel" in this table.                              JimG.]

  Grid    View    Picel   Row    Column Picel No.
   1,1      1       1      7        0      12
                    2      8        0      22
                    3     12        2      12
                    4      9       20      21
                    5     12       17      21
            2       1      4        0      10
                    2      7        0      22
                    3      8       20      11
                    4      9       11      29
                    5     14        0      21
            3       1      7       25      12
                    2      8       19      22
                    3      9       12      15
                    4     12       24      12
                    5     10        1      29
            4       1      7       20      12
                    2      8       26      12
                    3      9       19      22
                    4     15       15      12
                    5     15       15      12
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =


Designer landscape

Now to work on an example. Table C gives the data for the four
views from grid 1,1 on my map. Enter these using option 1, then,
using my map (or your own version), you can work out the design
for the remaining grid positions/views (Surely you didn't expect
me to do all the work!). Remember you can use 'n' in answer to
the "?" at the end of a picsub positioning move to reposition it
(or press 'a' to start the whole view over again), then use
option 4 to wander through the whole scenario when it is
complete, making corrections. Remember also when you make the
final SAVE of the whole landscape to answer 'y' to the
"landscaping complete?" prompt or you'll corrupt the last two
entries!

What to do next? Ah well, the ball is in your court now to
decide in what type of adventure you want to use your landscape.
I can't do that for you but I can show you how to incorporate it
into your programs and call up the landscapes.

You will need to CLEAR 65530, LOAD in the original program plus
code that you SAVEd, then MERGE in your adventure program.
Obviously your program must start after line 29 or you'll
overwrite the utility (also don't be tempted to alter any of the
routine's line numbers or the GO SUB in line 9 won't operate
correctly). Before you make any call to "the Landscaper"
subroutine (using GO SUB 9) you must set r to the grid row of
your map, k to the column and o to the orientation of the view
you want (1=N round clockwise to 4=W). So to display the view
looking west from the top centre grid square on our example map
you would use the line

LET r=1: LET k=2 LET o=4: GO SUB 9

When you start the adventure you would need to decide where your
adventurer was standing and which way he was facing, and set r,
k and o to these values before GO SUB 9.

To allow him to move around your scenario you would need to
include the following, probably as subroutines:-

To move in the direction faced:

1010 LET r=r+(o=3)-(o=1): LET k=k+(o=2)-(o=4) : GO SUB 9: REM update row/column variables

To turn (cursor pressed in r$):

2010 LET o=(1 AND r$="7")+(2 AND r$="8")+(3 AND r$="6")+(4 AND r$="5"): GO SUB 9: REM relate value in o to keypress

An adventure isn't just wandering around a landscape so the
values in r and k would also be used to check the predetermined
positions of monsters / finds in arrays to see if you had bumped
into a Balrog, or tripped over a Talisman or whatever.

Obviously you would SAVE the final adventure to LINE 9999 so as
to LOAD in the code automatically (which would be SAVEd after it
on the tape). You must also CLEAR 65350 before LOADing in the
program to play. You could have the machine do this for you by
LOADIng first a short driver program

10 CLEAR 65350: LOAD ""

which autostarts, lowers RAMTOP, then loads in the main
adventure, which itself autostarts and LOADs in the code above
the already lowered RAMTOP.

Bye for now.


-- end of file --
