General Instructions
This is the BBC/Electron conversion of the Archimedes game by the same name, exclusive to readers of EUG. It is a simple but challenging and enjoyable maze game in which you move a character around the screen that has to collect pieces of fruit. The catch is that once you start moving in a particular direction you carry on doing so until you hit a solid wall. So plan your route carefully. And hurry, there isn't much time.
There are 25 levels to complete, each of which can be accessed by typing in the a password when you select menu option 2 from the front screen. The game must be run with PAGE set to &2900. The EUG disc must be left in the drive throughout the game because, due to memory restrictions, sprites are loaded into a cache at the beginning of each level and these sprites are extracted from the sprite file on disc. Technical notes on programming are in the file PLIGTCH. Have fun!
Thanks are due to the authors of the original game, available for the Archimedes from Skullsoft at mysite.freeserve.com/skulloft/plig.htm.
Technical Notes
Notes on procedures, variables, and/or machine code subroutines are described under the notes on the program in which they are used. Machine code labels appear in lowecase in the program but are written in UPPER CASE for clarity in the text.
1. Files
S.CLEV | Level generator. Needs to be run before running S.GCODE |
S.GCODE | Main game assembly. Assumes S.CLEV has been run | S.TITLES | Machine code for title and password screens |
G.PTS | Sprite file accessed by G.PMC. Note these are not loaded into memory but extracted as required into a sprite 'cache' (See program description below) |
G.PMC | Object code created by S.GCODE |
G.PMC2 | Object code created by S.TITLES |
G.PINTRO | BASIC loader. Data for Plig banner poked into memory. *LOADs in G.PMC and G.PMC2 |
G.PGAME | BASIC control program |
2. CLEV Create Levels
0 | Space | 1 | Tree | 2 | Metal Plate | 3 | Rock | 4 | Palm Tree | |
5 | Pyramid | 6 | Fir Tree | 7 | Column | 8 | Plate 2 | 9 | Tree Stump | |
A | Solid | B | Bricks | C | Fence | D | Cube 1 | E | Piping | |
F | Cube 2 | 10 | Cube 3 | 11 | Barrel | 12 | Grave | 13 | Cherries | |
14 | Choc | 15 | Grapes | 16 | Apple | 17 | Pineapple | 18 | Drink Can | |
19 | Acorn | 1A | Lolly | 1B | Banana | 1C | Flames | 1D | Toadstool | |
1E | Plant | 1F | Mine | 20 | Left arrow | 21 | Up arrow | 22 | Right arrow | |
23 | Down arrow |
One character is represented by one nybble:
0 Always a space 1 'Fake' character Plig can pass through, e.g. false bricks 2-7 Fruit characters 8 Harmful character e.g. fire 9-C One-way characters e.g. arrows D-F Solid sections e.g. trees
For example on level 1:
Fakes- Fruit----- Harmful One way--- Solid-- Index (0) 1 3 4 6 7 8 9 A B C D E F Value (0) 0 13 0 0 0 0 0 0 0 0 1 0 0
The screen is based on a 10x8 grid, equivalent to 80 characters, stored as 40 bytes - one character per nybble - specified in data items 16-55.
Data item 56: Plig's (x,y) start coordinates, &YX
Data item 57: Time allowed in seconds (BCD, e.g. 30 = 30 decimal seconds.)
3. GCODE Game Code Assembly
Declared variables, lines 50-120:
C%() | Mode 2 colour codes, READ in from line 3130 |
NSNDS | Number of sounds used in game |
NSPRTS | Number of sprites |
NPLLTS | Number of palettes used by 4-colour sprites |
CACHE | Sprite cache. Only 15 sprites are held in memory at any one time, extracted from G.PTS file at beginning of each level |
ICND | Sprite data for clock and cherries icons |
FONTS | Data for 2-colour digits (character data) |
LEVPTR | Start of pointers to level data |
LEVDAT | Data for first level |
OSD, OSB, OSF, OSG | OSWORD, OSBYTE, OSFILE, and OSARGS respectively |
Zero Page Variables:
&50 Plig x coordinate in columns (0-71) &51 Plig y coordinate in character rows (0-27) &52 Plig x coordinate in map units (0-9) &53 Plig y coordinate in map units (0-7) &54 Plig character, 16=facing forward, 17= &55 Level number 0-24 &56 Number of fruit pieces left to collect &58 Clock value (BCD) &59 Clock flag, <>0 if clock needs decrementing &77-A Sprite Palette
Machine code subroutines in order of appearance:
CHKT | Checks &59, is non-zero if screen clock to be decremented |
PTIM | Calculates address at which clock digits appear (5,30) and calls NUM to print digits |
IEVNT | Initialise the event vector EVNTV at &220/1 to call TIMER every second |
TIMER | Increment &59. CHKT will detect the change and adjust clock if necessary |
NUM | Expand 2-colour digit data into a 16-colour mode 2 sprite. Entered with X=x pos of digits, Y=y pos of digits, A=digit pair to be plotted. High and low nybbles masked off. Multiplied by 8 and added to FONTS to get pattern address. Each byte of pattern has two bits at a time rotated out. Result is an index into CCDS, a table of values for black-black, black-white, white-black, and white-white Mode 2 colour codes. These are masked or ANDed with the corresponding value from FMSKS to get different colours for different digits. This routine is a variation on the one in the OS ROM |
CHKK | Check keyboard for key presses. List of five INKEY codes in KEYS |
PLGR | Move Plig right |
PLGL | Move Plig left |
PLGD | Move Plig down |
PLGU | Move Plig up |
PLGX | Acknowledge Escape condition. Set clock flag and zeroise clock |
FRUIT | Collect a fruit by reprinting (EORing therefore erasing) fruit, make sounds, and decrement fruit |
PLGF | Show Plig facing forward briefly, used when changing direction |
DELAY | Delay loop affected by value in A |
INTLEV | Initialise level. Get correct level data address by using &55 as index into LEVPTR table of addresses stored 25 low bytes followed by 25 high bytes. Copy level data into MAPDAT. Open filename at FSP, "G.PTS", by setting X and Y registers to point to CACHE and calling OSFIND with A=&40. Store file identifier in first byte of CB, the Control Block. CB+1 and CB+2 specify where to load the data. CB+5/CB+6 is how many bytes to load, in this case the size of the sprite - &80 bytes. A sprite index of zero is a space so the corresponding position in the cache is filled with zeros. Otherwise position in PSPTS from which to extract bytes is calculated by doing ((sprite index)-1)*&80 at NOSPC. X and Y registers set to point to CB, and A=3 to signify loading of data. NEXT2 adds &80 to &70/1 to get next position in cache until all 15 sprites have been loaded. Work out Plig's starting coordinates |
PPLG | Print Plig |
READM | Read value from map, returning &FF if off map |
CALCM | Calculate linear map position in memory, = X*4 + Y DIV 2 |
WRITEM | Write value to map |
SHWLEV | Show level, display map characters on screen. One byte represents two characters plotted one below the other. Note the 'cascading' nature of the routine where after a subroutine has been called the subroutine is executed again because it Is the next bit of code. SHW4 plots the sprite represented by a nybble. SHW3 plots sprites represented by two nybbles by calling SHW4 and leads into SHW4, thus SHW4 is executed twice. SHW2 plots a column of sprites (4 bytes=8 nybbles or sprites) by setting up a loop to call SHW3 four times. SHW1 calls SHW3 ten times to plot ten columns of sprites across the screen. Note that SHW4 tallies how many fruit characters it detects; this is the fruit counter |
BUMP | Make bump sound as Plig hits wall. Leads into MKSND |
MKSND | Make sound. A = sound number |
SNDDAT | Sound data |
CALC | Calculate screen address |
EXPAND | Expand four-colour sprite into mode 2 format. A=sprite number. Compacted data takes up &80 bytes, expanded to &100 bytes in page 6 of memory. Corresponding palette copied to zero page. Data is arranged in special format so that two bits at a time can be rotated out and used as an index into the palette to get the correct byte to put onto the Mode 2 screen |
PLOT | Plot sprite at address in &70/1 by copying data from page 6 |
PALETTE | NPLLTS x 4 bytes giving colour codes used when expanding sprite data. Line 3170 consists of strings of 4 characters corresponding to colours used in reverse order; the colour codes are worked out in line 3080 using C%(). E.g. pallette zero specified as 3120 becomes 0,2,8,10 (black, red, green and yellow), palette four specified as 6310 -< 0,2,10,40 (black, red, yellow and cyan) |
PALIND | Index for each sprite into PALETTE. For example sprite 1 (Tree) uses palette 0, sprite 2 (Metal Plate) uses palette 4 |
4. TITLES Title Page Assembly
TTL | Fills background with random combinations of blue pixels. Random number generator address is &AF51 on BBC B, &AA7B on Master. Prints menu options |
EPS | Password screen |
GOS | Game over screen |
DOUB | Prints double height, outlined characters at (&7B/C,&7D/E) in random colour |
V25 | Performs MOVE to coordinates held at (GX+1/GX,GY+1/GY). Note reverse order of VDU string for speed. |
PMESS | Prints each letter of message in double height |
BIG | Enlarges character definition to double height blanking some lines in lower half |
SPECIAL | Plots slanted dithered or plain bands of colour on screen |
VCDS | VDU codes for printing double height character |
RBTAB |
Colour codes for dithered bands:
Index Value Colour 0/5 13/14 Green-Yellow 1/6 7/11 Red-Yellow 2/7 19/35 Red-Magenta 3/8 52/56 Blue-Cyan 4/9 31/47 Yellow-white |
STRP | Codes for colour bands. &0X is plain colour where X = GCOL code. &8X = dithered colour where X=index (0-4) into RBTAB |
DRAWV | Move and draw codes for the coloured bands |
WINDAT | VDU codes for graphics windows set up before bands are plotted so bands don't have to fill whole of screen |
5. PINTRO Plig Intro
Defines ENVELOPEs, prints banner.
PROCplig | Reads and pokes in data for banner. A pair of numbers describe a vertical line's start position and length. See article LINEIT for details. Different parts of logo printed in different colours by Boolean test in line 340. |
6. PGAME Plig Game
PROCgame | REPEAT initialise timer, print screen. REPEAT check keyboard UNTIL all fruit collected or out of time. If fruit collected move to next screen. UNTIL out of time |
PROCintro | Show password for level (not first level) |
PROCgetpw | Player inputs password |
PROCadd | Add letter to input string and call letter plotting routine to plot on screen |
PROCdel | Delete letter from input string |
PROCkey | Wait for keypress |
PROCplig | Plot banner - same as in PINTRO |