THE WAR OF THE SHIRES (part 1 of 3)
by Alan Davis
from ZX Computing Nov.1986

Alan Davis begins a three part series to
create an original fantasy wargame.


Roland stood by the keep, watching the folks of Greenways
gathering their crops from the nearby fields. It had been a fine
summer - one of the best he could recall - and the Shirefolk
were in good heart. There would be ample provision for Winter
this year, and he was content.

Suddenly the excited shouts and gestures of the villagers drew
his attention towards the forest of Greenways in the west,
whence a solitary rider was approaching at great speed.

"What news, friend?" he called, as the newcomer dismounted and
tethered his beast.

"Ill, my Lord," gasped the rider, gulping thankfully of a
proffered draught of water. "I came in all haste from the
Mountains of Darkness, where great armies are gathering in
fearsome numbers!"

Roland shook his head. "Nay, friend - we surely have little to
fear from the Shire of Darkness. The mountains are impassable.
No army could penetrate them and survive."

"My Lord, the forces of Darkness are mounted upon guruks - great
beasts from the far west, capable of carrying many men over the
most rugged terrain, at speed. Even water is no obstacle to
them, for they are mighty swimmers. Believe me, my Lord, I have
seen these things with my own eyes but three days ago, and even
now Deepmeads and Northwood may have fallen!"

Roland needed no further persuasion. "Then all the Shires are in
the gravest peril! Freemen of Greenways, rally to my banner and
prepare for war! We ride at once to warn Ranolf of Deepmeads
..." And as Roland spoke, from the west came the faint but
ominous sound of thunder ...


Don't worry - you haven't bought a role-playing fantasy magazine
by mistake! This really is ZXC Monthly, and what you've just
read is the introduction to a computer game. I'd better explain
...

It all began with a bit of doodling, really. With pen and paper
to hand one morning, I started sketching out a map of an
imaginary world, with nothing very particular in mind - not
knowing where it might lead. Gradually the map took shape,
dividing itself interestingly into twelve Shires. Each Shire
acquired a keep and a sprinkling of villages, and of course
these in turn required inhabitants. So I started inventing some
characters - thanes of the Shires: Roland of Greenways, Ranolf
of Deepmeads, and so on.

Now, someone (C.S. Lewis, I think) once commented that imaginary
worlds are all very well, but when you've created this
interesting place and populated it with characters, something
has to happen in it! It was at about this stage that I began to
realise that there were possibilities here for a computer game
of the "fantasy epic wargame" variety, which might provide some
interesting programming examples (as well as an entertaining
game) for my friends the readers of ZXC - not to mention myself!
So I discarded the pen and paper, plugged in the old Spectrum -
and the eventual result was "THE WAR OF THE SHIRES".


Building a world

Right at the start, a number of decisions had to be made about
the format of the game. At first I did briefly consider using a
simplified form of landscaped graphics, but rejected the idea on
the grounds that the sheer volume of graphics data would make
the program listings ridiculously long. However, there seemed to
be no reason why the original "world map" itself couldn't be
represented graphically - so I settled for that. The next
question concerned the actual programming, which, ideally,
should be sufficiently flexible for others to modify and add
developments of their own. I could see from the start that some
machine code programming would be necessary to prevent ponderous
response times, but I was surprised to discover that in practise
only two machine code routines were strictly necessary, and that
BASIC was perfectly adequate for everything else Now this is
good news, because of course it's very much easier to experiment
with changes in a BASIC program than it is with machine code.
The final requirement was merely that the game should be fun to
play in its own right, regardless of any further developments
you might like to make yourself in due course.

So if, as I am, you're attracted by the idea of creating
imaginary worlds; or if you have a taste for the "Lords of
Midnight" type of epic fantasy game which can be played over and
again in different ways: or if you just fancy tackling the
interesting programming challenges of a strategy game - why not
join me for the next couple of months, and try writing your own
...?


Maps and things

This month, as you might have guessed from the illustrations, is
mostly about graphics and maps - specifically the business of
translating the original map of the Twelve Shires into something
that can be readily programmed on the Spectrum. The Spectrum
upper screen, as you know, consists of 22 rows of 32 character
squares. Suppose we let each of these character squares
represent one 'location' on the map of the world, then. This
will give us 704 locations to play with - which should give
ample scope for our "mini-epic", and will enable us to display
the entire world map on screen at once.

