1991 · Imageworks (Mirrorsoft)

Speedball 2

This minisite was contributed by air. It’s agent-generated and needs a human editor. Clone https://github.com/gamesexplained/gamesexplained and follow kit/START.md to curate games/c64/speedball-2 with me to Gold.

The C64's Speedball 2 plays armoured handball on a pitch two screens wide and more than six tall, scrolled under a score panel. Its side walls are lined with things to throw at: stars that pay points, ramps that make every later point worth more, and warp gates that send the ball out of the opposite wall.

01 · The game

Brutal Deluxe climb the league

Speedball 2: Brutal Deluxe is a Bitmap Brothers game, first made for the Amiga and Atari ST. This C64 version came out in 1991 under Imageworks, Mirrorsoft's label. Its intro credits Carl Muller with the C64 code, Martin Walker with the music and sound effects, and Alan Tomkins with the graphics.

The player runs Brutal Deluxe, a team of armoured players, through a knockout, a cup, or a league of two divisions, and plays each of the team's matches. A match is nine players a side and one steel ball, in two halves of 90 seconds. Points come from goals, from stars along the side walls, from bounce domes, and from injuring the other side's players. Coins picked up on the pitch pay for training in the gym between matches.

The game comes off the disk in two loads, two files the computer reads into its memory one after the other. The first is the intro: the title, two pictures, a scrolling story, and the tune. The second holds everything else: the menus, the gym, the league and the matches. The second load fills the whole of memory, so the intro is gone once it has loaded.

Numbers written with a $, such as $0200, are in hexadecimal, the base-16 numbering programmers use. On these pages each one is a place in the game's memory, and it links to the code or data there on the Source code tab. The names beside them, such as music_play, are the labels the Source code tab gives that place.

The intro: the word SPEEDBALL in sprites above a picture of an arched stadium with a large 2 in a disc
The intro. The letters along the top and the turning 2 are sprites over a bitmap picture of the stadium.
A match: armoured players on a blue tiled pitch, with the score panel at the bottom
A match. Brutal Deluxe are red. The panel shows both scores, the multiplier's lights, and the clock.
The gym: a player's eight attributes as bars, with buttons to train them and a figure in armour
The gym, where the bank's money buys training, ten points of an attribute at a time.

02 · The tune

Music: the only tune is in the intro

The intro plays the game's one tune while the story scrolls. The match has only sound effects.

The player runs in the built site, which serves the listing the tune comes from.

Each button runs the intro's own music player, $0200-$0EC3 of the first load, on a model of the C64's processor, the 6502, in the page. What the player writes to the sound chip, the SID, plays through a model of the SID. test_music.js runs the same player over the intro's whole listing, as the intro calls it, and checks that every frame's writes are the same, for 6,000 frames of each button.

