MULTI-SCROLL
by Alan Davis
from ZX Computing June 1987

Alan Davis presents an all-purpose scrolling utility.


[NOTE: The file "SourceCode" in MULTSCRL.TAP is an assembler source]
[file which I created with the OCP Editor/Assembler.           JimG]


Broadly speaking, I suppose there are really only two ways of
presenting text on screen in an adventure game. Probably the simplest
is to use straightforward PRINT statements in which strings of text
are printed from some specified screen line downwards. This is a
method more commonly encountered in older games, perhaps. There's
nothing actually wrong with it as a system, except for the (relatively
minor) disadvantage that the relevant part of the screen needs to be
cleared completely before each fresh printing - obliterating whatever
went before, of course.

The alternative method - and the one almost universally used these
days in commercial games - is the continuous scrolling one. With this
system, text is printed one line at a time to a particular screen
position, and the screen is scrolled upwards by one line between each
printing. In a text-only adventure this isn't difficult to achieve
because the well-known USR call to the Spectrum ROM (3582) can be used
to scroll the entire screen in between the printing of each line of
text. However, suppose you're writing a graphic adventure in which the
picture forms part of the permanent display - with the text scrolling
continuously in a window underneath it. Unfortunately, the ROM can't
help you much here.

On the other hand, perhaps you're looking for a different style of
presentation altogether? One (rather controversial) game in the
role-playing mould is "Out of the Shadows", in which a small map forms
a permanent part of the display, with text continually scrolling in a
narrow column up the right hand side of the screen. You really can't
attempt this sort of thing in BASIC, can you?

There's a lot to be said for trying out unusual methods of on-screen
presentation, in fact. There's a tendency for some adventure authors
to settle on one particular style and then stick with it, but if this
is overdone it isn't long before a certain monotony sets in. The
player begins to feel that the the adventure is just another
"production-line" effort - and you don't have to look far to find
examples. The old "Mysterious Adventures" series had a strong tendency
in this direction, and some of the more recent releases by US Gold
show all the signs of heading the same way. So it isn't only the
Quilled and GAC'd games which fall into stereotyping trap.

Of course we all know that mere appearance isn't the be-all and
end-all of adventure writing, but there's no doubt that it can help to
offset that "seen it all before" impression. Wouldn't it be useful to
have an off-the-shelf utility which could cater for all likely styles
of presentation? For a long time I've tended to take a short term
view, writing printing and scrolling routines specifically for the job
currently in hand - consoling myself that "one of these days" I'd get
around to writing a suitable "all-purpose" utility that could be used
for all conceivable situations. Well, "one of these days" has arrived
at last; "Multi-Scroll" is about to be launched upon an astonished
world.

What we want, essentially, is to be able to define a "window" of any
size, anywhere on the screen, so that text can be printed to the
bottom of the window and scrolled continuously upwards until it
disappears at the top of the window. If we could define INK and PAPER
colours for the window, independently of the screen colours elsewhere
on the screen, then that would be useful, and it might also be handy
to have a simple method for clearing the window completely. Finally,
we want to be able to do the actual text printing from BASIC without
worrying about whether the individual text lines fit the window, and
so we need a suitable word-wrapping routine as well.


Available Services

All these facilities are available with Multi-Scroll, and at your
service. Listing 1 [see MULTSCRL.ASM] is the assembly program - and
as always, I strongly recommend that you use this in conjunction with
an assembler - but Listing 2 [see below] provides a decimal dump of the
machine code (for those who've not yet seen the light). As you'll see,
the code is stored from address 64800 onwards, and is 474 bytes long.
You'll need a BASIC loader program if you're using the decimal dump,
but if you rifle through some back issues of ZXC you'll find something
suitable that you can modify (don't forget to CLEAR 64799 before you start).

I've annotated the assembler listing in plenty of detail, so I'll
confine my remarks here to a general outline of Multi-Scroll, and how
to use it. The machine code consists of essentially four separate
routines, each of which can be used from within a BASIC program as
required:

1) SCROLL (USR 64825). This scrolls the chosen window upwards by one
line. There are several ways of tackling this, and the method I've
adopted here uses a table of screen line addresses to minimise the
complexities brought about by the Spectrum's eccentric display file.
(You can find a more detailed discussion of this approach in Pete
Cooke's article in the March issue.)

2) ATTR (USR 64933). This washes the window with the chosen INK and
PAPER colours. Note that it doesn't clear the window - it only changes
the colours for whatever is already there, and for any subsequent
printing.

3) CLEAR (USR 65010). This performs as many scrolls as there are lines
of characters in the window; in other words, everything previously
printed in the window will be scrolled upwards and off the top,
leaving the window clear.

4) WRAP (USR 65084). Regular readers will have encountered similar
routines to this in one or two of my previous articles but we require
greater flexibility here, and this one represents (I hope!) my last
word on the topic. Its purpose is to print text held in the BASIC
variable z$ in the window, scrolling the lines and word-wrapping as
necessary - so you don't need to worry about padding your text with
spaces to make it fit the window; this routine will sort all that out
for you. The only limitation is that LEN z$ should not exceed 255
(which means that for really long chunks of text, you'll need to break
it into separate sections - and you'd probably do this anyway to avoid
textual claustrophobia on-screen.)

This, then, is what Multi-Scroll does - but how do we control it from
BASIC? Very simple. There are six addresses whose contents determine
the behaviour of the routines, and these should be POKED with suitable
values before the routines are used. Four control the size and
position of the window, and two control the colours as follows:

