1994 · Psygnosis

Lemmings

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

The cave on the Commodore 64 is made of sprites: eight of them, stacked eight times down the screen by raster interrupts. The lemmings are drawn into characters, a fresh set every pass.

01 · The game

Lemmings, on three disks

E&E Software's conversion of DMA Design's puzzle game: 100 levels in four ratings, Fun, Tricky, Taxing and Mayhem.

Lemmings drop out of a trap door and walk, whatever is ahead of them. The player cannot steer them. Instead they hand out skills one lemming at a time: a climber, a floater, a bomber, a blocker that turns the others round, a builder of stairs, and three ways through the ground, the basher, the miner and the digger. A level is won when enough of them walk into the exit before the clock runs out.

The Lemmings logo above five lemmings holding signs: 1 Player, Intro, New Level, a music note, and Fun with arrows

The title menu, with its credits in a scroller along the bottom.

Lemmings walking on a grassy ledge in a cave, above a panel of skill icons

Level 1 of Fun, "Just dig!", thirty seconds in. Ten diggers are on offer.

The boot disk holds the intro, the title menu and the play engine. Each rating's 25 levels are on a side of their own, disk 2 side A for Fun to disk 3 side B for Mayhem. Every level is a file that carries its own map, its own briefing and the access codes that lead to it and from it. The Maps / levels tab draws all 100.

02 · The play screen

A cave made of sprites

The terrain is eight multicolour sprites side by side, moved down the screen 21 lines at a time. The lemmings, the cursor and the panel are characters.

Drawn by this page from one recorded frame of level 1 (kit/c64/frame.py): the video chip's registers as the frame began, all 166 writes to them and to the sprite pointers in the frame, each at its raster line, and the memory the chip read. Redrawn with the site's model of the video chip, all 104,448 pixels match the emulator's picture of the same frame. The boxes follow the sprites' Y registers through the frame: orange for sprites 0-3, blue for 4-7, grey for the panel's.

Sprites 0 to 3 cover the left half of the play area and sprites 4 to 7 the right, 24 pixels apart. Each half is moved down 21 lines at a time, so eight rows of eight sprites cover the 168 lines of the cave. The two halves are 8 lines out of step, and the interrupts alternate between them: on line 60 the handler moves sprites 0-3 down below the rows still being drawn (band_first, $0935), and from then on each interrupt points one half at the next slice of terrain and moves the other half down (band_a, $093B, and band_b, $0956). A table of 17 raster lines drives them, 251, 60, 71, 79 and on to 217 (band_lines, $09F3), every 8 and 13 lines by turns.

The whole level is kept as sprite shapes, 13,104 bytes from $8000, laid out by the level's own unpacker so that each column of the level sits where a sprite expects it. The sprites show 64 shapes at $6000-$6FFF, and as the view scrolls a column of the level is copied in (scroll_view, $0C90). Moving the eight sprites' X positions does the fine scrolling (scroll_sprites, $0CDF). A lemming that digs or builds changes the level's own copy and the shown one at once (terrain_write, $2930).

The sprites run 24 pixels wider than the play area, and the screen's characters cover the edges. The sprites are set behind the characters, so the lemmings, drawn in characters, stand in front of the cave. Character 1, which fills the screen around the play area, covers the sprites where they overhang.

Lemmings in characters

There are no hardware sprites left for the lemmings, so they are drawn in software. Every pass, each lemming takes fresh characters for the cells it covers, up to three rows of two, starting from character 2 (next_char, resident $0422), and its frame is ORed into them (draw_lemming, $1AA2). The cursor is drawn the same way into characters $FC-$FF (draw_cursor, $1916), and water into $F4-$FB (animate_water, $2B96).

The drawing goes into the screen that is not shown. There are two, $4000 with its characters at $5000 and $4400 with its own at $5800 (screen_d018, $1349), so the characters drawn for the hidden screen never change the shown one. When the main loop has drawn one, the interrupt shows it at the next frame, but never sooner than five frames after the last swap (irq_band, $08EA). So the lemmings move at ten steps a second at most, while the cursor and the music keep the full fifty.

The panel

On line 217 the interrupt switches to the screen at $4000 with a third character set, at $7000, for the panel, and puts four sprites over it, one of them the highlight on the chosen skill (band_panel, $0989, and panel_setup, $0A04). At line 251 the frame's first interrupt sets everything back for the top of the next frame and does the frame's other work: the screen swap, the music, the cursor and the keyboard.

