Feature

SCUMM5-Amiga: Monkey Island 2 VGA on a Real Amiga 1200

How I brought the original 256-color VGA version of Monkey Island 2 to a real Amiga 1200, developing a native SCUMM5 interpreter for the AGA chipset with OpenAI Codex.

Eleven Floppy Disks and a Dream from 1992

Monkey Island 2: LeChuck's Revenge was released for MS-DOS in 1991 and arrived on the Amiga around the turn of 1991 and 1992. It was one of those games that highlighted the growing gap between PC VGA graphics and Commodore's ageing 16-bit hardware.

LucasArts still managed to produce an outstanding conversion. The original graphics, reduced from VGA's 256 colors to 32 in the Amiga's game area, remained remarkably close to the PC version. At first glance, it almost looked like the same adventure, with those beautiful backgrounds and an art direction I still consider among the finest ever seen in a video game.

To be precise, the Amiga interface used a separate palette from the game area, allowing more than the usual 32 colors to appear on screen overall.

But inevitably, something had been lost. Many environmental animations had been sacrificed, several background elements had become static, parallax effects were missing, and a considerable amount of the original music and sound effects hadn't made it into the conversion.

Despite these compromises, all you needed to play Guybrush Threepwood's second adventure was an Amiga 500 with just 1 MB of RAM.

And no, I haven't forgotten the hard drive. On the Amiga, you could play directly from floppy disks. All eleven of them!

I remember that back then, although I wasn't particularly enthusiastic about swapping disks every time the adventure progressed, I didn't think much of it. It was simply one of those things I was used to.

Today, though, I'm no longer willing to put up with all those compromises. At least not when it comes to playing the game myself.

Over the years, plenty of Amiga enthusiasts have argued that a virtually perfect conversion could have been made for the Amiga 1200, the A500's more powerful successor. I decided to see whether I could turn that old idea into something real.

I didn't want to simply replace the backgrounds in the Amiga version with their VGA counterparts. I wanted to rebuild the engine behind Monkey Island 2 and other LucasArts classics: SCUMM5.

A native interpreter, written in C and designed specifically to take advantage of the AGA chipset.

My initial goal was to run the original DOS/VGA version on a standard Amiga 1200 equipped with nothing more than a hard drive. I never considered a floppy-based version, for the reasons I've just explained.

During development, however, I realised that the machine's 2 MB of Chip RAM alone didn't provide enough headroom for everything I wanted to achieve.

In my dream version, I didn't want to give up environmental animations, parallax effects, scrolling, character scaling or, of course, the original 256-color graphics.

Guybrush Threepwood and Largo LaGrande on the Woodtick footbridge in the original Amiga OCS/ECS version of Monkey Island
The original Amiga conversion of Monkey Island 2, with 32 colors in the game area.
Guybrush Threepwood and Largo LaGrande on the Woodtick footbridge in Monkey Island 2 VGA running through SCUMM5-Amiga.
The same scene rendered by SCUMM5-Amiga, using the original 256-color VGA graphics.

Perhaps a little too ambitious, at least for an unexpanded machine.

That's why, for the current development stage, I decided to use an additional 2 MB of Fast RAM.

Back then, that would have meant a fairly substantial extra expense. But Commodore should also have done more to encourage people to expand their machines instead of continuing to rest on its laurels.

Computers were changing. Hard drives, additional memory and faster processors were becoming increasingly important. Commodore had a platform with plenty of room to grow, but never fully exploited its potential.

Another compromise concerns audio. The Amiga 1200 still relied on Paula and its four 8-bit PCM channels. An excellent solution for certain applications, but a limiting one when trying to reproduce the richness of the original PC soundtracks while also playing sound effects.

For this first stage, I therefore decided to keep the music from the original Amiga conversion and focus on restoring the missing sound effects.

But I'll come back to that later.

Developing SCUMM5-Amiga with Codex

Before getting into the technical details, I want to make one thing clear.

I developed SCUMM5-Amiga using OpenAI Codex, an AI-powered coding tool.

I'm not a professional game programmer, and I have no reason to pretend that I personally wrote thousands of lines of C code for the Motorola 68020.

Codex wrote the interpreter, developed the tools for processing the game's resources, and built the technical infrastructure needed for testing and diagnostics.

I directed the project, defining requirements and priorities, deciding which approaches to explore, evaluating compromises and personally verifying the results.

Despite what some people might imagine, though, it wasn't simply a matter of writing a prompt asking for Monkey Island 2 to be converted to the Amiga and waiting for it to magically appear.

If only it were that easy!

Development involved constant experimentation, testing, regressions and fixes. Sometimes a change produced an enormous improvement. Other times, after hours of analysis, the results were so modest that I decided to discard the modification altogether.