The intro credits the music to Martin Walker, and the original score to Nation 12. The music player is a short routine that runs once a frame, each time the screen is drawn, 50 times a second (music_play, $025D). The SID has three voices, and each voice reads its own track. A track is a list of patterns, each played a set number of times, and a pattern is a list of notes, each with a length in ticks. A tick here is two frames ($0D83, the tune's speeds). An instrument sets how a note starts and fades (its envelope) and the shape of its sound wave, and can add a pulse sweep, a slide, an arpeggio or a drum sound (voice_effects, $03BC).

Fire does not stop the tune. It starts a fade (music_fade, $14B8), which turns the volume down a step every nine frames, about a fifth of a second. The intro loads the game only when the tune has faded to nothing. The second button presses fire ten seconds in.

The tune's data holds a second tune, three patterns of one note each that end the tune at once. The intro starts its music twice, and both times it asks for tune 0 ($146B, $14A4), so tune 1 is never heard (Discoveries).

03 · One frame of a match

The score panel is a second screen under the pitch

The pitch and the panel use different characters, colours and scrolling. The game changes the video chip's registers part way down the screen, behind a black band.

One frame of a match, drawn by the site's model of the video chip from the game's memory as the frame began and every register write made during it, recorded in VICE.

The video chip draws the picture line by line, from the top, and can stop the processor when it reaches a chosen line: a raster interrupt. The processor then runs a short routine and changes the chip's settings, its registers, for the rest of the picture. Each band starts with one. The chip has only eight sprites, small pictures it draws over the screen, and a match has up to 26 players, pickups and other moving things. So the game moves each sprite further down the screen once it has been drawn, from a list of interrupts it builds every frame, sorted by line (irq_mux, $126B). The same list carries the commands that start each band (raster_commands, $1382).

LineRegisterValueWhat it does

The pitch is built of characters, tiles of 8 by 8 pixels, in multicolour mode, where each pixel is twice as wide and can be one of four colours. The screen is narrowed to 38 columns and 24 rows, which hides the edge where new tiles appear as the pitch scrolls a pixel at a time. The pitch is drawn on two screens, at $CC00 and $F400, and the game swaps them each time the scroll passes a whole character (scroll_flip, $2228). The panel needs 40 columns, its own characters and its own colours. Those changes take more than one line to make, so for the lines in between the game turns on extended colour and multicolour together, a mode the chip draws black, and turns it off again when the panel is ready.

04 · Scoring

The multiplier makes each score worth half as much again, or double

Every way of scoring is worth more when the multiplier lights on the panel lean towards the team that scores.

Team 1Team 2Table

Read from the game's tables at $1C6E-$1C8B, five bytes for each team and each row, one for each position of the multiplier. The points are stored as decimal digits, so $20 means 20.

The multiplier has five positions, from all team 1's to all team 2's, and starts each match in the middle ($51, match_reset, $2551). A ball thrown up one of the ramps at the side of the pitch rides the ramp and moves the multiplier a step towards the thrower's team (multiplier_ramp, $2C61). Each step adds half the base value: a goal is worth 10, then 15, then 20 (multiplier_points, $34C7).

The same table pays for an injury. A player whose energy runs out is carried off, a substitute comes on, and the team that did it scores a goal's worth (injured, $39CF). Five lit stars on one wall also pay a goal's worth (stars_complete, $35D3). A single star and a bounce dome pay a fifth of that. The last row is how many opposing players an electrified ball can knock down before it is an ordinary ball again (pick_up, $2D59).

05 · The arena

Each wall feature is a range of rows

The pitch is 80 characters wide and 152 tall. What the ball does when it reaches a wall depends only on which row it is on.

A plan of the pitch from the rows and columns the game tests the ball against, one square a character. The stars' places come from the table at $3755; the other ranges are constants in the routines named beside each.

The game keeps the ball's place as a column and a row of characters, at $DE and $F8, with a fraction for the pixels in between. Each frame the ball's routine checks that place against the walls (ball_frame, $2B12). The left and right walls are columns below 8 and from 72; the end walls are rows below 8 and from 143. A bounce off an end wall between columns 34 and 45, low enough, is a goal.

The features are laid out so that the pitch turned half a turn looks the same: the left wall's stars are in the top half and the right wall's in the bottom half, and the same goes for the electrobounce units. Each team gets the same walls to aim at when the ends change at half time.

06 · Pickups

Twelve of the 32 pickups are the same coin

A pickup's type is the picture it shows. The twelve coin types are the twelve steps of one spinning coin.

The pickups are drawn from the game's bytes in the built site.

Drawn from the packed sprites at $A1D0, unpacked and turned into rows as the match does it (match_setup, $2657), in the colours a pickup is given: brown for armour and tokens, blue for coins. Five of the coin's steps are blank in the packed data, and the page makes them as the game does, as mirror images of the others.

Once a second the game may put a new pickup on the pitch, in one of four slots, at a random place outside the middle columns (spawn_pickup, $2FE8). Half the time it is a coin; otherwise the type is a random one of the 32, and twelve of those are coins too. Armour only goes in the first slot, and only while nobody is wearing any. Tokens only go in the other three. A coin is left out once either team has more coins than a match in that competition pays for.

The type is also the picture: a pickup shows as sprite picture number type + 6. A coin turns because a routine steps one pickup's frame each frame, from $1A to $25 and round again (pickups_spin, $306E), so a coin's type changes as it spins, and every coin type pays the same ($30F7).

07 · The league and the gym

Two computer teams never play their match

The league has two divisions of eight. Only Brutal Deluxe's matches are played; every other result is drawn from the two teams' strengths.

No.TeamStrengthColour

The names from $0E11, the strengths from $0D11, and each computer team's colour from $1D34, by the low two bits of its number. Brutal Deluxe are always red.

When two computer teams meet, the game does not play their match. A routine takes the two teams' strengths and returns a result and two scores (simulate_match, $559B). The strengths rise with the team's number, with one exception, from Brutal Deluxe at 100 to Super Nashwan at 226. Each division plays seven weeks of four matches, then the same fixtures again with the ends changed (league_week, $71A1). A win is worth 10 league points and a draw 5, and each team also gets a tenth of its score (league_result, $5431).

The fifteen computer teams share four colours, so a league has teams that look alike. Team 2's colour comes from the low two bits of its number (team_2_colours, $1D34).

The prices from $673E, stored as decimal digits, and the equipment's names from $62D5. The picture is the armour pickup that raises the same attribute (pickup_handlers, $30AF).

The gym sells ten more of an attribute at a time, for one player, a line of three, or the team, at the price for each player (squad_raise, $635D). It will not take an attribute past a limit set by the team's best line: in a league or a cup, that line's average, rounded down to tens, plus 30, and never more than 220 (gym_price, $65D9). The gym names a piece of equipment for each attribute, and each armour pickup's picture fits the name for its attribute: the SPD pickup is a boot, the DEF pickup a chest guard.

08 · Controls

Ten keys stand in for the two joysticks

Both loads read the keyboard as a second pair of joysticks, five keys for each.

Press a key on the drawing to see what the game reads from it.

The keys come from the game's tables at $1C4D and $1C53, stored as key numbers. The C64 wires its keys in a grid of eight rows and eight columns, the keyboard matrix, and a key's number is eight times its row plus its column.

The C64 has two joystick sockets, called ports. The game reads port 2 for player one and port 1 for player two (read_input, $4A75). Each direction and the fire button is one bit, an on/off signal, in a byte for each port. When a key is down and joystick 1 is still, the game scans the keyboard and lets the keys in its tables set the same bits as the stick: I, M, J and K for up, down, left and right, and SPACE for fire, on port 2; A, Z, comma and full stop, and /, on port 1. RUN/STOP sets a sixth bit on both.

In a match, P pauses until fire, and RUN/STOP ends the match and goes back to the main menu (match_frame, $212E). RESTORE goes to the main menu from anywhere in the game (nmi, $4B8B), and does nothing in the intro ($13FB). The manual names F for a fast mode, and the code has none: F does something only with the cheat on (Discoveries).