03 · Music

Music: eleven tunes on three players

The intro, every level and the end sequence have tunes of their own. The credits name Jeroen Tel, and the play engine's driver carries his name. The end tune, with its sampled applause, has its player in the end sequence's section below.

The game's own players, run on the kit's 6502 through the site's model of the SID with the 6581's filter. The level tunes play on the play engine's driver ($3000), started as play starts them; the intro's on the intro's own driver ($4000). The test beside this page (test_music.js) runs every tune on the simulator as the game calls it and compares every SID write of every frame with the page's.

Nine tunes play in the levels, one to a file of its own, SA to SI, loaded with the level to $3652 (load_level, $5BAF). The play engine's driver reads it through a table of 64 sequences, the tunes' parts and the sound effects together (seq_ptr_lo, $3652). The music starts with the first lemming out of the trap door, which starts sequences 1 and 2 on the first two voices (release_lemmings, $1DD9). With sound effects chosen at the title (key 4), the same driver plays effects instead (play_sound, $29F8).

The driver's text (C) 1993 JEROEN TEL / MANIACS OF NOISE sits at $3009, between its three entry points and its variables. The intro's driver is a smaller relative, without the text, and the ending's a third, with a channel for a sampled sound: an NMI from CIA 2's timer writes four bits at a time into the SID's volume (sample_nmi, ending $0938).

04 · Sound effects

Sound: six effects, one note each

With sound effects chosen at the title (key 4) instead of music, the same driver plays the effects. Each is one note of one instrument.

The play engine's driver, run on the kit's 6502, starting each effect as play_sound ($29F8) does, with the tune file of level 1 loaded; every tune file carries the same six. test_music.js compares every SID write of each with the game's code.

An effect is a sequence like any part of a tune, kept in the level's tune file beside the music: sequences $1A to $1F of the table at $3652. Each is four to seven bytes: an instrument, a length, a note and the end. The instruments, 11 to 15 of the file's set, do the work with their own waveform, pulse and arpeggio settings, so a single note is enough for an explosion. play_sound starts the effect on voice 1 or voice 3 by turns, rewriting its own LDX operand each time, so an effect does not cut off the one before; in music mode it plays nothing. The trap door's creak is the exception: the level start plays it on voice 3 in either mode ($2AB2), and in music mode the tune then starts on voices 1 and 2.

Nothing here is sampled. The digitised voices the developer's diary mentions, "Let's go" and "Oh no", are not in the game part: its driver writes the three voices only, and its NMI vector in play points at a bare RTI.

05 · The lemmings

Twenty-one actions, eight skills

Each lemming is a handful of bytes: an action, a direction, a position and an animation frame.

A level has up to 50 lemmings, each with an action number in the low five bits of lemming_action (resident $0424) and its direction in bit 7. Its X, a 9-bit value, is the level's pixel plus 8, and its Y is the line it stands on. Every pass, move_lemming ($1E94) calls the handler for its action from a table of 21 (action_handler_lo, $1E6A). The Graphics tab plays every action's animation.

Read by this page from the listing: the handler table's 21 addresses and the label each has in the Source tab.

The handlers ask one question over and over: is there terrain at this offset from the lemming? terrain_at ($28E8) turns the offset into a byte of the sprite shapes and masks out one pixel. A level can also mark cells of steel and one-way walls in a separate map, two bits a cell (cell_kind, $2E07).

The keys 1 to 8 choose a skill, + and - change the release rate, SHIFT pauses, and the back arrow ends the level, but only while paused. DEL pressed twice is the nuke, which gives every lemming a fuse (key_action, $0AB4). The joystick in port 2 or a 1351 mouse moves the cursor; the mouse is read through the SID's paddle registers (read_mouse, $1704). RESTORE does nothing in play: the NMI vector points at a bare RTI (nmi_rti, $0B56).

06 · Levels and files

A level is one file that unpacks itself

Every level file brings a 160-byte header, its terrain packed, the routine that unpacks the terrain, and its objects.

Level 1's header, read by this page from the listing (level_header, $E000), where the game part's snapshot has it at the briefing.

