Harebrain

By Chris Dewhurst

Originally published in EUG #57

Instructions

Just as you were looking forward to sinking your teeth into that rich, dark, succulent chocolate, the evil Herr Hase of Hutchingham has stolen all the Easter eggs and hidden them in his underground network of caves and passages.

Your task is to find and collect the stolen eggs, which are scattered throughout the four levels of the network. The level on which you are currently situated will scroll left or right as you press the appropriate direction key. You can climb up and down ladders, move through doors which lead to other levels, and punch through certain wall sections to further your quest for those elusive eggs.

But watch out! You have a limited number of 'punches' which can only be replenished by collecting the carrots. Going through a door will take you to the same horizontal position in the tunnel above or below, but some doors are one-way only. To pick up a carrot, egg, or to walk through a door, simply stand in front of it and press the up key.

You are advised to make a map as you go along so that you can work out the most efficient way around! If you get stuck, press ESCAPE to begin again.

Game Controls

A - Left, S - Right, P - Up, L - Down, ESCAPE - Quit

Technical Information

Note that the main program "G.HAREBRA" must run at PAGE=&2100. It assembles the machine code, loads in G.HARESHA(PES), the sprites and masks and G.HAREMAP(S), the screen data.

Machine code subroutines

ascend Ascends to cave above by incrementing 'mpy' and calling 'draw'.
calc Calculates screen address given the column no. in X and character row no. in Y.
carrot Makes carrot eating sound, restores the screen behind the hare, and increases punch counter.
cpyscr Copies screen data at hare's position into address of sprite no.18.
delay Creates short delay, entered with a value in A.
descend Descends to cave below by decrementing 'mpy' and calling 'draw'.
dig Displays the two-digit BCD number in A in the big font by masking off the high and low nibble respectively and calling 'digit'.
digit Displays the number in A in the big font. Masks 9-18 are the data for the digit characters, so ADC #9 before calling 'expnd'. The exploded data is ANDed with &F0 (code for YYYY) to produce the green colour (logical yellow is actual green in the game).
down Moves hare down, provided the character below is a ladder character (no.6) and the hare isn't at the bottom of the screen.
draw Plots screen: map number 'mpy' starting at position 'mpx'. 3 bytes of data hold data for one column of 6 characters, high nibble/low nibble. 'draw1' masks off each nibble. 'draw2' adds 6 to get correct sprite number. If it was 0, the correct 'spine' sprite is drawn 'evntab' or 'oddtab' depending on if the current x co-ordinate is even or odd. Note hare is plotted immediately after the central column - instead of waiting until the whole screen is drawn - to avoid flickering.
eggno Adds the BCD number in A to the number of eggs collected and displays the value in the special big font.
expnd Expands mask A. Masks are stored in compacted form, since they are made of only two-colours. High and low nibbles of a byte of mask data represent two rows of pixels. 'dom' derives correct mode 5 display byte by duplicating the low nibble in the high nibble position, e.g. &C -> &CC. Data for fancy digits is stored in this format as well.
fin Finale display. The bottom three bits of values in memory locations are masked off and used as the colour in which to plot squares in the playing area. 'chqr' is a table of values for four pixels of the same colour in mode 5, i.e. &0=BBBB, &F=RRRR, &F0=YYYY, &FF=WWWW. The address at 'fxlop'+1 is incremented at the end so that next time 'fin' is called, the pattern of squares will be slightly different.
getegg Makes sound, restores screen behind the hare, and increases egg counter.
ghpos Calculates screen address for hare. Note hare is always at column 9.
hare Calls 'cpyscr' and plots hare sprite. Correct frame is 'wlk' + 'dir' + 1, where wlk=21 for facing left, =24 for facing right, i.e. sprite numbers for left- and right-facing hare head. 'dir'=0 or 1. Note use of SEC with ADC to add an extra 1.
keys Checks for keypresses. A loaded with internal key number (see ELECTRON ADVANCED USER GUIDE pg 39) before a call to 'scan'; if the result was negative the key was pressed.
left Moves hare left, provided character to left of hare isn't solid bricks (no.7), and character to left and below isn't blank (can't walk on thin air!). If character is destructable bricks (8-11) call 'smash' routine.
mksnd Generates a sound. On entry, sound number in A, which is mutliplied by 8 to index into 'sounds', then X and Y are set to point to this sound before a call to OSWORD 7.
objct Deals with object, if any, at hare's position. Object number in A on entry, and is used as an index into an 'action' table, which contains addresses of routines to go up/down through a door, collect a carrot, or pick up an egg. This address stored after the JMP in 'go'.
pnchno Adds the BCD number in A to the number of punches left. Ensures result is not >50.
right Moves hare right, provided character to right of hare isn't solid bricks (no.7), and character to right and below isn't blank (can't walk on thin air!). If character is destructable bricks (8-11) call 'smash' routine.
rmap Reads from the map at co-ordinates in Y and X and exits with result in A. See 'wmap' for more detail.
rstr Restores screen data, stored as sprite no.18
scan Scans keyboard using OSBYTE &79 with internal key number EORed with &80.
setup Resets hare's position, location in the network, and number of eggs collected and punches.
sides Plots the top and bottom horizontal sides of the screen.
smash Starts 'smashing' up bricks by replacing them with successive frames of disintegrating bricks. Destructable bricks are chars no. 8,9,10,11. If the current char is 11, it is replaced with 0 and decorative spine char (see notes on 'draw').
spr1 Main sprite routine. All sprites 3 columns wide, but sprites 0-21 are 2 char rows deep, and hare sprites 4 char rows deep. Dummy mask of 0s created for sprites 0-21 building blocks). 21 subtracted from sprites 22-27 to get mask no.
up Moves hare up, provided the character above is a ladder character (no.6) and the hare isn't at the top of the screen. If the character at the bottom half of the hare (hare is equivalent of 2 blocks tall) is 2 (door up), 3 (door down), 4 (carrot), or 5 (egg), the 'objct' routine is called.
wmap Writes A to the map at co-ordinates in Y and X (note X=y co-ordinate, X=y co-ordinate). Y is already a multiple of 3 because the hare's x co-ordinate is a multiple of 3 and one column of cave data (6 characters) is 3 bytes.

Machine Code Variables

dir, wlk Current frame of hare.
hrx Hare's x co-ordinate in screen columns.
hry Hare's y co-ordinate as a multiple of 3 for easy indexing into screen data.
hx,hy Hare's co-ordinates in character blocks.
mpx Horizontal position on map.
mpy Map number. A multiple of 2 so that it doesn't need to be multiplied by 2 before being used as an index into 'wrrns'.
mskadr Addresses of masks.
quit Contains 0 if game in progress, -1 if ESCAPE pressed, 1 if all eggs collected.
scrtab Addresses of the beginning of the first 16 character rows in Mode 5.
sizes Addresses of non-masked sprite data. Note first address points to blank area created by the bottom half of one spine and the top half of another.
S% Beginning of sprite data.
sounds Table of sounds.
wrrns Addresses of screen data.

Chris Dewhurst, EUG #57