1989 · Firebird

Rick Dangerous

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

Core Design's platform game of traps, sticks and dynamite. Rick jumps, rooms scroll and boulders roll to a beat of 25 steps a second, and ten objects share six sprites. What the game hides, from two names in its Hall of Fame that change the game to a line of its own source code, is on Discoveries.

01 · The game

An explorer in 1945

Rick Dangerous is an explorer in 1945, crashed in the Amazon among the Goolu tribe. The game takes him through four places: a cave in South America, a pyramid in Egypt, Schwarzendumpf Castle in Europe, and a secret missile base aimed at London. Each is a single tall map of rooms, which Rick crosses by walking, jumping, climbing and crawling.

Almost everything in a room can kill him: the tribesmen and guards who walk the rooms, and above all the traps, which the manual declines to explain. Rick carries a pistol, a stick for jabbing, and dynamite, and he starts with six lives, six bullets and six sticks. A touch from an enemy or a trap costs a life, and he starts again where he entered the room.

The title screen: RICK DANGEROUS in orange above Rick in a film-strip frame, with the Firebird and Core Design logosThe first room: Rick at the left of a grey stone cave crossed by blue water, below the score panel

The title screen, and the first room of the cave. The panel shows the score, the bullets, the dynamite and the lives as hats.

02 · One frame

What the game sees in a room

The picture below is drawn by this page from the memory of one frame of play, recorded in the emulator: the screen, the character set and the video chip's registers as they change during the frame. Every one of its 104,448 pixels matches the emulator's own picture.

Drawn by the site's C64 renderer from the recorded frame, pixel for pixel the emulator's picture. The overlay takes each tile's code from the screen and looks it up the way $4081 does, with the eight codes of graphics set 0 from $185B.

The room is made of characters, and the game decides what each one is by its code alone. Eight codes in zero page ($38-$3F, copied from $185B for each graphics set) mark where each kind begins: background first, then ladders, deadly tiles, scenery that stands in front of Rick, platforms, springy floors (Discoveries), ordinary floors and walls, and the tops of ladders. $4081 turns those eight numbers into a table of 256 flags at $0600, and every collision test reads it. The tile graphics only have to be kept in that order.

03 · The beat

The game takes a step every second frame

A PAL C64 draws 50 frames a second, and Rick Dangerous works to two beats. The picture is kept by the raster interrupt ($3A0D), which the video chip calls at chosen lines of every frame. The game is played by the main loop ($0A0A), outside any interrupt. The loop waits until the frame counter that the interrupt counts up ($07) is even, then takes one step of play. So Rick, the enemies and the traps move 25 times a second, while the sprites, the colours and the sound are kept up 50 times a second.

The interrupt works down a short list of handlers ($3B9D). Each handler has its own raster line in a table ($3BD7), and before it returns the interrupt sets the line of the next one. The list is picked again every frame: with more objects in view than sprites, one or two handlers go in the middle, at lines that follow the objects, and during a scroll two other handlers take over.

The recorded frame from section 02, with the lines at which each handler of the chosen list runs. The lists and the lines are read from the listing ($3B9D, $3BA7, $3BD7). The two lines marked "follows the objects" are put where the bottoms of the second and fourth sprite in height order fall, so they move every frame; here they are drawn at an example height.

One step calls, in order, Rick's move ($0B2A), the exits and the scroll ($186F, $3018), every object ($1990), the bullet, the dynamite, the room bonus, the panel's sprites, the masked sprite images ($0F83) and the panel. Nothing in the step waits for the beam. In the emulator, 141 steps took 284 frames.

04 · Rick on his feet

Rick jumps 33 pixels high, in eleven steps

Rick's vertical speed is kept in whole pixels and 256ths of a pixel ($39B5, $39A9). Each step adds the speed to his height and then half a pixel to the speed, up to eight pixels a step ($0B82). A jump sets the speed to 5½ pixels upwards ($0D2D). Eleven steps later the speed has run out and he is 33 pixels up.

Walking is two pixels a step to the left or right, with no run-up and no slowing down ($0E64). The stick is read again every step, in the air as on the ground, so a jump can be steered or turned round in mid-flight.

Rick's height at each step, from left to right, the numbers counting steps; yellow in the air, green on the floor. Drawn by rickStep, a port of $0B2A and $0C92 for open ground. test_move.js holds it to the game's own code run in the kit's simulator on the first room with its ceiling taken away: 400 runs of 80 steps of random stick, on both kinds of floor, the same position and speed at every step.

Before each move the game tests the tiles at the new place ($3F04). A move that runs into a solid tile is tried again without its sideways part, so Rick slides down a wall rather than sticking to it. Rising into a ceiling turns the speed into a fall of half a pixel a step. Falling onto a floor lands him: his height is put back on the row of tiles ($0C20) and his speed set to one pixel down. On the next step that pixel is blocked again, so a Rick standing still is landing on the floor 25 times a second. One kind of floor does not land him at all: "Springy floor" above shows it (Discoveries).

05 · The rooms

Each level is one tall map

A level is a column of map rows, eight bytes each, from $9200 to $A5BF. Each byte is the number of a block, and each of the 256 blocks at $8200 is four rows of four tiles. So a map row is 32 tiles across, the width of the play area, and four tiles deep. The screen shows six map rows; when Rick climbs near the top or the bottom, the view scrolls two map rows (64 pixels) as eight shifts of one row ($3018, $30A3), each drawn on a hidden screen (section 06).

The Maps tab draws all four levels from these bytes. Levels 1 and 2 use one tile set and levels 3 and 4 another; $1911 swaps them, exchanging 2 KB of graphics between $7000 and the RAM under the I/O chips.