From the beginning, I insisted on one principle: I didn't want an engine built around tricks designed to make individual rooms work. I wanted an interpreter capable of handling the situations described by the original scripts without resorting to shortcuts.

Monkey Island 2 is the first game I've chosen to run, but my goal is to make SCUMM5-Amiga usable with other LucasArts adventures as well.

SCUMM5 Is More Than a Graphics Engine

SCUMM, as many of you already know, stands for Script Creation Utility for Maniac Mansion, the system developed by Lucasfilm Games to power its graphic adventures.

Over the years, it was expanded and modified to accommodate increasingly complex productions, eventually becoming the heart of games such as Monkey Island 2 and Indiana Jones and the Fate of Atlantis.

It does much more than display backgrounds and characters. It interprets the original scripts, manages dialogue, inventory, objects, animations, character movement, room transitions and all the variables that determine the state of the adventure.

That's why I chose to develop an interpreter capable of executing the original SCUMM5 bytecode directly.

Graphical resources are processed when necessary to make them usable by AGA, but the game's logic still comes from its original scripts.

This approach made development considerably more complicated.

More than once, I reached a scene that appeared to work perfectly, only to discover that a particular SCUMM instruction wasn't yet supported or that a resource wasn't being loaded and retained correctly in memory.

A perfect background and a correctly animated Guybrush aren't much use if the adventure crashes the moment you try to pick up an object or start a conversation.

Eight Bitplanes: The Price of 256 Colors on AGA

The first major challenge was, naturally, graphics.

The VGA version of Monkey Island 2 runs at a resolution of 320×200 pixels, with 256 colors selected from an RGB palette.

Thanks to its AGA chipset, the Amiga 1200 is perfectly capable of displaying an image with those characteristics.

At least on paper.

The PC and the Amiga, however, organise graphical data in fundamentally different ways.

In the VGA mode used by the game, each pixel is represented by an 8-bit color index. This arrangement, known as chunky, allows pixels to be manipulated directly within a buffer.

The Amiga, on the other hand, uses a planar representation. Displaying 256 colors requires eight bitplanes, each contributing one bit to the color index of every pixel.

Drawing and compositing characters directly in this format, particularly when transparency, scaling and overlapping elements are involved, is far from straightforward.

That's why I adopted a graphics pipeline based on working buffers and chunky-to-planar conversion, commonly abbreviated to C2P.

The problem is that converting graphical data on a 68020 running at around 14 MHz takes time. And that time adds to everything else: interpreting scripts, preparing animations, drawing characters and managing the rest of the game.

I therefore tried to minimise unnecessary operations by tracking modified regions of the screen and using optimised conversion routines.

The Blitter and Copper are used for operations where they can offer a genuine advantage, while the mouse pointer uses a hardware sprite.

Palette management also required a considerable amount of work. Simply loading the VGA colors wasn't enough: I had to preserve the correct appearance of dialogue, the interface, the cursor and the original color effects.

And then there's Chip RAM.

On the Amiga, the processor shares access to this memory with the chipset. When the display uses eight bitplanes, video-related memory traffic becomes particularly demanding.

Having 256 colors available doesn't mean you can use them for free.

AGA offers impressive graphical capabilities, but making the most of them on an original 68020 requires constant attention to memory, DMA access and the amount of work needed to prepare each image.

Guybrush Needs to Move, Not Just Pose for a Screenshot

Displaying a background correctly was only the first step.

The next challenge was making Guybrush move around it while preserving the original game's behaviour.

Monkey Island 2 uses walkboxes to define accessible areas, coordinates to determine destinations, and scaling factors that change the size of characters depending on their position.

As Guybrush moves into the distance, he gets smaller. As he approaches, he grows larger. And all of this has to happen while preserving the original animations.

There's also Z-occlusion to handle, the system that allows parts of the background to partially hide a character when he walks behind an object.

A seemingly simple walk therefore involves quite a few operations: updating position and scale, retrieving the correct animation frame, compositing the character, applying any necessary Z-masks and converting the affected pixels into planar format.

One of the results that gave me the most satisfaction was Woodtick.

I wanted to see Guybrush walking through the scene as the camera followed him, with the original scaling, animated water and moving environmental elements.

I also spent a considerable amount of time working on the boat and its parallax effect, encountering some rather awkward limitations when combining hardware sprites, scrolling and eight bitplanes.

Some experimental configurations proved impractical, and work on these effects is not yet complete.

But reaching a point where Guybrush could walk around Woodtick, enter buildings, interact with characters and continue his adventure was an important milestone.

I was no longer looking at a graphics experiment. I was actually starting to play Monkey Island 2.

