1989 · Activision

Power Drift

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/power-drift with me to Gold.

A twelve-kart race over a track that climbs and falls like a roller coaster, drawn in text characters on a Commodore 64. Every hill, jump and bend is a short routine that changes how the road is drawn, row by row.

01 · The game

Four laps, and a place in the first three to go on

The player picks one of twelve drivers and one of five courses, A to E, each of five stages. A stage is a race of four laps against the eleven other drivers.

The select screen: twelve faces and five course pictures
The select screen. A cursor runs along the twelve faces on its own, the stick moves the highlight between the five courses, and fire picks both.
The start of a race on course A
The start of the first race of course A. The panel along the top shows the twelve faces in race order, the time, the score, the stage, the lap and the speed.

The track climbs, drops, banks into bends and jumps gaps. A kart that leaves the road on a raised stretch falls off and is dropped back onto the track, which costs time; one that hits the roadside scenery or runs into a slower kart spins out. Each race has three places on the podium. A player who takes one goes on to the next stage, and once rivals have taken all three, the game is over.

Power Drift was Sega's arcade game of 1988. Chris Butler wrote this version for Activision in 1989; the copyright line on the select screen names Activision, Sega and him, and that is the only credit the program holds.

02 · Music

Music: the game's own driver plays both tunes

The game holds two tunes. The race tune plays through every stage, and the other plays while a high score's name is entered.

The game's own sound driver runs on the site's model of the 6502 processor, from the listing's bytes. A button starts a tune as the game does, with the tune's number in $B804 and a call to sound_reset ($B80A), then calls sound_play ($B800) once a frame, as the race's interrupt does. test_music.js runs the game's own code beside it on the kit's simulator and checks every write to the sound chip, frame by frame, for 3,000 frames of each tune. The bass of the name-entry tune, on the second voice, stays between 46 and 220 Hz, and the race tune's goes down to 82 Hz: laptop and phone speakers barely play notes that low.

Numbers written with a $ are addresses in the computer's memory, in hexadecimal; each one links to the game's code on the Source code tab. The driver plays the SID sound chip's three voices. Each voice reads an order list, a list of patterns to play in turn (tune_table, $C4BA). A pattern is a run of notes, each a note number and a length, and of commands, each $FE and a number: change the instrument, slide the pitch, add vibrato, sweep the pulse width (which changes the tone's colour), or end the pattern (command_table, $BBFB). An instrument is a short list of waveforms, stepped once a frame (wave_tables, $C241). The chip's filter is never used.

The select screen is silent. Its interrupts never call the driver; only the race's interrupt ($5253) and the text screens' ($5181) do.

03 · Sound effects

Sound: four effects, two of them never heard

The driver stores four sound effects and plays them on the third voice. The game starts only two.

The same driver as the music, from the listing's bytes. A button leaves the driver as the game does before the select screen, with the music off, and writes the effect's number to sound_effect ($B805), as the game does. test_music.js checks these buttons against the game's own code as it checks the tunes. The spin's effect repeats its last note until kart_spin ends it as the spin stops, so here it plays until it is stopped.

The game writes $B805 in three places: 2 when the player's place changes (update_place) or a rival comes alongside (rival_near), and 3 when the kart spins (kart_spin). Effect 1 has no writer at all. Effect 4 is a steady tone with a sweeping pulse, which starts itself again whenever it ends; it sounds like an engine. Only starting effect 4 sets the flag at $B808 that keeps it going, and only a routine nothing calls clears it (sound_engine_off). So the game carries an engine sound it never plays.

04 · One frame

One frame of a race, drawn from memory

The race screen is two screens in one: a panel of five text rows at the top, and the view under it.

Both pictures are drawn on this page by the site's model of the C64's video chip, from a record of one whole frame in the emulator: memory as the frame began, and every write to the video chip during it, with the line it came on. In both, every pixel matches the emulator's own picture of the frame. Flat road: course B, stage 1, five seconds in, with poplars along the road. Raised track: the same stage later, at 119 km/h, on a stretch built high above the ground.

The panel is rows 0 to 4 of a text screen at $E000, drawn with its own character set, the shapes of 256 characters, at $F000. At line $5A of the picture an interrupt, a routine the video chip calls when it reaches a set line, points the chip at the view's screen and at the race's character set at $F800 (race_irq_view). The sky and the ground are one background colour that a timer changes partway down the screen (irq_handler), and the track's hills move the line where it changes. The karts are sprites, the C64's movable pictures, which lie over the characters.

The view is drawn into one of two screens while the other is shown, and the two swap when a picture is done (race_frame_loop). A whole picture takes about three video frames, so the race moves about 17 times a second.

05 · The view

The roadside is cut out of a sheet of characters

The view is a screen of text characters. Each object beside the road is a block of them, with a picture of its own for each of 16 distances.

Each picture is drawn here from the game's own tables. scenery_pictures ($3E0B) gives each of the 24 kinds of object 16 records of four bytes: a width and a height in characters, and where the top-left character sits in the tile sheet ($6E00-$B7F5), whose rows are 256 bytes apart. The character shapes are the race set's, with the block of 175 characters the stage loads before the object first appears, and the colour is the object's own (scenery_colours). A character 0 is left out, as the game's copying routine leaves it out. The colours are those of course B, stage 1.

Each picture of the view is built in the same order. clear_view fills the screen with the sky character. draw_horizon_rows copies in the stage's two horizon pictures, 40 characters of each from a picture 80 wide, starting at a column that moves one place for each step of a bend, so the skyline turns as the road does. draw_road draws the road a row at a time from the bottom up. Last, draw_scenery draws the objects, far ones first so that near ones cover them. Every object is copied out of the tile sheet by one routine, draw_tiles, which leaves out the empty character 0, so an object's shape is cut round its outline.