06 · The scroll

The scroll is drawn on a hidden screen

When Rick climbs near the top of the screen (his height under $60) or drops near the bottom ($CC and over), play stops for a third of a second while the view moves two map rows, 64 pixels ($3018, $30A3). The game keeps two screens, at $C000 and $C400. While the video chip shows one, the main program copies the play area into the other one row of tiles further on, with the next row of the map coming in at the edge ($3132). The raster interrupt then points the chip at the new screen ($3AE8), and the two change places. Eight shifts of eight pixels take sixteen frames.

The first rooms of South America scrolling up, drawn from the map. Each frame's screen and job come from the tables the scroll's raster handler reads ($3AE0, $3AE4, $3AE8) with the frame count $15 running from 15 down to 0.

The colour RAM cannot be kept twice: the chip has only one. Its rows are copied one row on from the raster handler at the bottom of the screen, as the screens swap ($32B0, $34C6). In the frames between, the objects move eight pixels to keep up ($3E55).

07 · Traps

Every trap says what sets it off

Each object in a room has a record of five bytes in the object lists ($A5C0): where it is, its type, and a byte of flags. For a trap, four of the flags say what sets it off: Rick walking into its zone, the stick, a bullet, or an explosion ($1A72). One more makes it deadly to touch while it moves and another while it waits, and one pays 1000 points and removes it when its movement ends.

Counted by this page from the object lists in the listing: the records of types 24 to 70, the traps, in the rooms of each level.

That is why the manual warns that the gun is often a trigger rather than a weapon. A trap with only the bullet flag goes off at nothing but a shot.

08 · The boulder

The boulder in the first room follows a script

A trap does not think. Once it goes off, it plays a script from a table with one entry for each trap type ($B880): records of three bytes, a count and a step across and down, repeated that many times, until $FF ($1B0B). A step that would take it past the side of the room or out of its 320 lines ends the script early. At the end the trap goes back to where it started and waits again or, with bit 0 of its flags, pays 1000 points and is gone. Its frames change every fourth step, from a list of their own.

The recorded frame of the first room, with the path of trap type 42 from where the game had placed it in that frame (object 5). Drawn by trapRun, a port of $1ACF; test_trap.js holds it to the game's own code for all 47 trap types, every step's position and frame.

The boulder of the manual's drawing is type 42 ($44B6). It waits at the far left of the first room, level with Rick, drawn with the blank frame $AB, until he walks into its zone. Its script has nine records: right for 96 steps at two pixels a step, a drop, back to the left, another drop. The boulder never finishes it. On the seventh record, its third drop, it reaches the bottom of the 320 lines an object can be in, and that ends the script.

The enemies have no scripts. Their handler ($11AB) walks each one two pixels a step towards Rick's column, takes a ladder when Rick is above or below it, lets it fall where there is no floor and turns it at walls. The stick stuns an enemy for 25 steps; a bullet or an explosion kills it for 50 points.

09 · Sprites

Rick walks behind the scenery

A C64 sprite can be set behind the background, but then it is behind every foreground pixel on the screen at once, and Rick has to pass behind some tiles and in front of others. So Rick Dangerous builds his picture again every frame ($0F83): it takes his 64-byte frame and ANDs it with a mask made from the tiles behind him ($1052), clearing every pixel where a tile of the "in front" kind stands. The dynamite and up to three enemies get the same treatment. The finished pictures go into one of two sets of buffers, $C800 or $CA00, by turns, so the video chip never shows a half-drawn one.

The bullet is not a sprite at all: $2ABA writes a character into the screen, keeping the one it covers, and moves it eight pixels a step.

10 · Sprites

Ten objects share six sprites

The C64 has eight hardware sprites. Rick takes two, laid one over the other, which leaves six for the objects of a room: enemies, traps, treasures and the dynamite, ten slots in all. Once a frame, at line 240, $3559 sorts the ten by height, and the six highest get sprites 2 to 7. A seventh and eighth object lower down get sprites 2 and 3 again: a raster handler waits until the beam is below the second of the six ($3831) and moves the two sprites down to them. A ninth and tenth get sprites 4 and 5 the same way, below the fourth ($387D), and lose the ninth bit of their X on the way: "Show the bug" below sets up a room where it shows (Discoveries).

A room of random objects, on the play area in sprite coordinates. Drawn by multiplex, a port of $3559, $36D9 and the handlers at $3831 and $387D; test_mux.js holds it to the game's own code on 3,000 random rooms: the order, the sprites, the split lines and the ninth X bits.

11 · Music

Music: seven tunes by Dave Pridmore

A tune plays on each story screen before a level, on the ending, on the title and Hall of Fame, and on GAME OVER. None plays during play: while a tune runs, the sound effects and Rick's footsteps are silent ($4F86).

The game's own music player, its code ($5042-$5730) and the tunes' data ($5732-$5F8D) as the listing holds them, run once a frame on the kit's 6502 simulator in this page, through the site's model of the SID. test_music.js compares every SID write of every frame of all seven tunes with the same code called on the simulator directly: 117,097 writes. The tunes do not use the filter.

Each tune has a header of three addresses at $5732, one track list a voice. A track list is a run of pattern numbers with a few commands mixed in (transpose, repeat, change an instrument); a pattern is notes and their lengths, rests, and changes of instrument, arpeggio and slide. Tunes 5 and 6 leave voice 3 alone.

12 · The tape

One load

The cassette loads once. A turbo loader puts up NOW LOADING ... RICK DANGEROUS and reads the whole game into memory, all four levels, the ending's text and every tune; nothing is loaded again. The game's first instruction is at $0810.