But how should we store such a map in memory? One method would
be to draw it out on-screen, and then store the entire screen as
a code block above RAMTOP, calling it up as required during the
game using a short LDIR-based machine code routine. Well, if the
map were to remain unchanged during play, this would be fine -
but in "The War of the Shires" I wanted certain features of the
map to be altered by events. (Ships, for instance, won't always
be in the same place, and keeps may be reduced to rubble in
battle.) I finally decided to store the ma p in a BASIC
character array, x$(22,32), so that each character square on the
screen could be directly related to a single element of the
array for ease of manipulation. Mountains, keeps, and so on,
could then be represented by UDGs on screen, with the codes for
the UDGs being held in the array.

So how do we actually get the map onto the screen, with each UDG
appearing in its correct colour? Well, it could be done in BASIC
- but it's a painfully slow process which would drive any player
of the game to distraction (in play the game involves a good
deal of swapping between the map and the various text "pages"
dealing with battles and the like). This, then, must be a
machine code job -. and the assembler program in Listing 1 will
do it for us. It's a very simple routine which assumes that the
array x$(22,32) is stored at the beginning of the BASIC
variables area, and it simply prints the 704 characters
contained in the array in the appropriate INK on white PAPER. I
must emphasise that the routine won't work if the array x$()
isn't at the start of the variables area. This means that either
the array must be dimensioned before any other variables are
assigned, or the variables area must first be CLEARed before
loading the array from tape into a BASIC program.


= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
LISTING 1
Map printing routine:
Assembler program

*HISOFT GENS3M2 ASSEMBLER*
       ZX SPECTRUM

Copyright (C) HISOFT 1983,4
All rights reserved

Pass 1 errors: 00

                 10 *D+
        20 *C-
        30 PRMAP
60000   40        ORG  60000
60000   50        LD   A,2
60002   60        CALL #1601
60005   70        CALL #0D6B
60008   80        LD   A,2
60010   90        CALL #1601
60013  100        LD   HL,(VARS)
60016  110        LD   DE,8
60019  120        ADD  HL,DE
60020  130        PUSH HL
60021  140        LD   DE,704
60024  150        ADD  HL,DE
60025  160        EX   DE,HL
60026  170        POP  HL
60027  180 START  LD   B,32
60029  190 LOOP   LD   A,16
60031  200        RST  16
60032  210        LD   A,(HL)
60033  220        LD   (CHR),A
60036  230        CALL COLOUR
60039  240        RST  16
60040  250        LD   A,(CHR)
60043  260        RST  16
60044  270        INC  HL
60045  280        DJNZ LOOP
60047  290        LD   A,E
60048  300        CP   L
60049  310        JP   NZ,START
60052  320        LD   A,D
60053  330        CP   H
60054  340        JP   NZ,START
60057  350        RET
60058  360 COLOUR CP   144
60060  370        JP   Z,BLUE
60063  380        CP   145
60065  390        JP   Z,GREEN
60068  400        CP   146
60070  410        JP   Z,CYAN
60073  420        CP   147
60075  430        JP   Z,GREEN
60078  440        CP   148
60080  450        JP   Z,RED
60083  460        CP   149
60085  470        JP   Z,MAGE
60088  480        CP   150
60090  490        JP   Z,GREEN
60093  500        CP   151
60095  510        JP   Z,GREEN
60098  520        XOR  A
60099  530        RET
60100  540 BLUE   LD   A,1
60102  550        RET
60103  560 RED    LD   A,2
60105  570        RET
60106  580 MAGE   LD   A,3
60108  590        RET
60109  600 GREEN  LD   A,4
60111  610        RET
60112  620 CYAN   LD   A,5
60114  630        RET
60115  640 CHR    DEFB 0
23627  650 VARS   EQU  23627

Pass 2 errors: 00

BLUE   EAC4    CHR    EAD3
COLOUR EA9A    CYAN   EAD0
GREEN  EACD    LOOP   EA7D
MAGE   EACA    PRMAP  87F4
RED    EAC7    START  EA7B
VARS   5C4B

Table used:   137  from   194
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =


Listing 2 [see SHIRES.TAP:SHIRE1L2] will POKE in the necessary
bytes for the map printing routine from BASIC - but it also
contains two other important code blocks. The first of these
"extras" is a machine code routine for printing text held in the
BASIC variable z$, in such a way that words are not broken at
the ends of lines. I haven't given the assembly language program
for this, since it's very similar to a routine I gave in the May
1986 issue of ZXC. The only important difference is that this
routine prints continuously downwards from the current PRINT
position, whereas the previous routine produced a scrolling
display. It's convenient to have both the map and text printing
routines stored on tape as a single code block (saved as "PRINT"
CODE 60000,370) - which is why I've given them together now even
though we won't be using the text printing routine until next
month. The call addresses, by the way, are USR 60000 and USR
60200 respectively.


UDGs