The scenery moves in four slots, each holding up to three objects: one left of the road, one over it and one right of it. A slot starts at distance 15, the farthest, and comes one step nearer with each step along the track (scenery_tick). When it passes the kart, it takes the next record of the stage's scenery list (scenery_list_next). The list can also name a block of 175 character shapes, which is copied into the race set when the list reaches it (chars_5820 and three more), so a stage can change from one kind of roadside to another partway round.

At distance 0 the objects are level with the kart, and drawing them is also the test for a crash (draw_scenery). An object on the right that covers column 21 spins the kart out, and so does one on the left that starts left of column 18 while the kart is off the left side of the road.

06 · The road

Every hill is a list of road widths

The road is drawn from the bottom of the screen up, one character row at a time. A list gives each row's width, and a hill is a different list for every step.

The flat road, drawn from road_flat_widths ($462F): nine rows of 34, 30, 26 and so on down to 2 characters, then 0 to end the list. The road's middle is shifted on each row by the bend and by where the kart is across the road, and the edges are drawn by ten small routines, chosen by how far the edge has moved since the row below (road_left_edge, road_right_edge).

A stage's track is a list of pieces (track_a1 and the 24 lists after it), each the address of a short routine that runs for a number of steps. A step is a fixed distance along the track, and a lap is about 400 of them. A straight runs for 4 or 16 steps and changes nothing. A bend takes 10 steps, moving the bend one notch a step towards the left or the right; a bend is nine notches either way, so it takes one piece to turn into a bend and another to come out of it. A climb, a crest and a descent point the road's three lists, of widths, of the rows the scenery stands on and of the heights of the karts, at a new set on each step, and move the horizon. A crest can hide rows of the road: a width of $80 marks a row behind the brow of the hill.

A climb also raises the track. From its twelfth step a count at $53D4 goes up one a step, and while it is above 0 a kart that leaves the road falls off. The kart is lifted back onto the track from the top of the screen, at 70 km/h (drop_kart_back). A jump is a crest with a gap in the road: from its 7th step to its 21st the kart is in the air, and a kart slower than speed level 10 on any of those steps falls (piece_jump). The Tracks tab draws every stage's pieces.

07 · The karts

Eleven rivals share four sprites

The C64 shows eight sprites at once. The player's kart takes four of them, and the other eleven karts take turns with the remaining four.

A rival at each of its 32 distances, drawn as the game builds it in place_rivals: the first sprite from rival_pictures ($3B43), and the others the routine for that distance adds (rival_picture_routines), 24 pixels apart and the head 21 lines above. The height on the screen is the flat road's, from road_flat_kart_heights ($4649). Distance 0 and 1 use the player's own kart pictures and the driver's own head from behind; here the head is the first driver's.

The player's kart is a head and three body sprites, set once a frame by a timer interrupt (sprite_band_irq). The rivals are up to twelve records of a position, a picture and a colour, built each race frame by place_rivals, sorted from the top of the screen down (sort_karts) and copied where the interrupts read them (copy_kart_sprites). Down the screen, an interrupt (kart_mux_irq) puts the next record into the next of sprites 4 to 7 just after the one before has been drawn, so one sprite can show several karts in one frame.

A near rival takes four records: three for the kart and one for the head. Up to distance 11 a rival takes two, and from 12 on, one. A rival at distance 1 in front of the kart, and slower than it, spins the player out (place_rivals). The rivals keep their order of speed: rival 0 tops out at speed level 30 and rival 10 at 12 (rival_top_speeds). The player's kart reaches 32 in high gear, the fastest on the track.

08 · Speed and time

Speed levels of 7 km/h

Up on the stick adds a speed level every other race frame. The read-out adds 7 km/h for each level.

GearTop levelTop speedHow it gains
Low18126 km/ha level every other race frame
High32224 km/ha level one race frame in four below level 14, then every other

From move_player and speed_up. Seen in the emulator: level 18 read 126 km/h, level 17 119 and level 10 70.

Fire changes gear, once a press (gear_change). With neither up nor down held the kart slows a level every other race frame, and twice as fast with down held. Off the road, above level 3, it slows whatever the stick says. Each race frame adds a quarter of the speed level to the score (add_speed_score), so a fast lap scores more than a slow one.

The clock counts race frames, not time. A digit after the seconds goes up every other race frame and runs from 0 to 5, so a second on the clock is 12 race frames (race_clock). The race makes about 17 race frames a second, so the clock gains on real time; the Discoveries tab has the figures. At the end of a stage won, the seconds on the clock decide a time bonus, which the game counts out in the wrong number system.

09 · Places

Three places on the podium, and the game ends when they are gone

Each race has three places on the podium. Once rivals have taken all three, the game is over, wherever the player is.

Three karts stacked above the road, each with a driver's face
The player has finished third. The three finishers stand one above another over the road, the first at the top, each with its driver's face from the front.

Each race frame update_place works out the player's place from the rivals' laps and positions. The rivals keep their order of speed, so it only has to look from the slowest up for the first rival ahead. A change of place starts a sound and swaps the player's face along the row of faces on the panel (show_place).

Every kart that finishes its fourth lap takes the next of three places on the podium (place_finisher): its kart and its driver's face appear over the road, with the place written across the top of the face. When the third place goes to a rival, the game is over (game_over). When the player takes a place, the stage is won (stage_won), and after the fifth stage of a course the screen says CONGRATULATIONS (course_complete).

When the player finishes, the slowest rival, rival 10, is given the player's lane, speed and colour, and the player's own sprites are pointed at an empty picture (move_on). So the kart seems to drive on up the road while the view stays where it is.