19

This pillow fighting game set in Venice depicts the two opponents fighting on a wobbly gondola on a canal. It was apparently known as "Pillow Fight" in English and as "Kissenschlacht" in German, and was part of a bundle called Alternative World Games.

enter image description here

I'm interested in the splashing water in the canal. That animation is five frames long; I have extracted the frames and cropped a small area. Most areas have five colours: white, gray, dark blue, and light blue. One of the blues is presumably the background colour, being shared with the sky. The shadow under the boat appears to replace the white by black.

Frame 1 Frame 2 Frame 3 Frame 4 Frame 5

I'd like to know how to do that. The problems I foresee:

  1. It doesn't seem to be tileset-based because the region does not fit the character cells.

  2. It doesn't seem to be sprites because it's wider than eight sprites put together.

  3. I don't think it's bitmap because it's moving too quickly for the 6502 to update the whole thing in time.

  4. doesn't seem to be a trick with the palette because there are more frames than possible colours in a multicolor image.

Well I think we've run out of (reasonable) options, so I guess I'm wrong somewhere! So does anyone know how this was accomplished? I'd very much appreciate:

  • An educated guess on how this could have been done.

or

  • A source/disassembly on how this actually was done.
  • 2
    what lets you assume (4)? - Just from the top of my head, I would exactly assume it's done like that. – tofro Sep 11 '18 at 13:01
  • @tofro It doesn't look that way to me. Essentially, if it was a palette trick, I'd expect to see at most three different frames because a multicolor palette has three colors other than the global one. But look at the bottom left: it's got maybe five frames, in a character cell that also contains black. – Wilson Sep 11 '18 at 13:08
  • 1
    The pattern repeats every 5 frames, and seems to be made of 4 colors: white, gray, dark "blue" (indigo?), and light blue. Blotches of a given color don't appear as other colors in other frames, so I think you're correct to rule out a palette trick. – DrSheldon Sep 11 '18 at 16:54
15

I had a brief look into the game running in an emulator. The pillow fighting game is using the multicolor bitmap mode. In this mode, the video screen RAM defines the colors for the bit patterns 01 and 10, which are set separately for each 8x8 area with one byte each. The area filled with water has only around 100 bytes for color definition. These bytes are constantly changed so that the same bitmap has a different look, in this case by switching between colors dark gray, mid gray, light blue, light grey and occasionally white on some areas. This creates the water animation effect. In the game, there is a copy loop to overwrite the values in the video screen RAM which is set to be between $5C00 and $5FE8.

If speed is a concern it would have been also possible to achieve the same effect by preparing several screens with the different colors and switching between them via the VIC memory control register at $D018, however this would have required an extra kB of memory for each frame and copying the sprite pointers around.

7

Like the Atari 2600, it recalculates each scanline right before it is drawn

By reloading the VIC-II's control registers via machine code hooked into the raster interrupt routine (the scanline interrupt), one can program the chip to generate significantly more than 8 concurrent sprites (a process known as sprite multiplexing), and generally give every program-defined slice of the screen different scrolling, resolution and color properties.

[...]

Utilization of raster interrupts is an essential part of C64 game programming.

https://en.wikipedia.org/wiki/MOS_Technology_VIC-II

I speculate that this game is installing its own raster interrupt handler. However, instead of manipulating the sprites (as the Wikipedia article suggests), the handler actually recalculates the background for just that scanline. It's not a lot of pixels, it can be done fairly quickly, and there are probably plenty of shortcuts to speed up the calculation. The players are probably drawn by sprites.

This is basically how the Atari 2600 game console drew the screen. The 2600 did not even have enough RAM for the whole screen -- just enough for the next scan line! So at the end of each line, it would quickly calculate the contents of the next scan line. Clever, but a pain to program!

  • You reckon it's basically copying a bitmap into that region then? what about the fact it's got the five colours you mentioned in your comment? – Wilson Sep 11 '18 at 18:05
  • I suspect it's more than a simple copy. It knows which scanline it is on, and it draws the appropriate part of the boat/shadow if those belong on the current scanline. Kind of like how the 2600 drew the edible dots in PacMan; it's a background feature that whose presence can be quickly calculated and rendered as needed. – DrSheldon Sep 11 '18 at 18:37
  • 4
    I'm unclear why you'd go to the effort of racing the beam in order to output bitmap graphics on a C64 where there is enough storage for a frame buffer? – Tommy Sep 12 '18 at 2:21
  • It may not involve copying a bitmap. The 6502 is too slow to do that every scanline because even sta $address is four cycles, and only stores four pixels, by which time twelve pixels have elapsed. Possibly it's overwriting some kind of tileset though. That could be done in time. But there would be no point. – Wilson Sep 12 '18 at 11:13
  • 1
    Another way to do it would be to have a very tall bitmap in video memory, precomputed with every possible line. Some screen lines (e.g. top half of screen) need only one bitmap line, animated lines need 5, the boat probably needs more than 5. Then during the raster interrupt, you adjust the vertical origin register appropriately, and the video chip does the hard work for you. – DrSheldon Sep 12 '18 at 13:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.