1985 · Datasoft

The Goonies

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

A packed picture from the disk for each scene, and every moving thing drawn into it by hand: no hardware sprites, two bitmaps taking turns, and the same four colours on every screen.

The colours

Every scene is drawn in black, red, blue, and white

The screen is a multicolour bitmap, where each pair of bits picks one of four colours for a double-width pixel. Three of the four come from the screen matrix and the colour RAM, which can differ for every 8 by 8 cell, and most C64 bitmap games use that to put many colours on screen.

The Goonies fills every cell with the same three. fill_screens ($691E) writes $26 into every byte of both screen matrices, which gives red and blue, and fill_colour_ram ($6905) writes 1, white, into the colour RAM. With the black background, those are the only colours any scene can show. Only the two status rows differ, filled with $3C for the score's cyan and grey.

Because every cell has the same colours, a shape can be drawn at any position without clashing with the cells around it. The reviewers noticed the price. ZZap!64 complained of "a distinct lack of colour, with only four used!"3

Two bitmaps

The game draws into one bitmap while the other is on screen

The game keeps two complete screens, one in each of the video chip's first two banks: the screen matrix at $0400 with the bitmap at $2000, and the screen matrix at $6000 with the bitmap at $4000. Each pass the main loop draws the next frame into the one not shown, then asks for a flip ($12C8), and the raster interrupt at line $FB (irq, $0A03) switches banks in the bottom border, after the visible screen has been drawn.

A pass takes four frames, so the picture moves at about 12.5 frames a second on a PAL machine. The player never sees a half-drawn frame, because the bitmap being drawn is never the one on screen.

Software sprites

Every Goonie and creature is drawn into the bitmap and rubbed out again

The game uses none of the C64's hardware sprites. Everything that moves is a shape drawn into the back bitmap by draw_shape ($6D4E), and every pass it is rubbed out and drawn again at its new place.

A shape is a width in bytes, a height in lines, and then its bytes, line by line. Each byte goes through a mask before it is drawn. build_mask_table ($6F51) builds a 256-byte table at $6400 that gives, for every byte value, the bits to clear in the bitmap: both bits of every pixel the shape colours, and none of the black ones. The black pixels of a shape are therefore see-through, and the scenery shows around a Goonie's outline.

Before it draws, draw_shape saves the bitmap bytes the shape will cover. Each bitmap has its own save area, from $F900 and $FC00, and a list of what was saved ($131E). The next time that bitmap is drawn into, erase_sprites ($6E23) walks its list from the last entry back to the first and puts the saved bytes back, leaving the clean picture to draw the new frame into.

The shapes

A shape moves eight pixels at a time unless it has copies

A byte of the bitmap holds four pixels, each two bits wide on the screen, so a shape drawn at a byte boundary can only be placed every eight screen pixels. To move more smoothly, a shape needs copies of itself drawn shifted inside its bytes.

The shape table at $70BE gives each of its 58 shapes four pointers, one for each value of the two low bits of an object's x position, which is counted in units of two pixels. draw_object ($0C8A) takes the pointer the low bits choose and draws that copy at column x divided by four. How finely a shape moves depends on how many different copies its four pointers name:

ShapesCopiesStepWhich
15four, two pixels apart2 pixelsshapes 30 to 42, 48, and 57, among them the bird's six frames
6two, four pixels apart4 pixelsthe two Goonies standing still, and shapes 26, 28, 29, and 55
37one8 pixelseverything else, the walking Goonies among them

Shapes 0 to 15 are the scene's two Goonies, eight frames each: walking right, walking left, climbing, standing, and swimming. The game holds seven Goonies, each a different child, in seven blocks of shape pointers at $B797-$B996. When a scene loads, load_scene_graphics ($6F7A) copies the scene's two blocks (scene_shape_blocks, $7049) into the start of the table, so the pair of Goonies on screen changes from scene to scene. Scene 8 breaks the pattern: its start routine draws the second Goonie from shapes 49 to 56 instead ($9D63), a figure about three lines taller than any of the children. Shapes 16 to 57, the creatures and the other things that move, stay in place for the whole game.

Every shape in the table for the chosen scene, drawn from the game's bytes at three times size. The colours here are the game's four. Show all four copies draws the copy for each value of the two low bits of x side by side, so a shape with one copy appears four times unchanged.

The walk

A walking Goonie's two frames are half a byte apart

A walking Goonie has one copy of each frame, so by the table above it should move eight pixels at a time. It moves four. goonie_frame ($0C36) picks one of two walking frames by bit 1 of the Goonie's x position, and the second frame is drawn four pixels further right inside its bytes than the first.

A Goonie walks two units, four pixels, a pass. On one pass the first frame is drawn at a byte boundary, and on the next the second frame is drawn from the same byte, its figure four pixels further on. The walking animation and the half-byte step are the same two frames.

A Goonie walking right, drawn the way draw_object draws it, one pass at a time. The grid marks the bitmap's byte columns, eight pixels apart, and the yellow mark is the Goonie's x position. The frame changes every pass and the column every other pass.

The pictures

Each scene's picture is packed on the disk and loaded when the scene starts

The code, the collision maps, and the shapes of every scene are in memory from the start. The scenery is not: load_scene_graphics loads the scene's picture from the disk each time a new scene begins.

The picture arrives packed at $4140. unpack_picture ($7071) unpacks it into the bitmap at $2140 with a simple run-length code. A count with bit 7 set repeats the next byte that many times (the count less $80), a count below $80 copies that many bytes as they are, and a zero ends the picture. The unpacked picture is then copied into the second bitmap, and the scene's shapes are drawn over both.

The disk loader lives in the first bitmap's top rows while it works, at $2000. Between loads the game keeps a copy of it in the RAM under the I/O chips at $D800, and copies it back before each picture loads. When a disk read fails, the status line shows DISK ERROR.