Monthly Archives: August 2024

Summer ’24 Update – Component & MIDI Manager news

It’s been a while since previous update, as life has been really busy during the past year. Sadly progress has been slow because of lack of time, but we do have some exciting news to share though for this year. Let’s dig in…

Enchanted Scepters

On Emaculation forums, one member asked us whether Enchanted Scepters was compatible with MACE. As we do have both 24-bit (and recently also 32-bit) addressing support, the original version of the game not being 32-bit clean was not an issue, but we ran into other interesting feature in the World Builder engine…when calling HandToHand to duplicate handle, we did return error code in D0, and resulting handle in A0 as specified by Apple documentation…HOWEVER, the original apple routine also does TST.W D0 before returning, so the zero flag is set to indicate the error state already at that state…Enhanced scepters expected this flag to be set by the time HandToHand returned, and of course we did not do this explicit testing of D0 register, and thus it crashed and burned with SysError 10. After adding a manual TSTW_D0 glue call at end of the trap (and a bunch of other traps returning value in Dn register), Enhanced Scepters seems to be mostly co-operating:

Enchanted Scepters

There’s still a bit weirdness with the custom WDEF it’s using, but we haven’t looked more into that yet.

Larger than 1mb slot space in 32-bit mode

As we did last year add the 32-bit addressing mode support to memory manager, we were finally able to experiment with taking advantage of this increased space, and added support for slot video devices to go beyond the 1MB slot device memory window limitation, which allows us to now use (almost) arbitrarily large display resolutions, that were previously limited to roughly 640×480 at thousands of colors, or 1024×768 at 256 colors. So…what better way to test this, than running SimCity 2000 in Full HD resolution:

SimCity 2000 running in Full HD resolution in full-screen mode

16-bit QuickDraw direct mode improvements

As some people might know, the original Marathon was recently released by Aleph One team for free on Steam, and partially inspired by this, we decided to work a bit on the direct color mode support of MACE, to allow running original Marathon in those higher depth modes. We previously already did have Marathon running in the usual, indexed 256-color mode, but there was a bunch of stuff missing or broken that needed to be implemented:

  • SetDepth needed to also accept color depth in addition to device modes
  • Cursor blitters and color table expansion did not yet work properly in direct modes
  • Device type of GDevices was set up incorrectly
  • Some blitters were unimplemented (i.e. colorizing BitBlt)
  • A bunch of blitters had byteswap bugs, that did not surface earlier, as indexed modes were never using more than 8 bits per pixel
  • 16-bit bitmap to pixmap expansion was missing
  • hilite draw modes were not rendering correctly as they did not expect data to be 16 or more bits per pixel
  • Some pattern drawing modes were not applying background/foreground color properly, as in direct modes black&white are reversed when compared to indexed modes, and this was not taken into account (in indexed modes, black is always last, white first, while in direct modes black is first, as its RGB value is zero, and white is last, as it’s either 7FFF or 00FFFFFF)

Here’s some before & after shots of Marathon main menu taken during this development process:

And here’s pic of the ingame dithering being inverted and font rendering still being broken:

Marathon “quit game” confirm dialog before the 16-bit color support fixes

Here’s also pics of the settings screen, before and after fixing the byteswap bug of 16-bit BitBlt:

Also, some pics of “Get File” dialog before & after fixes (also includes PICT 2 fixes, which will follow up):

PICT 2 recording improvements

As part of Marathon fixes, we also ended up digging into improving the previously broken PICT version 2 recording implementation. As the original PICT recording was specifically implemented with “classic”, non-color QuickDraw in mind that uses 1-byte opcodes, a lot of QD routines did not support saving the opcodes in the 2-byte format used by PICT version 2. Marathon uses this specifically for drawing a preview of the current map location, saving that in the savegame file, and using it to display preview in the Open/Get File dialog. Fixing this involved going through all the recording routines, and modifying it to use PICT version-independent code. This also has nice benefit that it made ResEdit DLOG/WIND previews also work now in color mode:

ResEdit DLOG preview works now in color modes too

AND also, this seems to have fixed the previously crashing Civilization 2 city screen, which uses PICT 2 recording somewhere in it:

