Monthly Archives: December 2018

Dark Castle (and BDC) almost works

During the Christmas holidays, Pukka was busy fixing 68K emulator bugs (including or.b/w/l and move.m instructions), and we can now play Dark Castle (without sound) at least through a few rooms, until it finally crashes in Shield 3:

Dark Castle is now almost working in MACE. No sound yet, but Shield 1 and Shield 2 can be played until crash in Shield 3

And as a bonus, here’s title screen of Beyond Dark Castle:

Title screen of Beyond Dark Castle

PICT version 2 support (monochrome)

As we got Railroad Tycoon intro to load further, we encountered one PICT resource which was a bit different from the others: It was a version 2 picture, while all previous pictures in the same game were simple version 1 PICTs. It appears that when apple added support for the new version 2, they also added rudimentary system software patches to the old-style QuickDraw on “Classic” type macs to handle the new opcodes. Without support for these opcodes, the classic QD would just ignore picture data and display nothing.

The interesting part of these version 2 format patches is the fact, that it allows non-color QuickDraw to take PixMap data, and map it using a simple 50% threshold to either black or white in a regular monochrome bitmap. Also, any unsupported picture opcodes get ignored using the simple dummy StdOpcodeProc implementation for non-color QuickDraw. So, to make this type of pictures show, we had to implement all of this color mapping functionality, resulting in this:

Almost got it right on the first attempt…

Well, almost got it…just accidentally incremented a pointer twice during the color mapping loop. After quick fix, this is what we had:

There we go! Nice version 2 PICT color-mapped and displayed correctly


With recent updates to Control Manager, and fixes to CPU emulation, we can now proceed in Tetris all the way to gameplay:

It’s not perfect yet, as clearing horizontal rows causes weird graphical corruption on screen – but it appears to be quite stable, music working and levels can be played through (although the graphical glitch makes it playing bit difficult). Here’s also a short video of the status of running Tetris in MACE at this point (with audio):

Tetris intro and one level running on MACE

In the land of odd bugs

These few weeks have been mostly bug fixing, and improving things to get the test applications to run further. This includes fixing the OR masking bug in Dark Castle, adding keyboard controls so we can actually move the character, and trying out different things. A lot has improved, but there’s still work to be done. At this point it might be appropriate to document some of the most strange bugs we had so far:

Broken bird sprite in Dark Castle

Most of Dark Castle levels load, but Fireball 1 crashes because of a buggy bird sprite.

Helicopter “trails” in Stunt Copter

There’s something wrong in the 68K code Stunt Copter uses to translate mouse movement to copter speed, causing trails to be left on screen after exceeding movement speed. Another issue with Stunt Copter is that it runs way too fast, but after experimentation we formulated a toolbox patch which would allow throttling the speed to make game actually playable.

Teleporting boulders in Dark Castle

And although Dark Castle starts to get playable, we still have issue of boulders teleporting around, and character falling through the floor 🙂

Control Manager, Icon Quest and Dark Castle main menu

One critical part of UI was still missing at this point, the Control Manager. Luckily implementing it was quite simple, as like with Window Manager, a lot of the core functionality depends on QuickDraw to do the difficult things.

IconQuest intro dialog

With support for Controls, we could now use buttons, like one in the above IconQuest introduction dialog, and the buttons below in Dark Castle main menu using ModalDialog:

Dark Castle main menu, almost working

The buttons still need titles, checkbox implementation is not complete, and TrackControl is implemented as a immediate return, but that is enough to allow entering The Great Hall in Dark Castle:

The Great Hall, with some bugs to iron out…

With this test case, Pukka identified a bunch of CPU bugs, including lack of BCD (Binary Coded Decimal) support which Dark Castle uses to display the values at bottom of the screen, which will be fixed next.

Update Events

When attempting to run 1000 miles, we soon noticed that it *could* draw to its windows, but it didn’t because we didn’t send update events to the application. As Window Manager implementation had already added foundation for posting the update events, we added support for it in the EventAvail/GetNextEvent, and stuff started happening.

After adding BeginUpdate, EndUpdate, and a bunch of other traps 1000 miles needed, such as PlotIcon and Pack7 (DecStr68K) package (for NumToString through LBin2Dec), we got nice looking interface of the game visible:

Update Events working; 1000 miles windows have now content

Title screen of Tetris (+ScrollRect)

After the recent changes, we decided to try out another classic game, Tetris:

The sound was not yet working correctly, but at least the title screen appeared correctly. As the game wanted to use ScrollRect to scroll text in the small box at bottom, this gave us a good excuse to go on and implement it:

Scrolling text in the title screen

The first Dialog

Now with Window Manager traps starting to get implemented, we could start work on the Dialog Manager. Technically, dialogs depend a lot on the Window Manager, as every dialog is a window, which contains extra information to track dialog items in it. After adding support for static text dialog items, we were able to display the intro dialog of one of our favourite games:

First appearance of a Dialog in our emulator

Menu titles and first windows

Menu Manager update

After some work on the virtual MBDF code resource, and related Menu Manager routines, we now have menu titles visible on the menu bar:

The menu titles are for the first time visible on the menu bar

For testing purposes, we also switched the desktop pattern by adjusting the ‘PAT ‘ 16 resource.

Window Manager

At this point, we wanted to get work done on the actual Window Manager routines, so we chose a few of the most simple applications we had for guiding our development and testing the results. One of them was the really old “3-D Maze” app by Mark Frohnmayer. Having the Pascal source code for it, it was quite easy to trace what the 68K code in it was attempting to do, so we could handle any issues we encountered. As this application is not a full game, but rather a demonstration for a Dungeon Keeper/Wizardry style engine, it consisted mostly of DrawPicture and CopyBits calls into a window.

Even the first GetNewWindow call had a lot of dependencies to other Window Manager traps (not to mention the ShowWindow and SelectWindow later!), but we got soon the first window displayed on the screen:

The first ever window, with picture drawn into it by the 68K test app

As we focused on the actual Window Manager implementation, we left the default WDEF for now as a simple one-pixel frame (and added for testing regions a small drop shadow), the windows look quite plain at the moment, but that should be enough to get applications run further.

1000 miles creates a lot of windows!

We also tested the new Window Manager routines with another app, 1000 miles, which was quite interesting because unlike most applications, which usually have one or a few windows, it had literally a window for every possible part of it’s user interface.