ResidualVM contribution

residualvm-logoGrim Fandango was one of the greatest adventure games from LucasArts, and probably the most underrated of its time. The quality of game design and the art direction is remarkable, but mixing 2D pre-rendered backgrounds with 3D characters always has its disadvantages: objects are “falling off” the screen, the jagged edges of dynamic objects tell you right away which parts of the game world you can interact with.

When playing the original I never understood why there wasn’t an option to apply antialiasing to the polygons, so I went into the control panel and forced antialiasing on. It looked a LOT better and even though my computer was well below average, thanks to the extremely limited number of polygons displayed per frame, it ran perfectly smooth. The objects blended in nicely with the backgrounds.

Grim Fandango with and without antialiasing

Grim Fandango with and without antialiasing

There was only one issue with it: the original developers tried to do some clever stuff to only re-render parts of the frame that’s changed. So it seemed like if something moved, they just drew the background over the affected rectangle and rendered the object again. Due to the forced antialiasing though, it sometimes underestimated the affected area of small moving objects and their edges littered the screen. I still preferred to play like that, even if it made the pigeons ugly.

When the original binary version started struggling on newer versions of Windows, I was overjoyed to find ResidualVM, an open source engine reimplementation using the original data files. You can find the code repo on GitHub.

I signed up for a GitHub account and created a quick patch to add antialiasing. As ResidualVM uses SDL, it was very easy to add:

if (ConfMan.hasKey("antialiasing") && ConfMan.getInt("antialiasing")) {
	// Antialiasing works without setting MULTISAMPLEBUFFERS, but as SDL's official
	// tests set both values, this seems to be the standard way to do it. It could
	// just be that in current OpenGL implementations setting SDL_GL_MULTISAMPLESAMPLES
	// implicitly sets SDL_GL_MULTISAMPLEBUFFERS as well.
	SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1);
	SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, ConfMan.getInt("antialiasing"));
}

It was all looking good and worked perfectly, until one day I received a crash report traced back to my commit. Someone switched antialiasing on in the config file with an unsupported value under Linux, and ResidualVM just exited when it couldn’t initialise the video mode.

I thought I should just query the available antialiasing modes before init, the problem was that you can only enumerate the available values after you have an OpenGL context open. As quickly destroying and re-creating OpenGL contexts via SDL was just crashing all over the place, I eventually settled on an easier solution.

At the moment it doesn’t care about the available modes, it just tries the following modes in order, failing over to the next one:

  1. 32-bit with AA
  2. 32-bit without AA
  3. 16-bit with AA
  4. 16-bit without AA
  5. Exit with failure

It’s not as elegant, but works well enough for a so far undocumented feature.

You can find the commit details here. This concluded my first ever contribution to an open source game engine.

Share Button
Posted in Blog Tagged with: , , , , ,

Leave a Reply