Night-time scene in Woodtick running through SCUMM5-Amiga, with Guybrush and other characters on the dock.
Woodtick in its original VGA colors, rendered by the SCUMM5-Amiga interpreter on the AGA chipset.

Captain Dread and the Milliseconds Saved

Achieving good graphical fidelity doesn't automatically mean achieving good performance.

One of the clearest examples involved Captain Dread.

During his animations, the engine initially needed around 562 milliseconds to prepare an update. More than half a second.

While analysing the program with Codex, I discovered that a huge amount of time was being spent repeatedly reading the same graphical resources from disk.

Every movement of Dread's mouth triggered I/O operations that could have been avoided.

Introducing a cache for immutable source assets reduced the average time from around 562 to 123 milliseconds. A subsequent optimisation of the image compositing process brought it down to approximately 61 milliseconds.

From 562 to 61 milliseconds, without changing the scripts or artificially speeding up the animations.

That result showed me how important it was to identify the actual bottleneck rather than simply trying to make the entire engine faster.

Unfortunately, things didn't always go so well.

The swamp sequence, in which Guybrush travels inside a coffin, remains particularly demanding.

After an initial series of significant improvements, I tried moving some of the working buffers from Chip RAM to Fast RAM.

The result was a performance gain of just 6.6%, at the cost of around 268 KB of additional Fast RAM.

Not enough. I decided not to adopt that change.

The introductory campfire scene, with Guybrush and the pirates sitting around the fire, also required considerable work.

In this case, the problem mainly involved character compositing and animation preparation.

The analysis revealed that the fire used only four different animation frames, yet the caching system kept rebuilding them almost every update because it retained only one frame for that actor.

I therefore had Codex extend an existing caching system, allowing it to retain multiple frames for other configured actors as well.

The average preparation time dropped from around 170 to 146 milliseconds, an improvement of nearly 14%.

Unfortunately, that still wasn't enough to make the campfire perfectly smooth. In the measured test, the scene continued to update at an average of roughly six times per second.

I decided to stop there, keeping the improvement and postponing more substantial changes.

Guybrush Threepwood inside Captain Dread's cabin in Monkey Island 2, displayed through SCUMM5-Amiga.
Captain Dread's cabin. Optimisations reduced the average animation preparation time from around 562 to 61 milliseconds.

Seven Seconds to Open a Menu

Not every difficulty involved rendering the game itself.

At one point, I noticed that pressing F5 to open the menu meant waiting almost seven seconds before the panel appeared.

Pausing the game also took more than four seconds.

Frankly, unacceptable.

The curious thing was that the input system worked correctly: keyboard events were detected almost immediately.

The problem lay in preparing the menu graphics, particularly some extremely expensive palette scanning operations, planar buffer filling and integrity checks.

After replacing those operations with more efficient routines, the time required to open the F5 menu dropped from around 6.95 seconds to 0.9 seconds.

Pausing the game also improved, going from approximately 4.17 to 0.88 seconds.

It's not an instantaneous response, but the improvement is enormous and, for now, I consider the behaviour acceptable.

The Save/Load system, however, still needs work.

I've technically verified its functionality, including writing save files, closing the emulator, restarting it and restoring the game state.

The interface remains too slow, though. In some tests, the save writing and verification process alone took around five seconds.

An experimental fix eliminated duplicate confirmation steps and some problems with displaying the panel, but I haven't yet integrated that version into the main build.

Copper, Framebuffers and Other Little Nightmares

If I tried to describe every problem I encountered during development, this article would probably turn into a book.

A considerable amount of work went into managing the AGA display.

I encountered situations where the framebuffer was perfectly correct according to the diagnostic checks, yet the image displayed on screen still contained visual glitches.

Other times, the program worked normally but left graphical artefacts on screen when returning to the AmigaOS Shell.

The cause was often related to synchronisation between the Copper, DMA, Blitter and video buffers.

Preparing an image correctly isn't enough. You also have to make sure it's displayed at the right moment, without modifying a buffer that the chipset is already using.

I had to carefully verify these conditions, along with the proper release of hardware resources back to the operating system when the game exits.

One particularly interesting problem involved palette updates during the introduction. Under certain conditions, the engine rebuilt and published a Copper list too late, causing visual glitches.

The solution was to correct the color update path, avoiding the unnecessary reconstruction of the entire list.

Then there were problems with resource loading, fragmented memory, character animation frames, save files and even the geometry of virtual hard disks.

In one case, a discrepancy of just forty sectors between the actual size of an HDF file and the size reported by the emulated IDE controller prevented a write operation during program shutdown.

