Inside ScummVM: Classic Adventure Engine Overhaulby Howard Wen
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
vkeybd by Takashi Iwai, and that part of the
sound code is an LGPL-licensed version of MAME's
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.
Pages: 1, 2