Inside ScummVM: Classic Adventure Engine Overhaul

ScummVM is a game engine emulator that
lets you play classic LucasArts adventure games, like The Secret of
Monkey Island, Day of the Tentacle, and Sam and Max Hit the
Road, on the Linux, Mac OS, PocketPC, and current Windows
platforms. There's even a version for Sega's defunct Dreamcast game console and
a Playstation 2 port in the works. ScummVM works by emulating and improving
upon the SCUMM ("Script Creation Utility for Maniac Mansion") engine
that LucasArts used to run these games.

Started in September 2001, the ScummVM project caught the ire of LucasArts
due to concerns by the company over ScummVM being released under GPL. As of
this writing, the two sides are deadlocked over this issue. The ScummVM
developers encourage users to purchase legal copies of LucasArts SCUMM games.
ScummVM reads the data from the original disks or CD-ROMs in order to run the
games; but, as is the case with most emulators for other game engines, pirated
copies of this data work equally well.

After this interview was conducted, but before it went to press, ScummVM
versions 0.50 and 0.51 were released. These new versions add support for
Adventure Soft's Simon the Sorcerer 1 & 2 as well as Revolution Software's Beneath a Steel Sky. In return for ScummVM's support, Revolution has allowed the project
to distribute the game freely.

Who's Behind It?

Ludvig Strigeus is a 22 year old computer science student
by day. He lives in Gothenburg, Sweden. Ludvig wrote the initial version of
ScummVM.

James Brown is a 20 year old programmer, living in Perth,
Western Australia. He is the current Project Leader of ScummVM. In his words,
"I think, because nobody else wanted to be woken up by LucasArts' legal department at 3 AM."

Max Horn is a 23 year old math and computer science student in Darmstadt, Germany. He contributed the initial support for Curse of Monkey Island as well as many bug fixes and the in-game GUI.

Torbjörn Andersson, 32, is a programmer in Säffle, Sweden. He concentrates on "fixing little things, bugs or features that may not be essential, but which make things look and sound a bit more polished."

The Developers Speak

O'Reilly Network: What's your motivation for taking part
in the ScummVM project?

Ludvig Strigeus: My first involvement was when I got an
idea to write my own adventure game engine a few years ago. To be able to do
this, I wanted to know about the internals of SCUMM, so I could borrow ideas
from there. I got an idea in my mind that I should make an interpreter [for
ScummVM] capable of playing Monkey Island 2, so I re-opened my old
disassembly and started working with it.

James Brown: Although the concept had been proven when I
joined the project, ScummVM has always been a learning experience, and
fascinating at times. Not only am I learning new techniques and methods of both
programming and reverse engineering, but we get a rather unique opportunity to
study the techniques of the programmers we am trying to emulate and
figuring out ways to improve on their original methodology and techniques.

ORN: What languages have been used to develop ScummVM?

JB: ScummVM started off as mostly plain C, wrapped inside a
few C++ classes. Soon after I took over, we switched to C++ proper.

Personally, I have no particular like for C++. I find it tends to produce
"spaghetti code" by people abusing inheritance and object orientation. I prefer
straight ANSI C any day. However, as we were trying to add support for many new
games and platforms, the object inheritance properties of C++ do make the code
a lot more readable.

For example, we have recently been working on emulation for the Curse of
Monkey Island, which uses Version 8 of the SCUMM system. We decided this
version was different enough to warrant implementing "version classes". So now
we inherit the script opcodes and resource management functions from our
Version 6 class, and simply replace the ones that are substantially
different.

Perl has been used, at various times, to prototype and test various
functionality. Also, we have used information gleaned from programs written by
other people in the community, especially by somebody known as Serge,
which were written in Delphi. And, naturally, x86 assembly, from our
reverse engineering.

ORN: What code does ScummVM incorporate which the team did
not originally develop?

LS: ScummVM uses SDL, which is a library that makes
it easier to write cross-platform sound/graphics code.

Torbjrn Andersson: The ALSA MIDI driver is mostly
cut-'n-pasted from vkeybd by Takashi Iwai, and that part of the
sound code is an LGPL-licensed version of MAME's fmopl by
Tatsuyuki Satoh.

JB: We use Kreed's 2xSaI family of
graphics scalers. We also use Ogg Vorbis and the MAD MP3 library to provide audio compression, mostly to make it easier to fit games onto portable devices
such as the iPAQ.

It might sound somewhat hypocritical, as ScummVM is an emulator, but there
is no point reinventing the wheel. It's far easier to take advantage of other
existing code and concentrate on the guts of the engine.

ORN: What have been the outstanding technical challenges
throughout the development of ScummVM?

Max Horn: To write a single engine that emulates the
behavior of different versions of the SCUMM engine, each with its own sets of
quirks, modifications and oddities.

A fix for one thing often will break five others, and sometimes you only
notice this a month later, making it hard to track down the cause. Then you
have to improve the original fix so it still fixes the problem without causing
new ones.

JB: One of our major goals is to remain as portable as
possible. We still have a long way to go, as our memory usage is quite
unoptimized at the moment; several people have tried to fit ScummVM
onto a Gameboy Advance, which has only 288K of actual program memory.

Given that we are dealing quite often with strange compression codecs—which, while reasonably simple to reimplement, can be hard to actually
comprehend—platform specific tweaks can become a great hurdle.

ORN: What have been the unique programming challenges in
reverse engineering the SCUMM engine?

LS: There's the technical challenge of analyzing an
.exe file, and reconstructing program logic from that. When a
program is compiled, the names of all variables and functions are lost. To
reconstruct those, you need to analyze the functions and see patterns to be
able to understand what the disassembly does and how it works.

Another technical challenge is the problem of supporting multiple
interpreter versions from a single source code tree. Each SCUMM game uses its
own version of the interpreter and expects certain things to be in certain
ways. So you need to find a common denominator of features that all interpreter
versions use, and then extend this with more interpreter-specific
features.

I can't say that I'm completely happy with how this has worked in ScummVM
during the time that I was involved with the project. Often a feature added to
support a newer game broke something in older games. When it comes to game
compatibility, ideally, each interpreter version in the code tree should be
independent of all the other ones. But that would require too much maintenance,
partly due to the fact that for each interpreter version, you would have to
duplicate all functions and, thus, the code tree would grow enormously.

JB: Implementing so many different minor versions is quite
hard, as there can often be major structural, if not functional
changes. That makes it difficult to find common points in code for
comparison.

Most game engines will have these problems, combined with the fact that,
when you are dealing with interpreted engines, you never can quite be sure what
tricks the scripters have done in the game code that might trip up your engine.
Writing a script decompiler should be your very first step, and making sure it
is flexible enough that you can correct opcodes on the fly and easily integrate
changes in arguments and parameters into your in-engine interpreter.