From Amiga Code to Browser: Rebuilding Conqueror’s Opening Screen

Last time, we got past the packed executable and verified that our recovered game image matched WinUAE memory. This time, we wanted something you could actually see: Conqueror’s original title screen, followed by the game’s opening menus. We now have that sequence in a browser, along with a small tank test scene that uses some of the mechanics we have checked against the original 68000 instructions.

This continues our beginner’s guide to reverse engineering the Amiga version of Conqueror. That article covered the disk, WinUAE and MCP setup, the unpacker, the GDB parser gotcha, and why an acknowledged breakpoint is not the same thing as a breakpoint hit. Here we will follow the graphics and sound data from the unpacked intro into a browser.

The title screen was already sitting in memory

The intro program sets up five bitplanes at $2103E. Each plane contains 8,000 bytes, enough for a 320 by 200 pixel screen at one bit per pixel. Five planes combine to select one of 32 colours. The palette is a 32-entry table at $2AC7E, with each colour stored in the Amiga’s compact RGB4 format.

There was one small detail that affected the first row: the intro copies the second byte to the first byte of each plane before displaying the screen. Our extraction script repeats those five writes, combines the planes and expands each RGB4 colour to normal browser RGB. The resulting PNG is the original art, including the logo, battlefield, tanks and 1989 credits. It is not a redraw or an approximation based on a screenshot.

We display the recovered 320 by 200 image on a canvas with pixel smoothing disabled and black around it. That preserves the original pixels when the browser enlarges the image. The canvas contents also match the extracted image byte for byte after rendering.

The music is a sequence of original samples

The intro contains two streams of 352 sample descriptors. Each descriptor points to sample data and stores its length, playback period and volume. The Amiga program feeds these streams to audio channels zero and one, checks the audio interrupt, and moves on through the sequence. A key press shuts the audio down and leaves the intro screen loop.

We used the original sample bytes and descriptor values to build a stereo WAV, then made it available from the browser after a click. A click or Enter leaves the title and stops playback. Browser audio needs a user gesture before it can start, so the first click is an explicit “Play intro sound” action.

The reconstruction is not yet a cycle-accurate Amiga audio player. It follows descriptor periods using the PAL clock and loops the extracted sequence, producing a track about 147 seconds long. The original Paula DMA buffer timing, interrupt phase, analogue filter and exact loop phase still need comparison against live WinUAE audio. We label that part approximate instead of claiming a perfect recording.

We let the original code draw its own menus

The game entry calls a language selector before the main menu. We traced the selector at $5F926, which draws the English and German flags and labels. The main menu begins at $584E0. It draws the header, a tank model, and the game type and level options. The controls screen and key-definition screen have their own drawing paths at $5F752 and $5F10A.

Rather than recreate those screens by eye, we ran the original drawing instructions inside Ghidra’s 68000 emulator. We supplied framebuffer memory and captured the display planes and palette for the language screen, each of the three game types in both languages, and both language versions of the controls and key screens. We also extracted the original proportional bitmap font: eight pixel rows per character and a separate character advance width.

These captures use documented hardware stubs. The CPU drawing instructions are original, but our script skips interrupt-driven blits and some display/audio setup, clears buffers directly, and captures the first menu frame before its buffer swap. The tank in the menu is therefore a still image. We have not yet recreated its animation or the automatic demonstration.

A browser path you can try

The browser now connects the pieces: title, language choice, main menu, controls and key setup, then a labelled tank test scene. We also wired up menu clicks and keyboard navigation. F5 returns to language selection, F9 opens the original controls screen, and F10 opens key rebinding. The menu images and lettering come from the original program; changed option labels and rebound keys are drawn over the captured pixels.

python remake/serve.py
# Open http://127.0.0.1:8766/

The small local server sets the correct MIME type for JavaScript modules on Windows. The standard Python static server can send .mjs files as plain text, which makes browsers refuse to load the game code. That one took us a moment to spot.

Click Play intro sound to start the music, then choose Continue. Pick English or German with the flag or arrow keys. At the menu, use Space or Enter to open the tank test. Press Escape to return. The controls screen is a faithful reference, while the test scene currently applies the keyboard controls for movement, turret, elevation, firing and pause.

What the tank test proves, and what it does not

The test scene reuses the portable JavaScript routines we have checked against original instructions. Those routines include the movement lookup table, turret and gun elevation limits, reload countdown, shell lifetime and gravity step, and armour-versus-shell-power arithmetic. The recovered type data also includes eight tank records and their armour values.

Across those routines, 64 controlled cases match results from Ghidra’s original-instruction emulator: 36 earlier input, gun and movement cases, plus 28 shell-flight and armour cases. A separate integration check confirms that the browser test can move, fire and apply a penetrating hit to a nearby target.

The test scene is a mechanics workbench, not a finished remake. Its top-down tank artwork, steering response, shell launch direction, flat ground, collision radius and 20 Hz update rate are provisional. The exact launch vector, terrain, 3D renderer, missions and full damage effects still need tracing. Changing the menu’s game type or level currently changes the displayed selection; it does not start a real original mission.

Where we go from here

We now have a visible opening sequence grounded in recovered data, and a place to exercise the mechanics while reverse engineering continues. The next work is to compare audio and menu timing against a live WinUAE run, animate the original menu tank, and trace the full shell launch and collision paths. Actual automatic breakpoint hits also remain unresolved, so live runtime verification still matters.

The important change is that we no longer have to wait until the full game is understood before showing progress. We can preserve original art and menu rendering now, while extending the portable rules one tested piece at a time.

Leave a Reply

Your email address will not be published. Required fields are marked *