Civilization 2 city screen no longer crashes

Sadly all recording are not yet fully supported, as StdBits is still missing some cases, and that causes at least ResEdit trying to display preview of windows that have goaway/zoom boxes, which are PixMaps, to fail to record/play back properly.

MAJOR FEATURE: Component Manager first steps

One other important milestone feature has also been support for Component Manager, which has now been partially implemented enough to allow Internet Config component extension to register, and the Internet Config application to load up and use the registered component mostly okay:

In case there’s somebody reading this, who does not remember what Internet Config was used for, it was the tool used to configure practically any internet-related settings in the old MacOS, offering through Component Manager a unified API for any applications to share & use these settings, co-exist and co-operate together. It consists of two main parts:

  • Internet Config Extension – This is actually not a traditional extension, which would contain ‘INIT’ code, but a component of type ‘thng’. Component Manager loads all these components during system startup, and registers them to be used by any applications which might rely on them
  • Internet Config Application – This is the UI for configuring the Internet Config settings, and it uses Component Manager to discover and connect to the Internet Config ‘ICAp’ component

Internet Config was a great test case for this, as it has very precise set of Component Manager features it uses, and does not depend on too many other features of the system, which we might not yet have implemented. There’s still dependency on file deletion which causes the saving of settings to fail, but we’ll eventually get that implemented and it should not be a major issue.

Originally Component Manager was developed for QuickTime, to support loading various video/audio codecs, but another major use case for it is Sound Manager 3.x – which is actually the major motivation for us to work on supporting components, as we hope to make our Sound Manager 3.x implementation follow the Sound Components design as closely as possible, which in turn relies on having Component Manager available to abstract all the mixers, hardware devices, compressors/decompressors etc in an universal pipeline.

Resource Manager fixes & ResEdit CODE editor

Just as a filler, we also wanted to get the famous ResEdit ‘CODE’ editor to work in MACE, as it allows disassembling any 68k code using the ResEdit itself. Interestingly almost everything needed to do this was implemented fine, but we had to implement SetResPurge trap (and default purge procedure), and also found a bug in reallocation or purged compressed resources by happy accident. Here’s pic of the CODE editor in action:

ResEdit ‘CODE’ Editor

AppleDoubler UTF-8 denormalization

Also on the side, we noticed that at some point the UTF-8 to MacRoman encoding in AppleDoubler tool had broken because of way UTF-8 can be present same file names both in normalized and denormalized formats, and we only supported denormalized UTF-8. As our current macOS host system gave us normalized file names, we added denormalization for all characters that are part of the MacRoman character set, and after that we were happily able to convert exotic names such as Déjà Vu II’s folder name into AppleDouble:

Déjà Vu II folder name denormalized & converted to MacRoman properly

Font/DA Mover

We already have had support for Desk Accessories for quite a while now, but until now we did all testing & adding those to the System file by manually copying the resources of those DAs. When we were working on the MIDI Manager support (news of which will follow up after this), we wanted to also add PatchBay DA to the System file, but decided to try for fun, how well would Apple’s Font/DA Mover work in MACE? Well…

Font/DA Mover

…the answer is: It worked just perfectly out of the box! We were able to manipulate both existing and new DAs from DA suitcases just fine, and the tool was happy to install PatchBay into our completely custom System file without any issues!

MIDI Manager implementation

And now to one of the coolest features we did do for this update: We had already been planning about experimenting with adding support for Apple MIDI Manager interface (which actually works using SoundDispatch with tool number 4), but we didn’t really get into this until this summer. One major breakthrough was finding finally the very elusive set of MIDI Manager documentation, which nowdays appears to be only found in Apple DocViewer format:

Apple DocViewer showing MIDI Manager SDK documentation

(The Palatino font above is a bit weird, as by design bitmap fonts default to half- or double-size versions if exact fit is not found, which in this case was the double-size one. Normally when viewing this font in this size in System 7 you’d get a way smoother look thanks to TrueType rendering, which we don’t support…yet!)

It took a couple weeks of work during the summer, but we finally got enough of MIDI Manager API implemented to allow both PatchBay to happily show our custom MIDI driver, load up MIDI Jukebox, and make connections between the driver and the application:

MIDI Jukebox and PatchBay in MACE

BUT what was even cooler, was the fact that thanks to MIDI packet format being universal, we eventually had very little to do to allow passing all the MIDI packets from MIDI Jukebox, through our custom driver, to the host system using CoreMIDI. And as we were able to hook actual MIDI Hardware, which in our case was M-Audio USB MIDI Adapter, and an original Roland SoundCanvas SC-55MkII, we got this nice recording of playing MIDI files in MIDI Jukebox in MACE through the real, physical hardware synthesizer:

The mouse cursor is a bit laggy in this capture, as we ran this whole non-stop one hour session in debug mode in Xcode, which is really slow even on a Mac Studio. We still need to work on the Time port timers, as randomly they don’t start up properly, instead stalling up the whole port. But once you get the timer running, it seems to work stable for a long time!

The very original motivation was to support native MIDI playback in Space Quest 1 remake, which does take advantage of Apple MIDI Manager:

Space Quest 1 using MIDI Manager, as seen in PatchBay

Sadly Space Quest 1 expects the sound module to be a MT-32, and we couldn’t figure out how to get SC-55mkII into MT-32 emulation mode, so the music in that game does not sound very great, and we didn’t take capture of it. Plus there’s also something missing from other part of emulation, as the game never proceeds from the intro screen, but stays there playing happily the music without allowing player to skip forward.

Also, thanks to PatchBay DA, which also uses the rarely used Desk Accessory feature of having its own menu in applications menu bar, we finally had a test case for SystemMenu trap, which was implemented!

Bonus: Some Havoc screenshots

Here’s also some screenshots of Havoc running on MACE…we wanted to just check if the game would try to use any QuickDraw 3D routines (as it’s supposedly one of the few QD3D compatible games), but apparently it’s happy to do everything in software 3D and actually runs pretty well, so…here’s how it looks like:

That’s all for now…we don’t know when the next update will be, as life’s going to get just more busy…but rest assured, work on MACE will continue. We’ll…be…back!

Full list of changes since last post