1) The limits of the window are defined using the four addresses from
65025 to 65028 inclusive (labels TOP, BOT, LEFT, and RIGHT
respectively - see Listing 1). Think in terms of the Spectrum's normal
system of identifying character squares, and set the limits
accordingly. For example, if you POKE 65025,19: POKE 65026,21 then
your window will be three lines high (with line 21 the bottom line to
which printing is done). POKE 65027,0: POKE 65028,31 will set the left
and right limits so that your window will occupy the whole width of
the screen (from character square 0 to character square 31).
Incidentally, no check is made for invalid screen positions within the
routines, so don't go poking any old numbers in here!

2) The colours (from 0 to 7 inclusive, as usual) are defined using
addresses 65029 and 65030 (INK and PAPER respectively). Again, no
check is made for invalid colours.


Other uses

Although the most obvious use for Multi-Scroll is in a graphic
adventure game, with text scrolling continuously below an illustration
of some kind, there's nothing to stop you from using it in other
contexts, perhaps with several windows on screen at once, by setting
up a small number of BASIC subroutines to define them. To show how
this can be done, and to illustrate all the things we've been talking
about, I've given in Listing 3 a short demonstration program which
will put Multi-Scroll through its paces for you. Notice that the
various USR call and POKE addresses are allocated to suitably named
variables in lines 30 to 50; this makes for improved readability, and
saves you looking up the numbers each time. Save the demonstration
program to auto-run from line 1 - if you're working from tape rather
than microdrive, you'll need to change the LOAD instruction in line
10, and save the machine code block immediately after the BASIC. If
you follow what's happening on screen, comparing it carefully with the
listing, you should rapidly get the hang of things. Have fun ...


= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
Listing 2
[NOTE: The last number on each line is a checksum. JimG]

64800   58   1 254  71  58   2
64805    2 254 144  60  50  10
64810   10 254  58   3 254  71
64815   71  58   4 254 144  60
64820   60  50   9 254 201 205
64825  205  32 253  33  12 254
64830  254 237  75   1 254   6
64835    6   0   9   9  34   7
64840    7 254  42   7 254  94
64845   94  35  86 229  42   3
64850    3 254  38   0  25 235
64855  235 225  58  10 254  61
64860   61 254   0 202 141 253
64865  253  50  10 254  35  34
64870   34   7 254  78  35  70
64875   70  42   3 254  38   0
64880    0   9   6   8 197 237
64885  237  75   9 254   6   0
64890    0 229 213 237 176 225
64895  225 209   1   0   1   9
64900    9 235   9 193  16 234
64905  234 195  74 253   6   8
64910    8 197 213  58   9 254
64915  254  71 175  18  19  16
64920   16 252 209   1   0   1
64925    1 235   9 235 193  16
64930   16 235 201 205  32 253
64935  253  58   6 254   7   7
64940    7   7  71  58   5 254
64945  254 128  50  11 254  33
64950   33   0  88  17  32   0
64955    0  58   1 254  71 175
64960  175 184 202 202 253   5
64965    5  25 195 192 253 237
64970  237  91   3 254  22   0
64975    0  25  34   7 254  58
64980   58  10 254  71 197  58
64985   58   9 254  71  58  11
64990   11 254 119  35  16 252
64995  252  42   7 254  17  32
65000   32   0  25  34   7 254
65005  254 193  16 231 201 205
65010  205  32 253  58  10 254
65015  254  71 197 205  57 253
65020  253 193  16 249 201   0
65025    0  21   0  31   0   7
65030    7   0   0   0   0   0
65035    0   0  64  32  64  64
65040   64  64  96  64 128  64
65045   64 160  64 192  64 224
65050  224  64   0  72  32  72
65055   72  64  72  96  72 128
65060  128  72 160  72 192  72
65065   72 224  72   0  80  32
65070   32  80  64  80  96  80
65075   80 128  80 160  80 192
65080  192  80 224  80 205  32
65085   32 253  42  75  92 126
65090  126 254  90 202  79 254
65095  254 205 184  25 235 195
65100  195  66 254  35 126  50
65105   50 246 254  35  35  34
65110   34 248 254 205 150 254
65115  254 254   1 202 200 254
65120  254 205 174 254 205 200
65125  200 254  42 248 254 237
65130  237  91 247 254  22   0
65135    0  25  34 248 254  58
65140   58 247 254  71  58 246
65145  246 254 144  50 246 254
65150  254  42 248 254 126 254
65155  254  32 194  89 254  35
65160   35  34 248 254  58 246
65165  246 254  61  50 246 254
65170  254 195 127 254  58   9
65175    9 254 198   1  71  58
65180   58 246 254 184 218 165
65185  165 254 175 201  58 246
65190  246 254  50 247 254  62
65195   62   1 201  42 248 254
65200  254  58   9 254  95  22
65205   22   0  25 126 254  32
65210   32 194 195 254 123  50
65215   50 247 254 201  27  43
65220   43 195 184 254 205  57
65225   57 253  58 142  92 245
65230  245  62  63  50 142  92
65235   92  62   2 205   1  22
65240   22  62  22 215  58   2
65245    2 254 215  58   3 254
65250  254 215 237  91 248 254
65255  254 237  75 247 254   6
65260    6   0 205  60  32 241
65265  241  50 142  92 201   0
65270    0   0   0   0   0   0

CHECKSUM 67338


--
Another Fine Product transcribed by:
Jim Grimwood, Weardale, England (http://www.users.globalnet.co.uk/~jimg/)
--