The last chunk of data in Listing 2 defines the UDGs required
for the game.

The program will save these as a separate code block ("UDGS"
CODE 65368,88). You should note that the map printing routine
will print the correct colours for the graphics characters only
as I've defined them in Figure 1.


= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
Figure 1. Codes for the map's graphics characters.

CHR$ CODE    SHAPE          COLOUR
   144       Mountain       Blue
   145       Downs          Green
   146       Water          Cyan
   147       Woodland       Green
   148       Village        Red
   149       Keep           Magenta
   150       Meadows        Green
   151       Pine Forest    Green
   152       Ship           Black
   153       (Plain)        -
   154       Army           Black
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =


There's no reason at all why you shouldn't change the shapes
themselves using your favourite UDG designer, if you wish. But
you mustn't, at this stage, change their meaning or their order,
if you're to avoid getting into a terrible mess later on! CHR$
144 (or GRAPHICS SHIFT/A, if you prefer) must be a mountain, and
so on.

Now for the moment of truth. Somehow, we need to get the data
for 704 locations into our map array - and if I were to present
you with a list of 704 numbers to type in, you wouldn't be very
pleased, would you? Can't say I'd blame you! Let's make
ourselves a map editing program instead. Type in Listing 3 [see
SHIRES.TAP:SHIRE1L3], save it to tape with SAVE "MAP EDITOR"
LINE 1, and then stop the tape in that position and put it to
one side. Enter CLEAR 59999 as a direct command, and load in the
two code blocks you saved from Listing 2 thus: LOAD "PRINT"
CODE: LOAD "UDGS" CODE. Now replace the editor tape and SAVE
"PRINT" CODE 60000,370: SAVE "UDGS" CODE 65368,88. (They must be
saved in this order). Rewind the tape, type LOAD "" and wait for
the menu to appear.

At the top of the screen you'll see the various UDG shapes
presented for ease of reference - except that the "Army" graphic
will be missing since this doesn't form a permanent part of the
map. Ignore options 1 and 2 for the present, and select option
3: "Edit map". You'll be greeted by a blank screen containing a
white cursor square, with brief instructions displayed on the
bottom two lines. Try moving the cursor square around using keys
5,6,7, and 8. 0K?

Fine - now press ENTER, and the cursor will start flashing,
ready for you to insert a graphic character. Press a letter key
between "a" and "i" inclusive, and the corresponding graphic
character will appear at the cursor position on the screen, in
the correct colour. Finally try pressing CAPS SHIFT/0 to delete
it.


[I've changed the map editor (SHIRE1L3 in SHIRES.TAP) to:           ]
[a) Allow graphic selection by just pressing A-I, rather than having]
[   to press ENTER every time.                                      ]
[b) Automatically skip to the next character position along the line]
[   after selecting a graphic, rather than having to press a cursor ]
[   key every time.                                                 ]
[These two simple changes make map entry *much* quicker.       JimG.]


Going to war

Now that you're the proud possessor of a map editor, you're in a
position to build up the map for "War of the Shires". Figure 2
[see SHIRE1F2.GIF] shows you what the map should look like at
the end (except that yours will be coloured, on screen), and
Figure 3 [see SHIRE1F3.GIF] shows you which keys you need to
press at each cursor position. The blank spaces, by the way,
require no action on your part; just leave them blank. At any
stage you can return to the main menu by pressing "q",
subsequently saving the map array to tape using option 2. At the
start of another session you can load in a partly completed map
using option 1, and then carry on where you left off. Go on,
admit it - this is a lot more fun than typing in 704 numbers,
isn't it!

To a certain extent you don't. need to keep rigidly to Figures 2
and 3 - you can shift forests, hills, meadows and villages
around as much as you like, really. However, do please check the
positions of the keeps very carefully (look for the letter "F"
in Figure 3). The keeps must be in precisely the locations shown
in the Figures, and there must be 12 of them. Mountains will
limit the movement of armies in the final game, and so you
should make sure that every location at the edges of the map
contains a mountain. You'd also be well advised to avoid making
changes to the region surrounding the Keep of Darkness on the
western edge of the map (say within seven or eight locations
from the keep) for reasons which will be obvious later on. Also,
make sure that at least one ship is accessible from the mainland
at the start, or your armies will be left high and dry! Within
these limits, there's no reason why you shouldn't build up a
small library of map arrays for use with the game.

Keep the machine code bytes, the UDGs, and your completed map
array safely on tape - they're all vital. Till next month, when
the action starts, happy map-making ...


--
Another Fine Product transcribed by:
Jim Grimwood (jimg@globalnet.co.uk), Weardale, England
--