2024-08-12 02:03:18 +0300 • Fix MIDI timer drift (hook to time manager global)
2024-08-11 03:49:44 +0300 • Fix disabled MIDI debug message compile warnings
2024-08-11 03:49:04 +0300 • Quick hack to connect host CoreMIDI to MIDI Driver
2024-08-11 03:27:59 +0300 • Readhook implementation and packet dequeueing
2024-08-10 19:51:39 +0300 • Update MIDI time ports from the MIDI timer handler
2024-08-10 19:49:52 +0300 • Start MIDI driver clock
2024-08-10 01:25:43 +0300 • First proto of MIDIWritePacket implementation
2024-08-06 00:25:08 +0300 • Work on MIDIWritePacket (packet alloc & dealloc)
2024-07-29 19:38:05 +0300 • Implement MIDI time conversion for formats 0 to 5
2024-07-29 17:55:46 +0300 • Implement MIDIGetCurTime for MIDI Manager
2024-07-29 16:13:56 +0300 • Fix MIDI driver signature & data port directions
2024-07-29 16:13:22 +0300 • Partial implementation of MIDIConnectData
2024-07-29 14:50:11 +0300 • Implement MIDIGetPortName and MIDISetSync
2024-07-29 14:36:33 +0300 • Add temporary (quick hack) ports to MIDI driver
2024-07-29 14:35:27 +0300 • Implement MIDIGetPortInfo for MIDI Manager
2024-07-29 14:34:41 +0300 • Fix invalid port ID bug in MIDIGetPorts
2024-07-29 14:00:23 +0300 • Fixes to global MIDI port indexing
2024-07-29 13:28:38 +0300 • Partial stub of MIDIConnectTime implementation
2024-07-29 00:25:24 +0300 • Partial stub of MIDISetCurTime implementation
2024-07-28 10:40:26 +0300 • Tweak type of Get/SetSR in M68kHelper
2024-07-28 02:22:48 +0300 • Link CoreMIDI on macOS targets
2024-07-28 02:22:39 +0300 • Implement MIDIStartTimer for MIDI Manager
2024-07-28 02:15:41 +0300 • Part of MIDIAddPort implementation
2024-07-26 15:53:05 +0300 • Test code to dump list of host CoreMIDI devices
2024-07-26 01:43:54 +0300 • Fix MIDI Manager version number
2024-07-25 00:59:39 +0300 • Implement SystemMenu trap (for PatchBay DA)
2024-07-25 00:45:18 +0300 • Implement MIDISignOut (partially) for MIDI Manager
2024-07-24 16:45:48 +0300 • Add dummy DILoad stub for Font/DA Mover to work
2024-07-24 04:35:59 +0300 • Implement MIDIGetClientName for MIDI Manager
2024-07-24 04:26:11 +0300 • Implement MIDIGetPorts for MIDI Manager
2024-07-24 04:07:04 +0300 • Implement MIDIGetClientIcon for MIDI Manager
2024-07-24 04:01:47 +0300 • Implement MIDIGetClients for MIDI Manager
2024-07-24 04:01:32 +0300 • Implement MIDIWorldChanged for MIDI Manager
2024-07-24 03:53:18 +0300 • First MIDISignIn implementation test pass
2024-07-23 18:13:04 +0300 • A bit of work on MIDISignIn (checks for duplicate)
2024-07-23 18:12:09 +0300 • Call MIDI sign-in from the MIDI driver
2024-07-23 18:11:46 +0300 • Add MIDIDriverSignIn alternate MIDISignIn selector
2024-07-20 04:48:30 +0300 • Fix stack mismatch icon transformed SICN rendering
2024-07-17 21:48:21 +0300 • Add Deja Vu 2 test application configuration
2024-07-17 20:59:06 +0300 • Implement utf8 denormalization in AppleDoubler
2024-07-17 07:00:12 +0300 • Fix reallocation of purged compressed resources
2024-07-17 05:40:17 +0300 • Implement SetResPurge
2024-06-08 17:56:50 +0300 • Fix 32-bit memory manager free space debug checker
2024-06-08 17:56:23 +0300 • Add missing AppleEvent header additions
2024-06-08 02:30:42 +0300 • Merge branch 'master' of
2024-06-08 02:30:24 +0300 • Fake sound manager gestalt
2024-06-08 02:22:10 +0300 • Add dummy stub for AEPutKeyPtr AppleEvent selector
2024-06-08 02:18:11 +0300 • Add dummy stub Pack8 AECreateAppleEvent selector
2024-06-07 22:31:04 +0300 • Fix color graying out crashes in popupmenu CDEF 63
2024-06-07 22:13:23 +0300 • Dummy stub for IconSuiteToRgn icon utils selector
2024-06-07 21:52:27 +0300 • Fix calculation of offsets in thing ID validation
2024-06-07 21:51:03 +0300 • Fix incorrect size of component open file table
2024-06-07 13:35:25 +0300 • Implement OpenDefaultComponent
2024-06-07 13:35:03 +0300 • Implement FindNextComponent
2024-06-07 13:34:48 +0300 • Fixes to & cleanup in RegisterComponent
2024-06-07 13:26:14 +0300 • Fix comp head byteswap bug in RegisterComponent
2024-06-07 02:40:10 +0300 • Fix CallComponent Delegate fallback case stack bug
2024-06-07 02:11:51 +0300 • Add dummy stub for FlushCacheRange in HWPriv
2024-06-07 02:04:45 +0300 • Fix stack mismatch in component parameters cleanup
2024-06-07 02:04:14 +0300 • Implement DelegateComponentCall (simple case)
2024-06-07 00:33:58 +0300 • Fix component & instance index/pointer conversion
2024-06-05 23:25:27 +0300 • Minor component bug fixes
2024-06-05 23:20:40 +0300 • Implement Set/GetComponentInstanceStorage
2024-06-05 23:19:28 +0300 • Implement CallComponentFunction
2024-06-05 23:18:59 +0300 • First proto of OpenComponent & open component call
2024-06-05 14:30:23 +0300 • LoadComponent partial implementation (in sys zone)
2024-06-05 14:08:51 +0300 • Implement CloseComponentResFile
2024-06-05 13:55:45 +0300 • Implement OpenComponentResFile
2024-06-05 13:54:56 +0300 • Fix resolving file of registered components
2024-06-05 11:52:17 +0300 • Component validation added, start work on loading
2024-06-05 00:22:56 +0300 • Work on open/close/register/unregister comp calls
2024-06-04 01:08:59 +0300 • Use UPPs in CallComponent instead of a 68k callsub
2024-06-03 16:15:53 +0300 • ComponentDispatch refactor & proto CallComponent
2024-06-03 16:13:44 +0300 • Use opcode enum in ClosePicture, not hard-coded FF
2024-05-27 18:39:38 +0300 • Implement GrafDevice trap
2024-05-18 15:18:11 +0300 • Fix screen dirty area tracker overflow
2024-05-18 14:10:08 +0300 • Fix StdFile dialog visibility failsafe not working
2024-05-18 02:57:42 +0300 • Fix byteswap size in PICT v2 padding
2024-05-18 02:37:27 +0300 • Merge branch 'master' of
2024-05-18 02:37:16 +0300 • Fix padding of PICT v2 data when recording opcodes
2024-05-18 02:30:22 +0300 • Fix srcOr mode for 16-bit region blitters
2024-05-18 02:30:06 +0300 • Fix or & bic modes for 16-bit rectangle blitters
2024-05-17 16:33:49 +0300 • Fix colorization of srcOr & srcBic in direct modes
2024-05-17 02:26:57 +0300 • Merge branch 'master' of
2024-05-17 02:26:54 +0300 • Disable debug zone dump for MoveHHi
2024-05-17 02:05:25 +0300 • Fix zcbFree after MoveHHi to below min size target
2024-05-15 03:25:46 +0300 • Fix cast warnings for reading shifted pattern data
2024-05-15 01:41:36 +0300 • Fix hilite drawing mode to work in 16-bit colors
2024-05-15 00:59:58 +0300 • 1-to-16bit monochrome pixel expansion routine
2024-05-15 00:59:11 +0300 • Major work on version 2 PICT recording support
2024-05-13 16:02:35 +0300 • Fix byteswap bug causing 16bit color mode glitches
2024-05-13 14:51:33 +0300 • Add colorizing block blitter srcCopy mode
2024-05-13 12:26:06 +0300 • Fix wrong gdType in InitGDevice after SetDepth
2024-05-13 11:45:10 +0300 • Support blitting cursor in direct modes properly
2024-05-13 03:02:13 +0300 • Make QDScaleMask16 work with 16-bit cursor data
2024-05-13 01:32:11 +0300 • Tweak GetCTable to pass through 16-bit case
2024-05-13 01:18:21 +0300 • Fix SetDepth to also accept mode as depth argument
2023-12-25 04:31:05 +0200 • Add SimCity Classic and Duke 3D 68k Demo test apps
2023-12-10 23:19:19 +0200 • Enable >1mb slot space for slot devices in 32-bi..
2023-12-10 23:13:30 +0200 • Fix 32-bit heap compaction
2023-11-27 19:31:59 +0200 • Fix MIDIWorldChanged signature
2023-11-24 15:08:05 +0200 • Add dummy MIDIWorldChanged stub for SoundDispatch
2023-11-24 14:57:28 +0200 • Merge branch 'master' of
2023-11-24 14:57:21 +0200 • Work on Component Manager call dispatcher
2023-11-24 04:06:23 +0200 • Add Enchanted Scepters test app JSON config
2023-11-24 04:05:54 +0200 • Reinforce unsigned selStart/selEnd in TextEdit
2023-11-24 04:03:47 +0200 • Do explicit TSTW_D0 to update flags in HandToHand
2023-11-24 04:02:49 +0200 • Do a explicit TSTW_Dn on traps that return Dn
2023-11-13 00:47:13 +0200 • Implement FSpOpenRF for HighLevelFSDispatch
2023-11-13 00:44:25 +0200 • Start work on CopyDeepMask
2023-10-21 14:04:37 +0300 • Fix far-right edge ShieldCursor bug in classic QD
2023-10-21 14:03:05 +0300 • Update OSX icns files
2023-10-21 14:02:29 +0300 • Add Shadowgate to test apps list