The loader stays at $CC00-$CFFF in the resident part for the whole game. A file is asked for by a code byte: its top three bits pick the first letter of the name, F, T, X or M for the four ratings and P, I, C or S for the rest, and the low five bits the second letter. Every byte on the disk is stored EOR the byte before it, and the loader undoes the chain as it reads, by rewriting the operand of its own EOR (resident $CEAA). Then it unpacks: bytes below $E0 are copied, and codes from $E0 up repeat a byte or fill memory to an address (resident $CC8D).

A level's own routine at $E094 unpacks the terrain the same way to $7E00, then rearranges its 78 columns by 168 lines into sprite shapes at $8000 (unpack_terrain). The briefing then checks that the file it loaded carries the access code the menu expects, and stops the machine with a red border if it does not (show_briefing, $526E; see Discoveries).

07 · The code sheet

320 numbers from one addition

Before the title, the game asks for a number from a page of the manual, picked by the lemming picture on that page. The manual's sixteen tables follow a rule.

Drawn and computed by this page from the menu's bytes: the page's picture, four sprites from $A400, and the twenty numbers by the game's own rule (choose_question, $9EF6). Click a number to see the question that asks for it. The test beside this page runs the game's code for all 320 and compares; the sixteen tables in the manual hold the same numbers.

Each page's first number is in a table (page_first_lo, $A070). Every number after it is the one before plus 23,171, less 56,831 whenever the sum reaches 56,831. So the manual's 320 numbers are one sequence the code works out on demand, and the disk carries 32 bytes of them. The question's page and line come from mixing the raster line over 256 reads, which changes with every boot. The answer is typed as five digits and compared with the number the game worked out ($A1AC).

Typing the access code at the title (option 3) skips to any level. The codes for all 100 are in the menu, ten letters each, every letter EOR the one before it (access_codes, $9701), and in each level's own header.

08 · The intro

Lemmings in pairs of sprites

Five pictures, each unpacked from the files IA and IB, with lemmings that walk, float down under umbrellas and climb.

A hot-air balloon over snowy mountains, with lemmings floating down under umbrellas

Scene 1: lemmings step out of the balloon's basket.

A lemming floating down under an umbrella in front of rocks under a red sky, two lemmings walking on the grass

Scene 2: floaters land and walk off.

Each lemming in the intro is two sprites in the same place: a hires sprite in black for the outline over a multicolour sprite for the body, which gives it more colours than one sprite can have. Sixteen sprites make eight pairs. Pairs 0 to 3 are put on the hardware directly, and pairs 4 to 7 reuse the same sprites further down the screen: they are sorted by height and each gets a raster interrupt two lines above it (build_bands, $581B, and sprite_band_1, $58DE).

Each actor follows a script of a few commands: a jump, a speed across or down, a position, and frames that last a number of steps (read_script, $5554). A step comes every fourth frame. The lemming images are 148 packed streams, unpacked into one of two buffers as an actor needs them, while the interrupt shows the other (show_image, $4EAA). Fire on the joystick skips the intro.

09 · The end

The end sequence: a photograph and an applause

After level 25 of Mayhem the loader fetches one more file, IC, and runs it at $C400.

A multicolour bitmap of five people in a row with a green-haired lemming held up among them

The end picture: five people with a lemming among them, a still multicolour bitmap (end_bitmap, $A000).

The picture is a plain multicolour bitmap in video bank 2, with its colours copied into colour RAM (end_picture, $C45B). The sequence lasts 2,592 frames, about 52 seconds, or until fire is pressed, and then the game starts again from the title (end_loop, $C415).

Music: the end tune and its sampled applause

The ending's own player, run on the kit's 6502, with CIA 2's timer counted down in the page and the game's interrupt handler run at each tick: 132,287 writes to the volume register in the 52 seconds. The site's model of the SID hears them as a 6581 does, by the level the volume scales when no voice sounds. test_music.js runs the same code on the simulator with a timer of its own and compares every SID write.

The tune's three voices play from the frame routine (end_tune_frame, $0994), but the volume is the sample's. The SID has no channel for a recording, so the ending plays one through the master volume: CIA 2's timer A raises an NMI at the sample's rate, 1.8 to 9.8 kHz by the note (sample_rates, $10CD), and each time sample_nmi ($0938) writes four bits of the recording into the low nybble of $D418, the high half of a byte, then the low. On a 6581 every volume step moves the chip's output, so the steps are the sound. The sound takes most of the file: about 30,000 bytes from $1500 to $886E. The frame routine never writes the volume itself, and the silence routine leaves it at 0, so without the interrupt the whole tune is silent. The screen before it promises "a huge applause".