Skip to content

Animation engine, .gif processing pipeline, play as a cat

Pre-release
Pre-release
Compare
Choose a tag to compare
@qguv qguv released this 02 May 23:21
· 118 commits to master since this release

Play this version directly in your browser

It might not look like a whole lot of the gameplay has changed, but this is a huge release in sheer hours spent. There are two major features: a new animation engine and the beginnings of a .gif processing pipeline. I also hacked together sprites that use white as a foreground color. Oh yeah, and you can now play as a cat! Thanks as always to Rachel for the lovely art.

screenshot of the new version, showing a pixel cat standing in a pixel kitchen

Animation engine

The Gameboy's sprite memory (OAM) stores x and y position, the currently displayed sprite index, and some flags regarding mirrored sprites and palettes. There's no information on animation frames, speed, or whether a sprite moves with the background or keeps its relative position on the screen. So to animate the sprites, we have to keep track of all this information somewhere. The animation engine is an attempt to pack it into a single place in working RAM so these parameters can be modified live from anywhere in code.

This has several nice consequences, not least of which is that it's much easier to define new sprites in code; you simply add your definitions to the sprite meta-table, and the engine will handle the initialization and frame animation. Final binary asset includes (e.g. 2bpp images) could be further improved.

The data used in the animation engine comes from the sprite metadata table (SMT) which has a ROM and a RAM component. The ROM component is defined using a macro:

SMT_ROM:
	Sprite lstar_sprite,SMTF_ACTIVE|SMTF_ANIMATED|SMTF_WORLD_FIXED,StarBeginIndex,$5d,$2e,0,8,2,0
	Sprite rstar_sprite,SMTF_ACTIVE|SMTF_ANIMATED|SMTF_WORLD_FIXED,StarBeginIndex,$6d,$2e,OAMF_XFLIP,8,2,4
	Sprite playerHL_sprite,SMTF_ACTIVE|SMTF_SCREEN_FIXED,SadcatBeginIndex+0,$50,$4e,OAMF_PAL1,0,0,0 ; head

On boot, the table is copied into memory: some parameters into OAM, others into the (much smaller) RAM component of the SMT. The vblank interrupt code reads the RAM SMT every ~16.75 ms and updates the animations accordingly. This animates sprites and moves them around the screen to match the movement of the background tiles as the viewport scrolls.

.gif processing pipeline

Rachel likes to make pixel art animations in .gif files. This makes them very easy to preview, but it can make them hard to load. After reading through the imagemagick manual, I came up with some additions to the Makefile that should make this possible.

White sprites

The Gameboy screen can produce four colors:

  • very light green / "white" / pixel off
  • light green / "light gray" / pixel 30% on
  • darkish green / "dark gray" / pixel 70% on
  • black / pixel 100% on

In sprites and background tiles, though, the Gameboy doesn't have a concept of color. It stores each pixel with a two-bit associated value: 00, 01, 10, or 11. You then apply a palette to select the behavior of each of these values in the sprite.

All this is dandy, except that sprites reserve the value 00 to represent transparency. The consequence is that, barring some crazy timing-precise hacks, each sprite can only contain three colors. We can choose which three colors they are, but we're still limited to just three.

Usually, we rely on a program called rgbgfx (which comes with the assembler toolchain we're using) to turn our computer-friendly .png files into Gameboy-friendly raw .2bpp image data for sprites and background tiles. The trouble is that rgbgfx always treats white pixels as 00, just as if they were transparent.

The solution is to fiddle with the picture beforehand using imagemagick so that the image is essentially inverted. As you can see in the link, this is not exactly an elegant Make recipe, but it works for now.

Main character

You can now play as a cat! This is the first frame of sadcat.gif, which is being successfully loaded into Gameboy tile memory! This cat is sad, but I'm not!

a sad-looking pixel cat, sighing

Next up: star̀ing͞ ͜in͟to͟ t͌̍̆̃ͩ̀h̗͉̰̤̺ͧẻ̮̃́̚ ̗͙v̈̇ͅö̳̳̩̳́̊ͩͥi̛̩̳͈͖͇͂̈̋͒͂͑ͅd̵͖ͭ͊.͚̙