Correcting the disk geometry was enough to solve the problem, without changing a single line of the engine.

That was another part of development: learning to distinguish a problem in the interpreter from one caused by the testing environment.

The Problem with Music and Sound Effects

Recreating the complete Roland or Sound Blaster soundtrack through digital samples would have required a different playback system, introducing further compromises in memory usage, processing power and sound quality.

That's why I initially kept the music from the original Amiga conversion and concentrated on restoring the sound effects found in the DOS/VGA version.

The difficulty, however, isn't simply finding the samples.

Some original effects are digitised sounds, while others are generated through sequences and synthesis systems. They can't all be treated as ordinary WAV files waiting to be converted.

I had to analyse the original resources, identify the events requested by the scripts and develop playback routines compatible with Paula.

The four-channel limitation also requires careful management of music and sound effects playing simultaneously.

Part of the system is already working, but coverage is not yet complete.

One of the more curious examples involves the Bloody Lip bartender cleaning glasses with a cloth.

I managed to recover the original effect, which isn't a simple PCM sample, and reproduce it correctly through a dedicated audio controller.

Subsequent integration, however, revealed some latency problems, particularly when loading the resources needed for the first playback. I therefore decided to keep this effect in an experimental version for the time being.

Roland MT-32 music is a separate matter.

My goal is to use the game's original MIDI events, sending them through the Amiga's serial port to a real Roland synthesiser or, with the appropriate connection, to a software emulator such as Munt.

This approach would allow Roland music to play without occupying Paula's four audio channels.

The first experiments have produced encouraging results. I've verified MIDI transport through FS-UAE to Munt and achieved the technical execution of an original music cue, Sound169, triggered directly by the SCUMM5 virtual machine.

The backend remains experimental, however. I still need to verify the musical playback of that cue myself, and the complete behaviour of iMUSE, including transitions and musical synchronisation, requires further testing.

I'm not interested in simply playing external music disconnected from the game. I want the interpreter itself to control it, as intended by the original system.

The Part II Parchment

The first confirmation that Part I could be completed came from a checkpoint shortly before the end of Largo's storyline.

The interpreter executed the original scripts: Guybrush defeated Largo, recovered the Voodoo Lady's book, obtained Wally's monocle and completed his arrangement with Captain Dread.

The “Part II: Four Map Pieces” parchment was loaded and displayed through the game's normal execution path, without artificially recreating the scene.

The framebuffer was compared with the original reference: 64,000 pixels, with no color differences detected.

But I wanted to verify the entire progression myself.

So I started Monkey Island 2 in FS-UAE and played normally, solving puzzles, exploring Woodtick and the other locations on Scabb Island, and completing The Largo Embargo.

I reached the Part II parchment without running into any problems.

The game still starts with the currently supported introduction, while the original SCUMM bootstrap, including the Full Game / Monkey 2 Lite menu, has yet to be completed. This test therefore doesn't certify every possible interaction in the game, but it confirms that the entire main progression of Part I is playable.

The Part II: Four Map Pieces parchment from Monkey Island 2, displayed on Amiga through SCUMM5-Amiga.
The original parchment introducing Part II, reached by completing the first part of the adventure with SCUMM5-Amiga.

Testing on a Real Amiga 1200

Until then, I had developed and tested the project mainly through FS-UAE, using a configuration close to the original hardware: Motorola 68020 at approximately 14 MHz, AGA chipset, 2 MB of Chip RAM, 2 MB of Fast RAM and a hard drive.

No accelerated processors or JIT compilation to hide the engine's performance limitations.

But I also wanted to verify that it worked on my original Commodore Amiga 1200, equipped with the standard 68EC020 processor, 2 MB of Chip RAM, 8 MB of additional Fast RAM and a CompactFlash card connected to the internal IDE interface.

I transferred the same executable used in the tests and installed it on the CompactFlash card.

I completed Part I on the real machine as well, once again reaching the Part II parchment.

An enormous satisfaction, especially when I think back to 1992.

An Interpreter Still in Development

SCUMM5-Amiga is far from finished.

Performance still needs improvement in the most demanding scenes, sound effect support remains incomplete, the Save/Load system requires further optimisation, and the original bootstrap has yet to be implemented.

Part II of Monkey Island 2 is not yet playable, and the possibility of running the engine without Fast RAM still needs to be investigated.

I want to continue improving renderer performance, resource management, audio and the missing virtual machine features, without sacrificing fidelity to the original scripts.

My goal is to complete Monkey Island 2 and then tackle another of my favourite adventures: Indiana Jones and the Fate of Atlantis.

This time, though, without having to start all over again.

0 memories

Reader memories

Comment on the article and join the discussion.

Comment rules

Loading comments...