Category Archives: Toolbox

Sound Manager 2.x Support

It’s again been quite a bit of time since last update, as we’ve been busy on doing other stuff for the latter half of 2021, and the winter – but now in spring, we again had time to work on the emulator. During the past couple weeks, Toni spent time finishing the first round of Sound Manager 2 research, so we were able to move to implementation phase last week. And after first week of coding, we already have a handful of test applications with (mostly) working Sound Manager 2 support – although, as planned, it is at moment limited only to applications running in the “classic” emulation mode. Here’s a short video demonstration of the new audio capabilities:

Sound Manager 2.x tests on M.A.C.E.

In the video, the following test applications are shown:

  • Civilization, with fully working sound output (exclusively with bufferCmds through ‘snd ‘ resources).
  • Prince of Persia 1, also fully working (interestingly, even without Sound Manager, PoP1 was able to *mostly* output audio with Sound Driver, but looping sounds (door opening) caused hang in that mode because of the way it used the Device Manager routines. With Sound Manager, none of those issues are present and all seems work fine (again, using bufferCmd commands).
  • Bard’s Tale was a bit different test case for us, as it uses soundCmd combined with noteCmd/restCmd etc commands to play the music. But it also works now, apparently fully.
  • Railroad Tycoon has also fully working sound support, again using bufferCmd with ‘snd ‘ resources like Civilization 1. This game has interestingly its own sound queuing system, separate from Sound Manager command queues – which allows funny way of queueing multiple sounds if invoked rapidly after each other, which eventually get played in turn after each other. Also this behaviour seems to match fully how audio in the game works on real Macs.
  • Pararena 1.3 also has now working sounds
  • And Pipe Dream finally also got sound and music
  • Finally, Loom also has working sound & music, although the Mac Plus/Classic style behaviour of music does sound a bit “fishy”. We checked that the music does sound same way at least on minivmac, although it appears to have been meant to be played using 4-channel output, while the “classic” hardware is limited to only one channel at once. This game also uses soundCmd/noteCmd to adjust playback frequency of samples, like Bard’s Tale. Also, there is still at least one known race condition issue in playback, which appears to actually be identical to a deadlock that happens also in minivmac, if the game is run under that emulator on faster than 1x speed.

Also, there’s working button click sounds in Speedometer system info window, and we’re working on getting sound to work also in Bolo soon (it uses apparently older style selectors for SoundDispatch at least in one case, which we don’t handle yet, so we need to improve that next).

All of the features of Sound Manager 2 haven’t been implemented yet, as we’ve been adding them “on demand” as we’ve been trying out various test applications. Some of features not yet implemented include:

  • Compressed sound decompression/compression
  • At moment, only ‘snth’ 5 (sampledSynth) synthesizer is supported (the squareWaveSynth and waveTableSynth still need to be added)
  • Sound Manager command timing is supposed to the drift-free Extended Time Manager tasks, but they for now default to regular TMTask behaviour. This will cause songs played using noteCmd/restCmd/etc, that depend on command duration for timing, to drift off a bit (at least in Bard’s Tale and Loom)
  • And as mentioned before, only Sound Manager 2.x for “classic” mode was implemented, so the color mode does not yet have audio. But that will follow up later as Sound Manager 3.x compatibility after we finish research on it (we plan to implement Component Manager emulation as first step on way to SM3 compatibility, which both allows us to provide Sound Component capabilities, and also allows in future other APIs that depend on Components to be implemented – such as QuickTime and Internet Config)

Other fixes

There are also a number of other improvements, of which some are listed here:

  • MDEF 0 now supports scrolling in popup menus, which allows the Machine Record selection popup to be opened in Speedometer, when screen size is smaller than the menu
  • Fixed issue in “classic” QuickDraw PICT color translation mapping, which was causing black credits screen in Railroad Tycoon
  • GhostWindow low-memory global handling was added – this fixes most of the issues in SuperPaint 1
  • ScalePt/FixDiv had a couple bugs, which caused at least two separate issues in MacDraw (related to calculation of object coordinates on the document)
  • Color search proc support and a couple color picker package traps were added (for HSV conversion) were added to allow Solarian 2 to work
  • Rounded windows (WDEF 1) finally have the close box (and color support) – this allows for example the about screen in Glider 2 & 3 to be closed 🙂
  • Allocation of WDCBs through OpenWD now check for existing working directories, to not flood the WDCB table and run out of memory. This happened at least with certain applications using the “Mercutio” MDEF, which on each message did SysEnvirons call, which in turn opened a WD in the system folder
  • A bunch of other important fixes
  • And finally, as first step of getting FPU support, Pukka has started implementation of the 68881/2 emulation, so we will eventually be able to run applications requiring the math co-processor instructions (such as Specular Logomotion and Pixar Typestry)

Full list of changes since last post

2022-04-12 23:42:44 +0300 • Fix typo in Bolo JSON config                      
2022-04-12 23:29:35 +0300 • Fix signed/unsigned comparison in FMSeek          
2022-04-12 23:28:33 +0300 • Tweak test apps for sound tests + add BoloSounds  
2022-04-12 22:06:17 +0300 • Fix classic QD color-to-mono translation mapping  
2022-04-12 21:31:19 +0300 • Implement rateCmd in snth 4101 (classic SM2)      
2022-04-12 21:24:47 +0300 • Fix uninitialized SndChannelPtr in SndPlay        
2022-04-12 00:48:08 +0300 • Add scrolling support to popup menu case of MDEF 0
2022-04-11 17:00:05 +0300 • Fix disposal of channel if SndNewChannel fails    
2022-04-11 16:45:48 +0300 • Some PrimeTime prep for extended timer mgr support
2022-04-11 16:43:27 +0300 • Fix timer task deactivation in RmvTime            
2022-04-11 16:42:37 +0300 • Fix setting of channel idle state from quietCmd   
2022-04-11 16:41:42 +0300 • Swap new buffer in note/freqCmd if already playing
2022-04-11 14:55:02 +0300 • Fix duration passed to timer in waitCmd           
2022-04-11 14:53:59 +0300 • Setup synthesizer state correct in noteCmd/freqCmd
2022-04-11 14:52:36 +0300 • Fix bug in checking whether timer was active      
2022-04-11 00:34:59 +0300 • Implement emptyCmd in snth 4101 (classic SM2)     
2022-04-11 00:33:56 +0300 • Fix sample rate conversion bug in soundCmd        
2022-04-09 19:10:16 +0300 • Handle noteCmd/freqCmd in snth 4101 (classic SM2) 
2022-04-09 00:02:14 +0300 • Implement waitCmd (classic SM2)                   
2022-04-09 00:02:01 +0300 • Implement restCmd in snth 4101 (classic SM2)      
2022-04-08 23:37:15 +0300 • Handle soundCmd in snth 4101 (classic SM2)        
2022-04-08 20:23:59 +0300 • Fix SM2 locking (dispose channel during playback) 
2022-04-08 20:21:14 +0300 • Fix  end-of-buffer handling in snth 4101 VBL Task 
2022-04-08 20:19:38 +0300 • Set correct state in quietCmd handler in snth 4101
2022-04-08 20:18:56 +0300 • Clear busy flag correctly at end of snth VBL Task 
2022-04-08 13:01:33 +0300 • Fix size mismatch when setting channelIdle flag   
2022-04-08 12:47:08 +0300 • Implement flushCmd handling (classic SM2)         
2022-04-08 12:46:50 +0300 • Implement SndDoImmediate (classic SM2)            
2022-04-08 12:25:55 +0300 • Implement freeCmd in snth 4101 (classic SM2)      
2022-04-08 12:25:41 +0300 • Fix a couple byteswap bugs in channel flags       
2022-04-08 12:23:09 +0300 • Implement SndDisposeChannel (classic SM2)         
2022-04-08 04:18:00 +0300 • Implement callbackCmd (classic SM2)               
2022-04-08 04:12:18 +0300 • Handle quietCmd in snth 4101                      
2022-04-08 03:56:40 +0300 • Implement resumeCmd handling                      
2022-04-08 03:47:29 +0300 • Handle tickleCmd in snth 4101 (classic SM2)       
2022-04-08 03:36:14 +0300 • Implement basic snth 4101 buffering (classic SM2) 
2022-04-08 03:34:44 +0300 • Implement Timer1 & tickleCmd sending (classic SM2)
2022-04-07 03:49:16 +0300 • Handle bufferCmd in 'snth' 4101 (classic SM2)     
2022-04-07 03:47:59 +0300 • Handle high-level pauseCmd (SM2 classic variant)  
2022-04-07 02:08:33 +0300 • Implement command timer & dequeueing (classic SM2)
2022-04-06 20:25:16 +0300 • Implement queueing in SndDoCommand (SM2 variant)  
2022-04-06 19:21:39 +0300 • Handle initCmd in 'snth' 5 (SM2 "classic" variant)
2022-04-06 18:21:17 +0300 • Implement availableCmd and versionCmd in 'snth' 5 
2022-04-06 18:08:38 +0300 • Implement quietCmd handler                        
2022-04-06 17:58:52 +0300 • SndAddModifier mostly implemented (SM2.x variant) 
2022-04-06 02:17:47 +0300 • Implement SndPlay 'snd ' format 1 resource parsing
2022-04-06 01:33:48 +0300 • Fix typo in previous commit                       
2022-04-06 01:33:08 +0300 • Initialize Sound Manager (and fix byteswap bug)   
2022-04-06 01:17:33 +0300 • Use SndAddModifier in SndNewChannel               
2022-04-06 01:14:29 +0300 • Add SndAddModifier trap (dummy stub at moment)    
2022-04-06 01:13:07 +0300 • SndNewChannel proto implementation (SM2.x variant)
2022-04-06 01:11:00 +0300 • Add snth 0x1005 (mac plus variant of sampledSynth)
2022-04-06 01:10:33 +0300 • Update sound manager headers with new information 
2022-04-03 22:31:59 +0300 • fix constants                                     
2022-04-03 21:32:09 +0300 • base for fpu                                      
2022-03-23 00:27:09 +0200 • Reinforce IODone to handle weirdness of SimCity1.3
2022-03-20 05:02:17 +0200 • Add missing GhostWindow check to FrontWindow trap 
2022-03-19 03:47:11 +0200 • Fix ScalePt special case byteswap bug             
2022-03-19 00:31:53 +0200 • Better fix for FixDiv overflow case               
2022-03-19 00:29:30 +0200 • Set MemErr to noErr when MoreMasters succeeds     
2022-03-18 04:39:24 +0200 • Avoid weird C bug causing FixDiv fail in release  
2022-03-08 03:14:17 +0200 • Add missing music file to PipeDream test app      
2022-02-17 22:40:14 +0200 • Re-use existing WDCB when possible (not MF-aware) 
2022-02-17 15:24:34 +0200 • Allow skip of selector high byte in some selectors
2022-02-17 15:20:12 +0200 • Fix overflow in iteration of WDCB list            
2022-01-12 02:43:01 +0200 • Implement _DelSearch (0xAA4C) Color Manager Trap  
2022-01-11 04:02:15 +0200 • Implement FADDL selector for FP68K in SANE        
2022-01-11 04:01:28 +0200 • Implement HSV2RGB in Pack12 (color picker package)
2022-01-10 00:25:46 +0200 • Implement RGB2HSV in Pack12 (color picker package)
2022-01-09 21:08:25 +0200 • Add dummy SndChannelStatus to SoundDispatch       
2022-01-09 08:56:43 +0200 • Call searchProc in _Color2Index trap when needed  
2022-01-09 08:56:05 +0200 • Implement _AddSearch (0xAA3A) Color Manager Trap  
2021-12-01 15:15:21 +0200 • Add dummy GNEFilter for modal dialogs             
2021-12-01 15:14:06 +0200 • Support kSpecialCaseGNEFilterProc mixedmode calls 
2021-11-03 05:54:14 +0200 • Fix handling of MP lock flag in MMSetSize24       
2021-11-03 05:52:18 +0200 • Fix measuring memory purge range in memory manager
2021-10-29 13:09:10 +0300 • Add Uninvited to test app JSON configs            
2021-10-27 14:52:29 +0300 • Fix calculation of offset to font name in 'ictb'  
2021-10-27 14:33:29 +0300 • Fix opOrigin PICT opcode (disposed wrong region)  
2021-10-27 13:54:33 +0300 • Fix typo in the Hornet JSON test app config file  
2021-10-27 13:31:04 +0300 • Add F/A-18 Hornet 2.0.1 to test app configs       
2021-10-27 13:30:38 +0300 • Fix SysEnvirons, use 'proc' instead of 'cput'     
2021-10-27 13:29:04 +0300 • Handle special palettes with bit 14 set in flags  
2021-10-27 05:13:14 +0300 • Fix minor Palette Manager bugs                    
2021-10-27 04:18:39 +0300 • Add ADB Manager & dummy CountADBs/GetADBInfo traps
2021-10-27 03:57:20 +0300 • Video DRVR: Handle status codes & add linear gamma
2021-09-26 20:45:07 +0300 • Disable SDL minimize/close keys (3rd party lib!!!)
2021-09-26 20:40:59 +0300 • Temp fix for return address of TRAP # instructions
2021-09-26 20:38:25 +0300 • Fix 32-bit overflow in ASR.W instruction          
2021-09-26 20:37:53 +0300 • Fix RTE instruction                               
2021-08-22 13:10:43 +0300 • Fix pattern masking bug in arithmetic rect blitter
2021-08-17 23:32:14 +0300 • Add dummy SRsrcInfo selector for Slot Manager     
2021-08-17 03:47:44 +0300 • Fix artifacting of outline/shadow color QD text   
2021-08-16 17:42:58 +0300 • Fix some Memory Manager type conversion warnings  
2021-08-16 17:42:03 +0300 • Add srcOr/srcXor/srcBic colorQD region blit modes 
2021-08-16 14:35:33 +0300 • Add missing WDEF 1 changes from previous commit   
2021-08-16 14:35:06 +0300 • WDEF 1 (rounded window) color support & GoAway box
2021-08-16 14:34:13 +0300 • Fix array overflow in the minilauncher hack proto 
2021-08-12 22:06:06 +0300 • Fix memory leak in DialogManager (Get)New(C)Dialog
2021-08-12 22:03:05 +0300 • Fix memory leak in CloseWindow (call CloseCPort)  
2021-07-29 19:48:49 +0300 • Add 1-to-2 bit non-colorizing pixel translator    
2021-07-13 23:42:11 +0300 • Sanity check ioNamePtr in _GetVol trap            
2021-07-13 23:41:02 +0300 • Add Bards Tale test app JSON configs              
2021-07-13 18:21:41 +0300 • Add Macintalk test app JSON configs               
2021-07-07 00:12:25 +0300 • Bump up version number                            
2021-07-07 00:12:14 +0300 • Fix VBL interrupt crash from start race condition 
2021-07-06 21:42:48 +0300 • Fix changes that broke .Sound DRVR #3             
2021-07-06 00:05:22 +0300 • Install dummy DRVR 4 at startup                   
2021-07-05 23:06:35 +0300 • Tweak Space Quest 1 config JSON (pass copy checks)
2021-07-05 23:06:02 +0300 • Add missing DskErr lowmem from previous commit    
2021-07-05 23:05:48 +0300 • Add dummy .Sony driver, allows DRVR 4 Status calls

First status update of 2021

For the past half year progress has been a bit more slower than usually, mostly due to Toni being busy with the daily work, playing around on Twitch, and experimenting with his retro raycaster 3D engine prototype, while Pekka has been busy with work and private stuff. There has however been some bits of progress, which are summarized in this post:

“Classic” audio upsampling

Even though Sound Manager support is still under development (with relatively good progress), the audio support for “Classic” type audio (that is, the emulation of audio hardware of Mac 128K through Plus/SE/Classic series machines) has been improved a bit. Originally the audio buffer with 22255 Hz sample rate was passed directly to SDL2, which caused some problems as some systems were not able to handle that format very well. Even though it worked on Mac Pro, for example on M1 Macs it caused the audio in other applications to start cracking and breaking up. By allocating the SDL2 audio buffer in default native format (usually 44100hz), and upsampling the audio data in emulator, most of this problem was eliminated. However, in some cases, clicks are still present in the audio, mostly due to the way how original hardware handles square-wave and sampled sound as a mix of both unsigned and signed 8-bit samples (that is, square wave sound amplitude ranges from 0 to 255, while in same buffer, sampled sounds are in range -128 to 127, with different “silent” baseline level.

TextEdit fixes

There were two critical fixes in the TextEdit, one of which caused at least one of Marathon terminals to crash:

  • In styled text line height table handling code, the code that was used to zero newly added line heights (when adding new lines) was not working properly in the case number of lines was reduced (causing it to try to clear a negative number of lines, wrapping around to a crazy number)
  • TESetStyle was calling TESelView with an invalid pointer

With these fixes, this particular Marathon terminal is now working without crashes – and looks identical to the one on real Macs:

The previously crashed Marathon terminal that works now

Minor fixes to allow streaming of The Fool’s Errand

Most of code needed to support running The Fool’s Errand was already implemented long time ago, but one of the most important things, a way to display the prologue and finale was missing. The original game used a separate application for prologue, and also a dynamically generated file for viewing the finale after completing the game.

On real Macs they were opened using Finder, but we needed to have an easy-to-use way to open them when running the emulator from the single-click app bundle. For this purpose, we hacked very quickly a “MiniLauncher” tool, which allows not only selecting the launch application, but also passing a document in launch parameters – which is required to show the finale (as clicking “Show finale” on Macs actually launches “prologue – finale” application passing the “Show finale” as opened document to it).

Right now the Minilauncher is very primitive and a quick hack to support this one single game, but we plan to improve it later to a more reusable launch tool, probably similar to Apple’s old MiniFinder, to use as a stopgap tool for the first general-purpose version of M.A.C.E.

While implementing this, we found a minor byteswap bug in Launch trap’s handling of AppParmHandle. (Also, Toni was able to complete the full Fool’s Errand playthrough on Twitch using this improved version).

Star Wars day

This year we also celebrated the official Star Wars day (May the 4th) by trying out how the Brøderbund’s Star Wars arcade game’s Mac port works on M.A.C.E. and streaming a bit of it on Twitch:

Star Wars for Mac

Both the sound and visuals seemed to work without any problems. The “main menu” of the game did seem to run a bit faster than on real Macs, but luckily the actual ingame play was not affected by machine speed, and ran just fine.

Monkey Island

Inspired by the number of people recently streaming Monkey Island on Twitch, we were interested to see how the Mac version of that game would run on M.A.C.E. There were a couple tweaks needed to get it to run:

  • The Start Manager traps GetVideoDefault and SetVideoDefault traps were needed, and it seems the the dummy implementations were good enough to make Monkey Island happy
  • ReserveEntry palette manager trap had a bug where the GDevice’s color table was not reseeded when clearing the “reserve” (only when setting it). This caused the inverse color lookup table to not update properly, turning at least the pile of monkeys in Monkey Island about box from grayscale to black & white 🙂

It seems that Monkey Island runs quite well now on the emulator, although doesn’t yet have any sounds until the Sound Manager implementation gets finished. Also, it has some timing glitches at least in cutscenes, which may be related to the timer issues with Prince of Persia 2 and Loony Labyrinth (which need more investigation).

Hilite transfer mode

Another task from long time ago was implementing the hilite transfer mode for Color QuickDraw. It is basically a special transfer mode used to improve the highlighting of selections, done with simple color inversion in monochrome Macs, with a more colorful visualization.

In this mode, the color ports have special rgbHiliteColor field used to determine highlighting color (which by default is populated from HiliteRGB low-memory global). If using the hilite transfer mode of 50 or 58 (or when the special hilitebit in HiliteMode low-memory global is cleared in combination of using xor transfer mode), QuickDraw will swap background and hiliteColor with each other, producing toggleable highlight coloring:

Additionally, the hilite mode was also one missing piece of the scrollbar CDEF thumbnail drag drawing code, so that is now also visualized correctly.

The mysterious stuff in Sierra games #1: Sound in Mixed-Up Mother Goose

Although King’s Quest 1 was already working nicely since last year, Mixed-Up Mother Goose was interestingly having trouble playing audio, so we did a bit of investigation about it. It turns out that game is very strangely using some of the unused 68K user exception vectors to save handle to data being used to track music/audio playback in their VBL handler.

The reason this didn’t work, is that all those vectors were originally uninitialized (set to zero), and this particular version Sierra’s AGI engine checked if the exception vector pointer was set to a value above ROMBase, and it being lower assumed some handler was already present, and skipped using it for its own data. On real Macs, every unused 68K exception vector is initialized during startup by the Error Manager to DS exception handler, which by default is in ROM, and thus makes the game work on those systems. By adding a dummy exception handler and populating all the exception vectors, Mixed-Up Mother Goose was able to play music & sounds without any problems (Toni also did a one-hour playthrough of this game on Twitch to celebrate this fix).

Mixed-Up Mother Goose (with audio working)

The mysterious stuff in Sierra games #2: Color support

One of Toni’s friends on Twitch mentioned that some Sierra AGI games had problems running the 16-color versions in Mac emulators (specifically Space Quest 1), so we were curious and investigated this issue. On the first try, the same problem manifested also in M.A.C.E., so we started to dig a little bit deeper to find the cause of this, and found something interesting.

When I dissected the AGI code in Space Quest 1, I noticed that really weirdly, as the very first thing, the game checks if the the baseAddr of screenBits is above $F000 0000 – and if this check failed, even if the screen would be set to higher bit depth, it would go on and assume it was displaying the game on a monochrome screen.

As the problem on other Mac emulators may be partially related to inability of switching to 24-bit mode (at least when I tried it with Basilisk II), I believe that what is happening is that Slot Manager addresses the cards in different way in 24- vs 32-bit modes (for example, card $9 is accessed through “minor slot space” range of $009x xxxx, which translates to 32-bit address range in “standard slot space” of $F90x xxxx – problem is, that in 32-bit mode, the address would be in “super slot space” of $9xxx xxxx). It should be noted that even in 24-bit mode, at least QuickDraw handles the actual video memory access in 32-bit mode by using SwapMMUMode to temporarily switch the mode – same thing that some 24-bit compatible early color games also do, such as Maelstrom.

In our emulator, as we ran everything in pure 24-bit mode, including the video memory access, we didn’t care about the high byte of the address, which being zero originally displayed the same behaviour. However, after populating the high byte with “faked” standard slot space-type address of 0xF9900000 for video memory as a hack, both Space Quest 1 and Mixed-Up Mother Goose started to work in color mode:

Space Quest 1 in color mode

A more proper memory addressing and slot manager implementation will however be definitely needed, and that will most likely be done when we will be adding the 32-bit memory addressing support in the later part of this year.

Minor Warcraft 2 demo progress

We also did a little bit of work on trying to get Warcraft 2 (and its demo) to work. As it’s so far the only game that requires Thread Manager, it was previously put on a hold due to uncertainty about how much threading features it would be using. Turns out that adding dummy implementations for MacGetCurrentThread, SetThreadSwitcher and YieldToThread were enough to get Warcraft 2 progress a bit. Naturally proper Thread Manager implementation will be added at a later point, most likely in combination of Process Manager and EPPC/AppleTalk support which all are related to each other. But for now, we are able to get at least to the startup options screen – but sadly not further yet:

Warcraft 2 demo startup options dialog

What’s next?

For now, we will try to focus on continuing the research of Sound Manager during the summer. So far the progress on that has been pretty good, as we have already good idea about some of the sound manager data structures and behaviour – but more work is still needed to get it to the point where it can be used in the test applications, and to actually produce the sounds. It should be noted that we will be adding two variants of Sound Manager, the 2.x compatible version that will be used in the “classic” mode (which was the highest Sound Manager version supported by the old monochrome Macs), and 3.x compatible version for the color-capable (i.e. slot manager) emulation mode. We also may need to implement ASC-compatible version of the “.Sound” driver to support stuff like fourtone synthesizer in early color games (but instead of hardware emulation like in “classic” mode, that will be all done directly in software).

Full list of changes since last post

2021-06-21 03:42:10 +0300 • Add dummy IconIDTorgn & PlotIconID to IconDispatch
2021-06-21 03:41:08 +0300 • Fix NewGWorld fail crash (duplicate DisposeHandle)
2021-06-21 03:39:03 +0300 • Add dummy SPBOpenDevice to SoundInputManager      
2021-06-21 03:38:17 +0300 • Add dummy YieldToThread selector to ThreadDispatch
2021-06-19 13:27:53 +0300 • Fix some incorrect PaletteDispatch selector sizes 
2021-06-19 13:04:30 +0300 • Add dummy SetThreadSwitcher to ThreadDispatch     
2021-06-19 13:01:37 +0300 • Don't crash MDEF 0 on unsupported messages        
2021-06-18 21:00:20 +0300 • Add ThreadDispatch & dummy MacGetCurrentThread    
2021-06-18 17:30:21 +0300 • Add dummy Thread Manager module                   
2021-06-14 16:30:06 +0300 • Add Space Quest 1 test application JSON configs   
2021-06-14 16:29:41 +0300 • Add 16-color Sierra AGI compatibility HACK        
2021-06-14 16:27:15 +0300 • Add dummy _Eject trap handler                     
2021-06-05 04:09:17 +0300 • Fix drawing of scroll thumb outline in color mode 
2021-06-05 03:18:30 +0300 • Add Civilization DEMO test application JSON config
2021-06-04 22:18:11 +0300 • Fix GetResource (DON'T set resNotFound to ResErr) 
2021-06-04 00:03:10 +0300 • Implement PixMap32Bit                             
2021-06-04 00:02:12 +0300 • Fix initialization of screen GDevice pmVersion    
2021-06-03 23:39:35 +0300 • Fix byteswap bug in GetPixelsState in QDExtensions
2021-06-03 23:00:04 +0300 • TextEdit fixes for the hilite mode support        
2021-06-03 22:58:40 +0300 • Implement GetIconSuite for IconDispatch           
2021-06-03 21:11:28 +0300 • Fix inet_ntop buffer size in AddrToStr in MacTCP  
2021-06-03 17:43:28 +0300 • Also add hilite transfer mode to region blitter   
2021-06-03 17:21:44 +0300 • Support hilite transfer mode in rectangle blitter 
2021-06-03 17:18:33 +0300 • Fix mask of source pixels in transparent blit mode
2021-06-03 01:39:31 +0300 • Merge branch 'master' of <redacted> 
2021-06-03 01:39:26 +0300 • Fix ReserveEntry (reseed CT also w/ reserve=false)
2021-06-03 01:35:55 +0300 • Add StartManager + dummy Get/SetVideoDefault traps
2021-06-03 01:35:02 +0300 • Add Monkey Island test app JSON configs           
2021-05-31 11:50:14 +0300 • Merge branch 'master' of <redacted> 
2021-05-31 11:50:10 +0300 • Add dummy minilauncher code, to be improved later 
2021-05-30 22:01:00 +0300 • Fix nested VBL interrupt support (to not hang)    
2021-05-30 20:25:37 +0300 • Add a generic DS exception handler to all vectors 
2021-05-30 20:21:55 +0300 • Add Mother Goose test app JSON configs            
2021-05-04 04:55:48 +0300 • Add Star Wars test app, for May 4th celebration 🙂
2021-04-13 16:47:10 +0300 • Merge branch 'master' of <redacted> 
2021-04-13 16:47:05 +0300 • Fix 1-bit pixmap expansion with custom colortable 
2021-03-30 02:09:37 +0300 • Fix byteswap bug of AppParmHandle in A5 world     
2021-03-03 13:15:25 +0200 • Ignore thirdparty lib xcode user workspace folder 
2021-03-02 22:45:30 +0200 • Merge branch 'master' of <redacted> 
2021-03-02 22:45:12 +0200 • Fix invalid pointer bug in TESetStyle             
2021-03-02 22:44:15 +0200 • Fix negative bytecount bug in TESetLineHeights    
2021-03-02 19:42:19 +0200 • Fix debug mode in posix file copy utlity (errno)  
2021-03-02 19:41:43 +0200 • Fix __APPLE_ preprocessor typo to __APPLE__       
2021-03-02 19:11:43 +0200 • Make raspberry pi version compile again           
2021-03-02 02:45:14 +0200 • Make CMP0114 policy compatible with old CMake too 
2021-03-01 22:22:12 +0200 • Remove printf                                     
2021-03-01 04:09:50 +0200 • Setup QoS class for main thread on Apple M1       
2021-03-01 04:09:09 +0200 • Upsample audio from 22255 to 44100 manually       
2021-02-24 22:56:53 +0200 • Universal compilation cmake config for M1 macs    
2021-02-21 01:20:48 +0200 • Minor fixes(?) to 16/32-bit bitmap upscaling      
2021-02-21 01:18:25 +0200 • Fix planeBytes comparison in PixMap equality check

Happy new year! First M1 benchmarks, and other fixes

First tests on Apple Silicon

Toni finally got a M1 MacBook Air in mid-January, so we have now been able to try out compiling the emulator on macOS arm64 target. As all arm-specific issues were already fixed in the Raspberry port, the code compiled directly without any modifications needed, and is also running without any issues. However, the CMake build system needs to be tweaked a little bit to allow universal builds, as by default it generates only arm64-only builds. Soon when this is sorted out, we will update the available downloads to include the M1-native versions. Below however are some Speedometer test that we got from quick testing:

Here’s breakdown of the scores:

  • The first score, 35.8 total (0.774 cpu) is from x64 native code running on 2015 MacBook Pro (2.7 Ghz i5)
  • The second score, 90.6 total (1.700 cpu) is from x64 code running on M1 MacBook Air in Rosetta emulation
  • The third score, 146.2 total (2.770 cpu) is from arm64 code running on M1 MacBook Air natively

So it seems that the Apple Silicon builds seem to be working quite well (even though according to Pukka, there is a lot of possibility for optimization; more about this later)

Color support for scrollbar controls

Another TODO-task from long time ago was adding finally color support for the scroll bar control (CDEF 1). The windows, standard buttons and menus had already color support, but this was the last piece missing from a full reproduction of System 7-style appearance. Technically the control code is complete, but the scrollbar thumb dragging is still missing hilite mode rendering, so it is only 99% complete. Below is screenshot of one of the games where this visual change is visible (scrollbars on the SimCity 2000 map window):

Color scrollbar (CDEF 1) contols, here in SimCity 2000

Boolean bitmap color blending fixed

Another fix we did was analyzing and fixing the problem with text rendering in Master of orion, which we wrote about in the last month’s update. What we found out, was that according to IM:Imaging With QuickDraw book, sourcing any bitmap transfers from monochrome sources to color destinations need to be colorized in a bit different way compared to color transfers. What this means, is that when doing pixel scaling, the source color table lookups are skipped, and the foreground/background colors are applied directly on the source bitmap data. With this fixed, all the texts appear now correctly in Master of Orion:

Master of Orion with text blending issue fixed

Trying out a couple more new games

We also added some new games to the suite of test cases, in this case Might & Magic II and Loom:

  • Might & Magic III needed a couple Script Manager routines, which we added as placeholders, so the game starts up, but text rendering is still a bit off
  • Loom seems to work nicely as-is, although like all other color applications, needs Sound Manager support to get any sound.

68k TRAP instructions and THINK Pascal LightsBug

Another thing that we got to work was the 68K TRAP instruction handler, which enabled the debugging in THINK Pascal to work quite nicely. Breakpoints, execution control, LightsBug features (variable views, 68K registers, heap) seem to work mostly okay. The IDE does however complain about memory zone corruption, although all zones are fine (something is also causing the LightsBug zone explorer to fail, so there may be still some minor incompatiblity there).

Pukka is currently in progress of improving the exception support in the 68k emulator, so we will have the support for TRAPs fully implemented soon.

Other stuff

Here’s a couple other things that were fixed:

  • Added support for drawing labels for the popup menu control (CDEF 63). This is used by Master of Orion in the new game setup dialogs
  • Don’t assume FMExist low-memory global exists on “classic” type Macs. This came up as THINK Pascal does a lot low-level patching on a number of Toolbox routines (to allow running applications inside THINK Pascal itself), InitFonts is expected to run on the older machine profiles even if FMExist would be marked to tell that Font Manager is initialized
  • Fixed CopyBits device port pre-draw intersection to take port origin into account; ignoring this cased scrolling up ResEdit editors to make contents of window disappear as the origin moved far enough up off the screen
  • Graying of standard button control (CDEF 0) checkbox and radio button variants; this fixes the issue that disabled controls did not render as grayed out in color ports
  • Added a number of color menu table access routines (GetMCInfo, SetMCInfo, DisposeMCInfo + other tweaks), which allow ResEdit to now display MENU resource previews also in Color QD mode – and also, the MENU resource editor seems to also work, with full color editing features

Regarding optimization, after discussion with Pukka, we decided that we should try in very near future an alternate way of mapping the emulated machine memory using host system/machine paging instead of the currently VM lookup table. Theoretically, using mmap (with possible combination of libsegv or similar) to map memory to a certain fixed “window” in memory, we could almost completely eliminate the penalty of emulated machine memory accesses. According to profiling results, should theoretically double the emulation speed, but we need to experiment with this to see how the results are. We will write more about this when we soon have chance to try it out.

Also, Toni has been doing a couple small experiments on using M.A.C.E. for trying out Twitch.TV streaming at https://www.twitch.tv/truetonizz.

Full list of changes since last post

2021-01-12 13:55:56 +0200 • Add missing path to toolbox cmake build script
2021-01-12 11:03:38 +0200 • Inline VM access calls & add dummy page handler
2021-01-12 02:57:09 +0200 • Add Loom test app JSON config settings for CMake
2021-01-12 02:55:57 +0200 • QDScaleColorize1ToIndexed4 (colorizing 1-to-4 bit)
2021-01-08 13:58:28 +0200 • Add QDScale1ToIndexed4 (1-to-4-bit depth scaling)
2021-01-06 05:12:58 +0200 • Apply bgColor in patBic mode in color rect blitter
2021-01-05 22:22:34 +0200 • Force also ROM clut copies to NoPurge in GetCTable
2021-01-05 22:19:49 +0200 • Set MemErr in HPurge/HNoPurge/HClrRBit/HSetRBit
2021-01-05 16:37:01 +0200 • Handle empty (zero-size) 'ictb' resources properly
2021-01-05 02:10:20 +0200 • Fix also graying of CDEF 0 radio/checkbox buttons
2021-01-05 01:50:08 +0200 • Color QD button graying (text & default frame)
2021-01-04 22:41:52 +0200 • Fix color QD CopyBits when scrolling w/ SetOrigin
2021-01-04 06:00:32 +0200 • Implement GetMCInfo/SetMCInfo/DisposeMCInfo traps
2021-01-03 03:10:35 +0200 • Don't use FMExist on "classic" b&w configuration
2021-01-03 03:09:32 +0200 • Use non-MacPlus trap table profile in THINK Pascal
2021-01-02 20:32:55 +0200 • Minor code cleanup in standard windowproc (WDEF 0)
2021-01-02 20:31:57 +0200 • Add color support to scrollbar controls (CDEF #1)
2021-01-02 20:30:52 +0200 • Merge branch 'master' of
2021-01-01 10:49:54 +0200 • Clean up Dialog Manager drawing save state locals
2021-01-01 02:28:56 +0200 • Implement VisibleLength selector for ScriptUtil
2021-01-01 01:34:20 +0200 • Add dummy StyledLineBreak selector to ScriptUtil
2021-01-01 01:12:18 +0200 • Partial implementation of TEGetStyleScrap selector
2020-12-30 23:20:43 +0200 • Merge branch 'master' of
2020-12-30 23:08:14 +0200 • Add CMake JSON test config for Might & Magic III
2020-12-30 20:47:49 +0200 • Add colorizing 1-to-8bit pixel translation
2020-12-30 20:45:07 +0200 • Fix ctSeed byteswap in stretch dither mode check
2020-12-30 18:45:02 +0200 • Uncheck item after popup menu selection
2020-12-30 18:41:35 +0200 • Draw labels in popup menu control + colorQD stuff
2020-12-30 10:14:41 +0200 • Fix some byteswap bugs in the popup menu control
2020-12-30 00:42:07 +0200 • Fix popup menu control MENU reloading
2020-12-29 23:28:18 +0200 • Fix mouseMoved message signature
2020-12-29 22:16:18 +0200 • Pixpat expander a bit safer in case of memory move
2020-12-29 22:12:37 +0200 • Add correct 1-bit boolean stretching depth scaling
2020-12-24 00:11:46 +0200 • use memory macros for all 68k emulator memory i/o
2020-12-24 00:10:27 +0200 • use memory macro in cpu look, remove unused proc..
2020-12-24 00:09:10 +0200 • make index offset branchless
2020-12-22 00:09:37 +0200 • Add Solarian II to test application CMake configs

Merry X-Mas! (with Glider 4 and Scarab of RA)

Even though it’s been a rough year around the world, soon will again be the time of the year, when the friendly, white-bearded dude in red outfit from Lapland will fly around the world, giving presents to everyone.

This year we are able to contribute to your holiday celebration, as we got permissions for distributing not only one, but two new classic Mac games, which you can enjoy during the holiday break:

New application bundles available for download: Scarab of RA and Glider 4

Thanks to the generous permissions by John Calhoun (author of Glider 4), and Rick Holzgrafe (author of Scarab of RA), those two defining samples of the classic Mac gaming history are now again available for everybody to play with during the holidays!

To download and try out these classics, go to the https://mace.software/files page on this site, and you will find links to both Mac and Windows 10 versions of these application bundles, including details about these games.

Although Glider already runs quite well in color mode, it is only available as the “classic” version for the time being, as sound is not yet working in the color mode. I will update the application bundle later in the spring, when the color version is ready for public testing.

NOTE: The current version of M.A.C.E. may cause random “pops” on macOS platforms, and possibly low-volume high-pitch background noise on Windows 10 platform. This is most likely is caused by the old classic sound emulation code we are still using, as it passes the 22255 Hz frequency used by old Macs directly to SDL2. It may apparently, depending on platform, give the job of upsampling it to the host operating system, which in some cases may give varying results depending on the audio hardware and drivers being used. This is a known issue, and it will be fixed when Sound Manager implementation is added in the spring, possibly even before that.

Most recent new tests cases: Holiday Lemmings, Master of Orion, Pararena 2.0

Fitting for the holiday season, we tried running X-Mas Lemmings demo, and for most parts it seems to work pretty well. However, in this game, the most important features missing are still Sound Manager and color cursor support.

Another test case, which we recently added, was inspired by watching a Twitch streamer playing the DOS version of this particular game: Master of Orion. The Mac version seems to work okay’ish in M.A.C.E., but there are some minor glitches:

  • Dialog items are missing from various new game setup dialogs
  • A lot of the color texts are drawn reversed, i.e. the text is transparent but rectangle around is text color. This is probably just a minor glitch in text blitter, which we will investigate and fix soon.
  • Sounds are missing because of the aforementioned missing work on Sound Manager

And as part of getting John Calhoun’s great games to work in our emulator, we also made some fixes which allow Pararena 2.0 to (almost) work in M.A.C.E. The only missing feature, which we know of, is again Sound Manager support. I guess that will be a main goal to aim for during the spring…

More Styled Textedit updates

In other news, there is progress in various parts of the emulator, one of them being the ongoing work on improving Styled Textedit support. Two of the test cases most recently made functional are Speedometer and the aforementioned Pararena 2.0 (which both ironically use it for help screens, by pure coincidence):

There is still some work to do, as for example editing a Styled Textedit field does not yet work, because caret and highlight features are still not updated for multi-style support.

Full list of changes since last post

2020-12-21 03:14:09 +0200 • Fix updating FSSpec name from TE field in StdFile 
2020-12-21 03:12:17 +0200 • Implement StandardPutFile selector (#5) in Pack3  
2020-12-21 02:56:24 +0200 • Add Master of Orion test app to CMake JSON configs
2020-12-21 02:04:46 +0200 • Implement DisposeCCursor trap for Color QD
2020-12-20 01:21:33 +0200 • Merge branch 'master' of
2020-12-20 01:21:23 +0200 • Add Holiday Lemmings Demo CMake JSON configs
2020-12-20 01:19:57 +0200 • Fix handle MP flag check in ResrvMem
2020-12-19 17:36:06 +0200 • Remove colon from CMake JSON config app names
2020-12-18 17:01:07 +0200 • Merge branch 'master' of
2020-12-18 17:00:41 +0200 • Color PICT recording updates
2020-12-17 01:10:47 +0200 • Rename native EqualRect to not collide Win64 API
2020-12-17 01:09:52 +0200 • Make GestaltKeyboardType windows compatible
2020-12-17 01:09:16 +0200 • Update windows icon caches
2020-12-17 01:08:26 +0200 • Update appname in cmake configs to support windows
2020-12-17 00:40:50 +0200 • Fix invalid character in wolf 3d cmake json config
2020-12-10 23:38:31 +0200 • Implement TEGetOffset trap
2020-12-10 23:32:23 +0200 • Add Pararena 2 CMake JSON test application config
2020-12-10 23:31:31 +0200 • Implement TEGetStyle selector for TEDispatch
2020-12-10 23:01:36 +0200 • Add patOr color QD rectangle blitter mode support
2020-12-10 02:44:49 +0200 • Mark rect dirty in b&w CopyMask (+fix warnings)
2020-12-10 01:44:02 +0200 • Add some john calhoun's games to CMake JSON conf..
2020-12-10 01:35:42 +0200 • Use ShieldCursor instead of HideCursor in CopyMask
2020-12-10 01:34:02 +0200 • Some cursor code cleanup (init state, AllocCursor)
2020-12-09 16:07:08 +0200 • Add patOr, patXor & patBic color QD StdLine modes
2020-12-09 13:57:13 +0200 • Fix missing icon check in Dialog Manager item draw
2020-12-08 03:14:20 +0200 • Handle launch failure more gracefully
2020-12-06 05:26:53 +0200 • Add SimpleText test app JSON config to CMake
2020-12-06 05:25:59 +0200 • Tweak Glider 4 CMake config, update 4.06 to 4.10
2020-12-05 16:21:48 +0200 • Fix Pixel2Char output width on TRUE result case
2020-12-05 14:30:26 +0200 • Work on TEStyleInsert; Speedometer help works now
2020-12-04 05:50:01 +0200 • Fix start pt to bottom right clamp in GrowWindow
2020-12-02 22:47:00 +0200 • More CMake tweak + update build number
2020-12-02 20:30:30 +0200 • Update some CMake test app JSON configs
2020-12-02 02:37:25 +0200 • Fix compilation on Xcode 12

TextEdit update: first styled text features added

The progress has been a bit slow in the last month because of us being extra busy at our regular daytime jobs, but we did manage to squeeze some long-awaited changes in. We finally started the work on multistyled textedit support, which is extension added to TextEdit API around System 6.0.4, allowing more than a single style to be applied within text edit records.

As we did not have much time to work on this yet during November, we only have so far roughly these features implemented for style support:

  • Multistyled TE record creation using TEStyleNew
  • Partial setting of appending multistyled text using TEStyleInsert
  • Adjusting existing styles using TESetStyle
  • Drawing multistyled text within the TEDoText’s teDraw selector
  • Measuring multistyled text

And the following style properties can be used within the styles:

  • Style font family
  • Text face (bold, italic, underline, etc…)
  • Font size
  • Text color

From the test applications we have been running, the most important ones requiring styled textedit support have been HyperCard 2.x and Marathon. Below is screenshot of HyperCard 2.0 Home stack, with multistyled text showing right on the welcome screen:

HyperCard 2.0 Home stack with multistyled text

And even more importantly, Marathon terminals can now be opened and operated, which means that we can finally proceed forward in Marathon gameplay to the other levels beyond the first one:

Marathon’s terminal view, with multistyled textedit field used for the text rendering

However, there are still some missing features, of which we need add these most important ones next:

  • Finalize TEStyleInsert to handle given StScrpHandle data properly
  • Implement other multistyle TEDoText selectors, such as teFind and teCaret, to allow actual styled text editing
  • Merge identical adjacent styles after style adjust operations, to avoid excessive style run array growth
  • Add other missing selectors to TEDispatch where needed
  • Also implement any other missing toolbox calls used by textedit where needed

With current speed of progress, the most important ones of the remaining parts textedit API should be usable within a couple of weeks. Unless we get too distracted by playing Marathon 🙂

Full list of changes since last post

2020-11-29 23:52:29 +0200 • Added PortChanged (no-op) selector in QDExtensions
2020-11-29 23:27:24 +0200 • Add JSON cmake config for HyperCard 2.2 test app
2020-11-29 23:26:55 +0200 • Add no-op dummy InitDateCache ScriptUtil selector
2020-11-29 23:22:50 +0200 • Implement partially ScriptUtil's SetEnvirons
2020-11-28 04:47:13 +0200 • Fix clamping of negative offset in TEPinScroll
2020-11-28 04:46:09 +0200 • Fix clamping of below bottom in pt-to-line routine
2020-11-28 03:48:03 +0200 • Implement TEGetPoint selector for TEDispatch
2020-11-27 01:30:49 +0200 • Handle styled text in TEDispose
2020-11-27 00:52:53 +0200 • Refactor TE locals, don't cache dereferenced hTE
2020-11-26 05:38:32 +0200 • Other fixes to make TESetStyle to work & add debug
2020-11-26 05:33:34 +0200 • Get correct style run idx for singlebyte edge case
2020-11-26 05:31:53 +0200 • Fix lineheight calc (wrong index & zero new slots)
2020-11-26 05:28:27 +0200 • Add missing TEApplyStyle byteswap (run->startChar)
2020-11-26 05:27:33 +0200 • Return correct style index @ existing style lookup
2020-11-26 05:26:30 +0200 • Set stCount, stHeight and stAscent for new styles
2020-11-26 05:25:31 +0200 • Add viewRect validation to TEDoText (debug mode)
2020-11-26 05:24:38 +0200 • Set stCount to 1 when inserting a new style
2020-11-26 05:23:52 +0200 • Re-deref TEHandle in TEStyleNew after hText alloc
2020-11-26 05:22:51 +0200 • Increment text pointer in TEFindLine for new style
2020-11-26 05:19:32 +0200 • Fix byteswap in numerator check in StdText
2020-11-25 04:28:32 +0200 • Work on TESetStyle (not yet working, but almost)
2020-11-23 03:24:16 +0200 • Start work on TESetStyle (and TEContinuousStyle)
2020-11-22 05:15:36 +0200 • Add style support to TEGetLineForV
2020-11-22 04:47:30 +0200 • TESetSelect styled text support
2020-11-22 04:45:35 +0200 • More TEStyleInsert work (line heights calculated)
2020-11-22 00:57:54 +0200 • TEStyleInsert progress (TEFindLine style support)
2020-11-21 04:53:05 +0200 • TextEdit BIG refactor & start adding TEStyleInsert
2020-11-21 02:46:25 +0200 • Implement GetCPixel and SetCPixel (ResEdit PACK 1)
2020-11-20 15:59:17 +0200 • Fix colorQD colormap bug, 1&2-bit modes flipped fg
2020-11-20 15:37:02 +0200 • Implement GetEntryUsage trap for palette manager
2020-11-20 15:23:33 +0200 • Implement old-style FONT lookup in RealFont
2020-11-20 14:47:15 +0200 • Fix bugs in styled text rendering, it works now
2020-11-20 13:56:34 +0200 • Don't set/read flags for purged/unallocated handle
2020-11-20 12:44:49 +0200 • Implement TEGetHeight (non-styled) for SimCity 2K
2020-11-20 12:28:04 +0200 • Make SWAP macro single-line safe
2020-11-20 05:48:11 +0200 • Fix for what looks like VERY strange bug in Excel…
2020-11-20 05:45:10 +0200 • Add dummy GetPortNameFromPSN selector @ OSDispatch
2020-11-20 05:44:27 +0200 • Add PPC trap dispatcher w/ dummy PPCInit & PPCOpen
2020-11-20 05:20:57 +0200 • Temporarily increase system heap size
2020-11-20 05:20:15 +0200 • Dummy switcher info data for testing Excel 3.0
2020-11-20 04:36:18 +0200 • Prototype styled TextEdit draw & linewidth measure
2020-11-10 22:48:13 +0200 • Implement TEGetStyleHandle for TEDispatch
2020-11-10 22:28:22 +0200 • Implement dummy IsLayer selector for LayerDispatch
2020-11-10 22:09:35 +0200 • Add TEDispatch, and TECustomHook and TEFeatureFlag
2020-11-10 03:22:20 +0200 • Implement TEStyleNew trap handler for TextEdit
2020-11-10 03:20:44 +0200 • Update Scarab of RA test app config to new version
2020-11-08 13:47:35 +0200 • Optional release version logging/assertions toggle
2020-11-08 13:46:56 +0200 • Minor code cleanups (logging, prep dirtyrects etc)
2020-11-08 13:27:22 +0200 • Fix src/mask address calculation in B&W CopyMask
2020-11-08 00:54:19 +0200 • Reinforce save of auxiliary regs in C->68k calls
2020-11-08 00:42:58 +0200 • Fix clamping of teLength in TextEdit's DoDraw proc
2020-11-04 16:17:43 +0200 • Add GWorld rowbytes calculation method selection
2020-10-31 03:26:53 +0200 • Handle wInGoAway also in SystemClick (Close DA)
2020-10-31 03:25:08 +0200 • Add missing change from the slot manager commit

Marathon fixed & INITs revisited; Fun with Control Panel (cdevs & After Dark)

Marathon color fix

As predicted in the previous post, the culprit for the messed up colors in Marathon was actually just the unfinished implementation of UpdateGWorld. What caused problems in this case was, that the color table in the backbuffer GWorld, which the game uses for off-screen drawing, was created during loading when the intro color table was active, and thus it “inherited” that active color table from the GDevice. However, UpdateGWorld was expected to update new colors from the GDevice when entering the game, and as it was not implemented, that left the old color table intact and messed up the colors. The current implementation of UpdateGWorld handles most of the cases, but does not do the existing pixel data conversion cases, which some applications might required (TODO-assertions were added there though, to signal when we encounter such case).

One handy source (literally!) for debugging Marathon’s backbuffer behaviour was the Marathon source code, which Bungie published quite some time ago at: http://infinitysource.bungie.org/

Also, we noticed that Marathon has pretty decent support for mouselook, so we enabled the relative mouse mode for test JSON config, and it feels pretty playable with it.

Here are some screenshots of the first level of Marathon running (finally) with proper colors:

Here are also a couple screenshots of one of the demo levels played by the game after staying idle in the main menu:

The first level seems to be completely playable until the end, except that the terminals on the level do not work yet (they require the Styled TextEdit implementation, which still remains on the TODO list – however with quite higher priority now, as so many applications seem to need it already). This is especially tricky as the teleport used at end of the level requires that feature also to pass the level 🙂

INITs revisited

Some time ago, we played around a bit with the INIT loading during startup, and used it to load After Dark screen saver. However, the handling of memory during startup was not optimal; basically BufPtr, which is the top of memory usable for application zone, and 68k stack pointer, were colliding, which caused random crashing.

As the color support is already quite nice for most basic cases (in indexed color modes), we wanted to see how After Dark would work in the color mode, so we did some quick fixing for this. Basically we moved the stack to near middle of the memory range, in a area which was very unlikely to hit the top of system zone, and way below the BufPtr limit, which After Dark wants to lower. This seems to fix that problem for now.

Control Panels

Another important thing we wanted was to allow the After Dark control panel to be usable, so that the screensaver modules could be configured. As we don’t have yet our own control panel to support running cdev resources (the control panels), we temporarily tried out what happens if we run the actual, real Control Panel desk accessory from System 6 – seems that there almost no issues getting this to work, as seen below:

System 6’s “General” Control Panel (cdev) running in the System 6’s Control Panel Desk Accessory (DRVR) running on M.A.C.E.

Surprisingly, bunch of the functionality in “General” control panel was directly working; The desktop pattern editor was almost completely functional, but required implementation of the SetDeskCPat trap, which it uses to apply modified pattern on the desktop. Menu blinking and caret flash controls work directly (as TextEdit and Menu Manager were built to use those low memory globals), and speaker volume control works when run in the “classic” (monochrome Mac Plus style) mode – color version still has the unfinished Sound Manager implementation. The date & time controls show placeholder value as the International Utilities routines are still unfinished, and RAM cache does nothing 🙂

System 6’s “CloseView” Control Panel (cdev) running in the System 6’s Control Panel Desk Accessory (DRVR) running on M.A.C.E.

Even more interestingly, the CloseView control panel (above) also work almost without any fixes; The Key1Trans and Key2Trans low memory procedure pointers were needed to allow shortcut keys to not crash. The zoom controls and zooming work neatly and follow mouse properly, as the cdev does some clever patching of a number of QuickDraw routines, so all the native C drawing is directed to a secondary buffer, which the CloseView cdev draws actually on the screen – when active, it seems to replace WMgrPort and WMgrCPort with the backbuffer, and even modifies ScreenBase to make CopyBits work properly! However, there is still some issue with the algorithm it uses to track “dirty” area, when magnification is off but closeview is active, as it leaves some artifacts on the screen when for example moving windows.

After Dark Control Panel (cdev) running in the System 6’s Control Panel Desk Accessory (DRVR) running on M.A.C.E.

But most importantly, After Dark is now also working. There were a couple fixes needed to make the control panel itself, and some modules, work – such as blend and subpin transfer modes for rectangle blitter, and a number of System 7-type temporary memory handle allocation functions (which for now just directly map to regular handle allocations in the application zone).

But most importantly, the rather complex and deep mix of native C, 68k DRVR, INIT and cdev code with patched traps included, surfaced a rare register trashing condition in the invocation of 68k code from native code – this was only present as a crash when using “Demo” feature of After Dark control panel! The problem was, that as certain 68k procedure calls needed arguments to be passed in registers, they were not saved before the call – and as native C part of the toolbox does not use the 68k registers, and thus does not internally save them, certain 68k -> native -> 68k call combinations resulted with registers being trashed. After adding the fix by implementing proper register save/restore, After Dark is much more stable, and looks great! Here are screenshots of some of the modules which work now (you can click image for larger view):

There are still a number of things to fix though; for example, MultiModule does not work yet (cannot configure modules for some reason), and other modules have unique cases which need to be handled separately (such as “Down the Drain” requiring GetCPixel), and some modules occasionally spitting “Not enough memory” error, but this is good as it provides a lot of test cases for the future!

Also some of the other desk accessories were kind of working and not; some such as “Mouse” control panel won’t have any affect (mouse is right now completely controlled by host operating system), “Monitors” requires proper Slot Manager implementation for handling the graphic devices to not crash, “Color” (probably) needs to have support for modifying the labels in System file, and “Sound” does not do much without Sound Manager. We will in future also try out other cdevs to see what happens 🙂

Full list of changes since last post

2020-10-30 04:38:37 +0200 • Rename SMSlotInterruptGlobals for clarity
2020-10-30 04:36:28 +0200 • Iterate INIT resources in LoadNamedINITFile
2020-10-30 04:33:32 +0200 • Enable relative mouse mode for marathon cmake JSON
2020-10-30 04:33:05 +0200 • Add control panel files to TeachText cmake json
2020-10-29 23:57:28 +0200 • Implement CloseCPort trap
2020-10-29 23:53:50 +0200 • Also add subPin mode to pattern rectangle blitter
2020-10-29 23:26:20 +0200 • Arithmetic blend mode in pattern rectangle blitter
2020-10-29 23:24:53 +0200 • Save & restore ALL 68k register on C->68k calls
2020-10-29 17:40:16 +0200 • Fix byteswap bug in UPP routineCount
2020-10-28 03:55:16 +0200 • First part of Key(1/2)Trans lowmem proc support
2020-10-27 07:09:52 +0200 • Add dummy TempFreeMem/NewHandle/HLock/DisposHandle
2020-10-27 05:52:11 +0200 • Add ShutDown Mgr (+ dummy ShutDwnInstall selector)
2020-10-27 05:30:12 +0200 • Make SystemTask more compatible with DAs
2020-10-27 03:05:01 +0200 • Implement SetDeskCPat trap handler
2020-10-27 02:49:46 +0200 • Implement PixPatChanged selector for QDExtensions
2020-10-27 02:43:19 +0200 • Also fix the hack in boot-time temp memory size
2020-10-27 02:42:05 +0200 • Temporarily move SP out of below BufPtr at startup
2020-10-27 02:41:05 +0200 • Fix a really stupid DRVR call bug (HLock missing)
2020-10-13 01:03:50 +0300 • Set RAMBase during startup
2020-10-06 01:17:40 +0300 • Dummy placeholder for WriteParam trap handler
2020-10-06 01:16:12 +0300 • Fix directory ID for indexed non-HFS GetFileInfo
2020-10-06 01:14:03 +0300 • Implement (kind of) TempTopMem OSDispatch selector
2020-10-03 17:27:12 +0300 • Add SlotManager dispatcher (and SVersion selector)
2020-10-03 03:33:17 +0300 • Fix memory leak in ClosePort
2020-10-03 03:30:57 +0300 • Add rest of UpdateGWorld (except pixmap data copy)
2020-10-03 02:33:45 +0300 • Handle _MapRgn wideOpen case; Fixes Marathon map
2020-10-03 01:34:23 +0300 • Clear MemErr in Lock/UnlockHandle on success
2020-10-02 16:30:08 +0300 • Fix warning in LayerDispatch from missing #include
2020-10-02 05:07:00 +0300 • Pass right pixelDepth to NewGWorld in UpdateGWorld
2020-10-02 04:57:55 +0300 • Some progress on UpdateGWorld implementation

Notarized test applications & Other fixes

Most of the past couple weeks have again been a bit quiet due to busy time at the daytime job, but there are a couple improvements which are worthy of creating an update in this development diary:

Notarized macOS downloads

The set of (macOS) app bundles on the downloads page have finally been notarized, after Toni enrolled again in (& paid for) the Apple developer program for one year required to do it. So, there won’t be any longer any trouble with the scary warnings on the recent macOS versions.

The downside is, that the default notarized applications require macOS 10.9, but we’ve left the old, unsigned application bundles for Mac OS X 10.6+ compatibility, for now.

There are not much functional differences between the most recent notarized applications and the previous builds, as most of the recent progress has been on improving color compatibility, and other features in applications not currently part of the set of the downloadable app bundles.

Escape Velocity map “works” now

After a couple days of debugging, the code crashing Escape Velocity when opening the map was isolated. However, curiously it would appear there might be a bug in Escape Velocity causing the issue; in map, the game keeps track of four data structures of 10 bytes each (which I assume may contain coordinates for at least the nebula and asteroid field pictures), but in the map drawing code it accidentally accesses a fifth element in the array, which will contain random data at end of the allocated memory area. I briefly tested this part on a real Mac running Mac OS 9 – and it exhibited the same behaviour, but luckily SectRect intersected the offending corrupted coordinates, before running CopyBits, which would crash on negative source rectangle size; in M.A.C.E. as a workaround the StdBits (which CopyBits uses) was reinforced to ignore negative transfer sizes, which appears to be invalid operation on the QuickDraw on real Macs.

The Escape Velocity map window now works without crashing

There were also a couple other minor fixes:

  • MakeFSSpec did not populate the FSSpec fields correctly for non-existing file, which was required behaviour when using it to create FSSpecs for creating new files with FSpCreate
  • The “search & replace” mode in _Munger trap did not work correctly; The mission list was using this to replace “<DST>” with destination name, but in the case the search string was not found, it would keep appending it in the end of string infinitely
  • StandardGetFile selector in Std File Package was missing typeList pointer, causing the “Open pilot” dialog to not display any files

Thexder

We recently also tested Thexder on M.A.C.E., which seems to be working quite well in both “classic” monochrome mode (with audio), and in the color mode. The controls are also quite responsive, although having played previously the DOS version it took a short bit of learning to play with the numpad controls, where vertical and horizontal movement keys are combined, as holding down multiple arrow keys is disabled in the Mac version, perhaps to avoid conflicting with the use of space bar as fire button.

This game is quite rare in the sense that it is the only game which we know that uses 2-bit (four-color) mode in the color version; this however works as a perfect test case for the 2-bit display mode testing and debugging. Interestingly, the monochrome version of the game seems to have some bugs (such as enemies not following player horizontally in the same way as in color version, and also some walls destructible by lasers seem to not work correctly). But as these bugs appear also on real Macs and minivmac, it seems that at least the emulation is working as intended.

Palette fix for Loony Labyrinth

As mentioned in the previous post, Loony Labyrinth was having some color corruption problems, which seemed to only affect the playfield. After a quick evening of debugging, it appeared that as the game used custom palette for intro screens, it was trying to reset color table back to default using RestoreDeviceClut selector of PaletteDispatch, which contained some code which was left previously as unimplemented to-do task. With a quick implementation to release the palette links from the GDevice, and doing a reallocation of color entries to restore original palette, the playfield now appears and displays as it should:

Loony Labyrinth playfield now displays correctly

Also, to celebrate this in combination with the physics fixes from earlier this month, here’s a video of how well the game’s own AI is able to play the game in the demo mode:

Loony Labyrinth playing one game of pinball in the auto demo mode

Although this does not fix Marathon’s color table issue, we luckily we have identified the problem with that game, and will be fixing it before next week. More about that in the next update!

Full list of changes since last post

2020-09-29 03:12:46 +0300 • Finalize (mostly) RestoreDeviceClut implementation
2020-09-29 02:13:02 +0300 • Fix PortList allocation & add PortList debug tool
2020-09-27 03:26:40 +0300 • Fix missing typeList in StandardGetFile
2020-09-27 02:56:59 +0300 • Fix "search&replace" mode in _Munger trap
2020-09-27 02:19:43 +0300 • Implement FSpSetFInfo for HighLevelFSDispatch
2020-09-27 02:17:32 +0300 • Add dummy empty NewAlias and NewAliasMinimal
2020-09-27 02:15:44 +0300 • Populate properly fnfErr result case in MakeFSSpec
2020-09-22 11:09:13 +0300 • Merge branch 'master' of
2020-09-22 11:09:08 +0300 • Minor tweak in colorQD detection in CDEF 63
2020-09-22 02:06:41 +0300 • Fix warnings causing errors on the new Xcode
2020-09-21 03:26:21 +0300 • Fix StretchBits crashing on negative srcRect width
2020-09-21 03:24:14 +0300 • Fix ADF filenames starting with % to map correctly
2020-09-21 03:23:00 +0300 • Add OrbQuest test application JSON config to cmake
2020-09-10 13:22:57 +0300 • Fix vfs file dependency command in cmake
2020-09-10 11:57:35 +0300 • Tweak Thexder JSON config
2020-09-10 11:57:03 +0300 • Pixel-doubling support for 4-bit (16-color) mode
2020-09-10 11:56:35 +0300 • Pixel-doubling support for 2-bit (4-color) mode
2020-09-10 04:13:30 +0300 • Fix cmake to allow again unsigned apps in OSX 10.6
2020-09-10 03:19:58 +0300 • Also return success code for decoding opOpColor…
2020-09-10 03:18:11 +0300 • Add Thexder test app to cmake json configs
2020-09-10 03:17:43 +0300 • Implement opOpColor in PICT playback

Many fixes: DIVU.W, Bitfields, Time Manager; Prince of Persia 2…

A lot of has happened past week, perhaps thanks to the summer finally starting to be over, and us having more time for the project again. Here’s a breakdown of most important advances made last week:

Fixed the DIVU.W overflow calculation

A long-time bug in unsigned 16-bit division instruction was finally found, and fixed by Pukka! We accidentally calculated overflow using signed 32767 limit, while it should have been unsigned 65535. This immediately fixed highly noticeable glitches in two of the test applications, Vette! and Test Drive II: The Duel (both ironically of same racing simulation genre):

Before the fix, Test Drive II had noticeable warping and glitching in the road near the bottom, and the polygons in Vette! had sometimes incorrect tangents, causing them to get messy depending on the angle of polygon edge.

This also fixed the “Divide overflow” bug occurring in SoftPC, which was weirdly happening on certain times of day, which does indicate that some calculation related to the computer clock time was failing because of the incorrectly signaled overflow. Now SoftPC works quite reliably.

Bitfield instruction fixes

One recently added test application, Prince of Persia 2, used a lot of the bitfield instructions for the SHAP resource drawing on the screen (apparently RLE/LZ decoding), which originally had a really messy artifacts:

But after fixing the instructions, the levels finally looks as they should:

Time Manager fixes

Besides the bitfield instructions, Prince of Persia 2 also uses Time Manager heavily for timing, and that surfaced a couple nasty bugs in the code, which were fixed.

There are still so oddities to investigate, for example the intro sequence does not advance past second screen yet, and the death and level completion delays do not trigger during the gameplay.

Sadly these fixes do not (yet) fix the one special case in Speedometer, where Dhrystone test does not work properly because of some issues that may be related to Time Manager (it starts the same timer twice, and stops it before test, so it never runs).

Keyboard handling threading bug

There was also a nasty bug in keyboard handling, which had rather surprisingly managed to stay hidden for a quite long time; Basically, the SDL2 key events that were handled by the keyboard code on main thread had chance to accidentally modify data structures and especially the A0 register, while 68K was running in VBL interrupt handler, causing in some rare cases the A0 register value to get corrupted; This caused a lot of crashes in Prince of Persia 2, and is most likely the cause of a very rare crash in Wolfenstein 3D. The offending part code was made thread-safe, which fixed this particular crash completely.

Sound in SoftPC

This was a very minor fix, but still worth mentioning; the reason for why there was no sound in SoftPC was caused by the fact that the application was setting the sound driver volume from the SPVolCtl low memory global, which had been set to zero on startup. By improving the PRAM simulation to populate all low memory PRAM values with sensible default values, the sound works now nicely in SoftPC!

Dark Castle “_Random” bug

As Pukka guessed last Christmas, the reason for buggy behaviour of robots, and some other minor glitches, in Dark Castle was indeed related to calling of the “_Random” trap! Of the last weekend was spent on searching the bug in other places at first, such as robot behaviour code, until we noticed something strange.

In Apple documentation, and all references known to us, the QuickDraw random number generator is defined simply as a Pascal type function with the following signature (in IM: Mathematical and Logical Utilities, 3-51):

pascal short Random (void);

Which means, that the function takes no arguments, and returns a 16-bit signed integer on stack. But, however, the way Dark Castle used was rather odd:

This screenshot of ResEdit showing disassembly of the part of Dark Castle code calling _Random shows, that it actually ignores the result value at offset 000B60 by discarding it off stack! And later looking at the code, it was actually using value in D0 instead…so, a quick look at System 7 _Random trap handler gives some insight to this:

Here actually it is visible, that on real Macs, the trap trashes a number of registers, and has the side-effect of leaving result value in the D0 register (being a toolbox trap, the trap dispatcher does not clean up any of the registers, unlike it does for some of registers after calling OS traps).

So, to fix Dark Castle, we added extra code to set up the D0 register as the game expected it, and everything started to work perfectly.

Some other progress from these changes

A couple other test applications seemed to benefit of these changes too, although they still need a bit of work to make sense: Loony Labyrinth now loads correctly after bitfield instructions were fixed (and physics in it also work correctly after the DIVU.W fix), and Marathon now actually runs and is playable with the Time Manager fixes:

Interestingly both of these games still seem to suffer from having colors completely messed up, but besides this glitch, they appear to be playable and run quite nicely.

Bonus video

And to celebrate getting SoftPC finally to work properly, I recorded this short video of M.A.C.E. running SoftPC running David Murray’s (The 8-bit Guy) Planet X-3:

You can find more information on Planet X-3 here: http://www.the8bitguy.com/product/planet-x3-for-ms-dos-computers/

Full list of changes since last post

2020-09-09 23:29:07 +0300 • Merge branch 'master' of
2020-09-09 23:28:59 +0300 • Update CMake scripts to support Apple notarization
2020-09-09 21:14:01 +0300 • add missing addressing fixes
2020-09-09 20:32:11 +0300 • memory addressing fixes
2020-09-09 20:26:50 +0300 • Fix compilation error in QDColorStretchBits.c
2020-09-09 20:00:29 +0300 • Fix some warnings in StretchBits color blitters
2020-09-09 19:59:57 +0300 • Fix some warnings in CodeResourceWDEF1
2020-09-09 19:26:58 +0300 • Fix return value in C_PlotCIconHandle
2020-09-09 19:18:10 +0300 • Merge branch 'master' of
2020-09-09 19:16:59 +0300 • fixes for bitfield and divuw instructions
2020-09-07 04:23:28 +0300 • Tweak more Dark Castle CMake JSON configs
2020-09-07 00:04:11 +0300 • Simulate PRAM (SysParam) to make SoftPC sound work
2020-09-06 23:04:58 +0300 • Update MACE version in CMake config
2020-09-06 13:14:44 +0300 • Color pixeldouble & (disabled) CRT simulation
2020-09-06 03:45:52 +0300 • Update trap generator XLS file
2020-09-06 03:44:13 +0300 • Tweak Dark Castle JSON config settings
2020-09-06 01:52:48 +0300 • Hack Random result value in D0 to fix Dark Castle
2020-09-05 03:54:17 +0300 • Get correct tmCount in RmvTime for non-first tasks
2020-09-03 02:16:54 +0300 • Fix the conversion of positive count in PrimeTime
2020-09-02 19:30:04 +0300 • Fix threading issue with keyboard input module
2020-09-02 19:28:30 +0300 • Don't crash on purged handles in GetHandleSize
2020-09-02 19:27:42 +0300 • Fix a lot of Time Manager bugs & clean up the code
2020-09-02 19:23:45 +0300 • Fix typing of region handle to CMDoDrawControls
2020-08-31 23:01:40 +0300 • A simplified MakeFSSpec implementation, for POP2
2020-08-31 04:17:44 +0300 • Add missing EqualRect change in EmuUtils.h
2020-08-31 04:16:59 +0300 • Fix GetCCursor crash when ResLoad was FALSE
2020-08-31 04:16:08 +0300 • Add dummy SCSIDispatch for Loony Labyrinth
2020-08-30 21:32:44 +0300 • Add Prince of Persia 2 to test app JSON configs
2020-08-03 01:45:10 +0300 • Make NewGWorld's rowBytes to work w/ Color VETTE!
2020-08-01 20:08:42 +0300 • Record PICT2 opHiliteColor, opOpColor &opDefHilite
2020-08-01 19:45:53 +0300 • Record HiliteBit as opHiliteMode in PICT2 format

Post-midsummer update; Eric’s Ultimate Solitaire

As we estimated previously, the progress has been a bit slow during the summer months, with so many things to do in “real life”. But there have been a few things here and there that have been tweaked in the moments, when there has been a moment of time. Here’s a brief breakdown of the key things that have been changed:

In attempt to get some picky color games to work (such as Warlords 2, Warcraft and A/10 attack), a number of hacks have been added:

  • A number of placeholder gestalt functions, with dummy values to allow the games to pass startup tests (for example, Warlords 2 appears to not start unless the system tells it supports truetype fonts…)
  • Some help manager’s Pack14 selectors, such as querying balloon help mode and setting the balloon help mode
  • A number of process manager selectors in OSDispatch, which seem to be used by some apps to check if it is in foreground in multitasking environment
  • More dummy placeholders for Apple Events. There was not yet time to research futher, but I’m guessing some of the apps are expecting kAEOpenApplication (‘oapp’) event at startup to proceed correctly. The apple events will most likely be implemented parallel to better process manager support later, so that any dependencies with EPPC can be verified)
  • subPin mode for the awesome looking alpha-blended shadows in Warlord’s 2 windows

More work is still needed to make the above games work, assumedly the lack of AppleEvents right now is blocking a number of them from working.

Eric’s Ultimate Solitaire Sampler also required implementing (& fixing) some things:

  • Some color blitter updates (blend and srcBic transfer mode improvements, and other minor improvements). The game uses these to do nice blending effects on the highlighted cards, including blending the card “slots” with background. These appear now to draw exactly like on real Mac.
  • ‘PICT’ opOrigin opcode was fixed, if a picture would have a non-zero origin, the fact that V and H values were swapped would cause it to be drawn at a wrong location

One of the most important changes was finally fixing the SANE’s Extended 80-bit to 64-bit double encoding/decoding bugs. The basic exponent/fraction conversion was already fixed over one year ago, but the special cases were completely broken (such as NaN, Inf and zero values). Also, clamping the exponent/fraction values when doing conversion to lower bit size was broken, instead of actually getting clamped these values would wrap around…not good! Most notable result of these fixes is that Speedometer now displays properly zero (0) as the initial score instead of 2.0.

Below are some screenshots of this awesome-looking card game:

There are still a couple issues left to fix, most notably the game complains about missing resources on each startup, even though it still succeeds to open. And as the sound manager implementation for the color version environment is still unfinished, there are no sounds yet. But mostly, the game works quite well, and is very playable, as you can see from the number of games and time played statistics screenshot above 🙂

At the moment, Toni is working on getting the picture recording to work in color mode (PICT2 support), which is required to get some editors to work properly in ResEdit, and Pukka is researching the full extension word format of 68020 emulation, which when will allow a large number of new color applications to work.

Full list of changes since last post

2020-07-31 22:06:34 +0300 • More work on PICT2 recording (pixpats in-progress)
2020-07-21 05:29:26 +0300 • Support grafProcs' putPicProc for StdPutPic
2020-07-21 05:01:31 +0300 • Implement CopyPixPat trap
2020-07-16 22:41:09 +0300 • Initialize pnMode correctly in OpenPicture
2020-07-16 22:40:40 +0300 • Fix PICT verb recorder bugs (pnSize & swap pnMode)
2020-07-16 05:13:03 +0300 • Make StdComment recording version 2 compatible
2020-07-14 05:47:44 +0300 • OpenCPicture & ColorQD OpenPicture abstraction
2020-07-08 05:31:55 +0300 • Tweak Float64 to Float80 conversion (denorm exp)
2020-07-07 14:34:46 +0300 • Other Float80 special cases; NaN, denormals, infs
2020-07-04 20:35:08 +0300 • Handle zero special case @ 80-bit float conversion
2020-07-04 12:28:21 +0300 • Fix mixed up H and V delta values in opOrigin
2020-07-04 12:26:43 +0300 • Add non-colorizing stretch blitter for srcBic mode
2020-07-04 04:05:17 +0300 • Fix opOrigin picture opcode
2020-07-04 02:35:44 +0300 • Fix missing alignment shift of arithmetic blitters
2020-07-03 14:39:58 +0300 • Implement FSUBS for SANE's FP68K dispatcher
2020-07-03 14:34:15 +0300 • Improve direct color support in stretch blitter
2020-06-28 01:38:25 +0300 • Add indexed region blitter for "blend" (0x20) mode
2020-06-28 01:36:23 +0300 • Add Eric's Ultimate Solitaire Sample test app
2020-06-22 02:45:59 +0300 • Fix inverted handling of TE record's active flag
2020-06-22 02:44:50 +0300 • Add AE and ProcMgr control configs to environment
2020-06-14 04:58:58 +0300 • Add Prince of Destruction test app to cmake JSON
2020-06-13 21:42:12 +0300 • Add missing procNotFound define to MacErrors.h
2020-06-13 21:41:27 +0300 • Add A10 Attack! Demo test app to cmake json config
2020-06-13 19:13:46 +0300 • Add dummy GetNextProcess
2020-06-13 19:13:10 +0300 • Add some missing data types & enums to Processes.h
2020-06-12 04:08:43 +0300 • Add dummy InitEditionPack & EditionManager module
2020-06-12 03:56:06 +0300 • Add dummy RestoreDeviceClut selector
2020-06-12 03:44:33 +0300 • Properly fix the previously disabled optimization
2020-06-12 00:10:50 +0300 • Add dummy AESetInteractionAllowed Pack8 selector
2020-06-11 17:48:36 +0300 • Fix InvalMenuBar to really work (Warlords 2 menus)
2020-06-10 20:57:41 +0300 • Disable a buggy copybits colorization optimization
2020-06-10 19:09:03 +0300 • subPin mode color region blitter (WarLords 2 demo)
2020-06-10 19:08:15 +0300 • Fix invCT pointer in color mapping (skip header)
2020-06-10 13:59:56 +0300 • Fix WDCB allocation: list size is bytes, not count
2020-06-10 05:57:31 +0300 • Dummy HMIsBalloon & HMSetBalloons for Pack14
2020-06-10 05:51:30 +0300 • GetCurrentProcess, GetProcessFromLayer, SameProc..
2020-06-10 05:29:24 +0300 • Implement AECreateDesc in Pack8 (AppleEvents)
2020-06-10 05:28:23 +0300 • Add MacAppleEvents.h (+move old stuff from Events)
2020-06-10 05:27:17 +0300 • Tweak trap generator to allow "result" param name
2020-06-10 04:49:08 +0300 • Add dummy OSDispatch & GetProcessInformation
2020-06-10 04:17:52 +0300 • Fake gestaltLaunchControl flag for Warlords 2
2020-06-10 03:52:44 +0300 • Fix script mgr gestalt functions (emIntlGlobals)
2020-06-10 02:35:00 +0300 • Add 'a/ux', 'edtn', 'help', 'pop!', 'font', 'stdf'
2020-06-10 01:23:22 +0300 • Add dummy AEInteractWithUser selector for Pack8
2020-06-10 01:14:16 +0300 • Add 'kbd', 'hdwr', 'evnt' and 'os ' gestalt funcs

GWorlds and PixPats

Since the last update, there has been progress on many features, but especially on the following ones to highlight:

GWorlds

The GWorld routines are practical utility functions for easy creation and handling of off-screen color ports, relieving the developer from a lot of mundane tasks for allocating the memory structures and house-keeping them. In the old “classic” QuickDraw, the developers were forced to do all this by themselves, but on other hand, the old-style QuickDraw had a lot less complexity and fewer data structures. The color QD requires maintenance of PixMap structures, and possibly “fake” GDevice handles with unique color tables and inverse color lookup tables, etc. The routines which color version were implemented this time were (* indicates ones that previously existed for “classic” QD’s GWorld wrappers):

  • NewGWorld
  • LockPixels*
  • UnlockPixels*
  • DisposeGWorld
  • GetGWorld
  • SetGWorld
  • CTabChanged
  • AllowPurgePixels
  • NoPurgePixels
  • GetPixelsState
  • SetPixelsState
  • GetPixBaseAddr
  • GetGWorldPixMap

The games which benefitted most of the new GWorld routines were Wolfenstein 3D, SimCity 2000 and Civilization. It is also possible other games are utilizing them, but these were the ones first encountered in the test suite:

Wolfenstein 3D

PixPat support

Another new feature added in the color QuickDraw are the PixPat patterns. As old QuickDraw only allowed 1-bit monochrome patterns, these PixPats have much more flexibility allowing multi-color patterns and also higher resolutions (most commonly seen as powers-of-two from 8 to 64 pixels, and up to 256 colors, although the PixPat data supports also “direct” pixel data).

The interesting feature of these “pixel patterns” is the fact that they actually use regular PixMap data as the pattern storage, so that a lot of internal routines for PixMap manipulation were directly helpful in the implementation of the color patterns. The most code needed for pixpat-specific drawing were the conversion to target depth (using the shader PixMap translators), and handling the special pattern modes in blitters, with repetition of pattern with variable-size dimensions.

Glider 4.0 in color

The first games requiring use of PixPats were Glider 4.0 and Siege of Darkwood – but as a nice side effect, we now also have support for using color patterns on the desktop!

Other stuff

There were also many other minor improvements, some of which include:

  • Finally a proper region-clipped color blitter (was on TODO list for a long time…)
  • 32-bit PICT pixel data support, needed for Escape Velocity
  • CopyBits & ScrollRect, for Civilization and SimCity 2000 map scrolling
  • A bunch of new blitter modes
  • Partial resouce read support for SimCity 2000
  • Abstracted resource loading as a magic “CheckLoad” vector, to make AutoDoubler-compressed applications work (the one we encountered was the color version of Lemmings)
  • MANY bug fixes and other improvements (complete list of everything at the end of this post)

New videos

Since the the last post, we have two new videos of test applications running in color mode. First is Glider 4.0, which seems to now be playable, benefitting especially from the most recent transparent arithmetic transfer mode support:

Glider 4.0 running in color mode on M.A.C.E.

Also, here’s video of Wolfenstein 3D running (the lag is from QT video capture, game itself runs quite smoothly):

Wolfenstein 3D running on M.A.C.E.

And of course as Sound Manager is not yet implemented, there is no audio in either videos.

Status of some of the color test applications

There are also some other games which are starting to get more functional in color mode, here’s a brief update on where they’re at right now:

Most of these games run nicely, but there are some common issues still to be resolved:

  • Menu drawing still need to be updated to support color mode properly
  • List Manager does not yet handle hilite mode properly
  • Scroll Bars are still rendered as monochrome versions only
  • Standard File dialogs have still issues with color mode (folder popup menu, hilite mode, etc)
  • No sound yet because of incomplete Sound Manager implementation
  • Horizontal stretching for pixmap data is not yet implemented (although vertical stretching is), so horizontally scaled text/images do not yet appear properly
  • A lot of missing blitter modes (they will be written as needed in the first pass, but will be generalized and optimized later so that all cases will be properly covered)

There are also a couple cases with application-specific problems:

  • Maelstrom is playable & smooth, but gets stuck at end of level screen probably because of missing Sound Manager Implementation
  • Civilization has a rare bug where inverse color tables appear to break down after playing the game for some time
  • SimCity 2000 has a palette manager bug where a couple of palette entries go to wrong slots, causing a couple specific colors to not display properly (mostly visible in the title screen, and “Dispatch Firefighters” map sprite)
  • Escape Velocity gets to main menu, but crashes due to some unresolved 68k cpu emulation bugs which Pukka is investigating

The status page will be updated in the coming weeks to reflect this new status.

Full list of changes since last post

2020-04-07 00:38:42 +0300 • Add pixpat patOr mode for color rectangle blitter
2020-04-07 00:31:42 +0300 • Add srcBic support to color rectangle blitter
2020-04-07 00:30:52 +0300 • Fix outline/shadow text style in color text render
2020-04-06 21:29:15 +0300 • Do 68K VM stack guard magic check for native fra..
2020-04-06 01:07:31 +0300 • Set bg color in SetWinColor, fix Siege of Darkwood
2020-04-06 00:39:03 +0300 • Fix crash when decoding pixpats from PICT resource
2020-04-05 23:10:26 +0300 • Fix GetPalette bitmasking (missing window redraws)
2020-04-05 05:21:26 +0300 • Indexed transparent arithmetic region renderer
2020-04-05 04:39:00 +0300 • Indexed transparent arithmetic rectangle renderer
2020-04-05 03:22:26 +0300 • Indexed transparent arithmetic scanline renderer
2020-04-04 16:53:34 +0300 • Clean up old commented-out legacy code
2020-04-04 16:52:27 +0300 • Handle undefined EnvDefaultColorDepth case
2020-04-04 16:51:21 +0300 • Handle arithmetic mode setup for color mapping
2020-04-01 22:24:46 +0300 • Update test desktop background pattern
2020-04-01 03:01:26 +0300 • Color desktop ppat (forced on for now for testing)
2020-04-01 02:47:14 +0300 • Fix 8x8 pixpat expansion
2020-04-01 01:59:00 +0300 • Implement (mostly) pixpat conversion & rendering
2020-04-01 01:57:35 +0300 • Separate pixel translation from stretch blitter
2020-04-01 01:43:46 +0300 • Clear CGrafPort refs to pixpat in DisposePixPat
2020-03-30 16:59:25 +0300 • Add (partial) FillCRect/Oval/Arc/Rgn/Poly
2020-03-30 16:00:04 +0300 • Add EnvDefaultColorDepth for app-specific default
2020-03-30 15:32:31 +0300 • Fix region masking bug of diagonal Line/LineTo
2020-03-30 15:30:07 +0300 • Fix ErasePoly (typo from copy-paste)
2020-03-30 11:53:03 +0300 • Fix right-to-left color rectblit & right-edge mask
2020-03-30 04:57:07 +0300 • Add srcXor mode for non-colorizing stretch blitter
2020-03-30 04:54:25 +0300 • Color QD version of polygon operations
2020-03-30 04:47:10 +0300 • Add region-clipped color blitter & fix LOT of bugs
2020-03-30 04:44:10 +0300 • Fix invalid masking in srcCopy in translating blit
2020-03-30 01:18:15 +0300 • Fix iteration of region 3-only non-rect case
2020-03-28 21:53:06 +0200 • Fix inverted hilite flag check in colorized WDEF 0
2020-03-27 21:39:58 +0200 • Fix TextEdit locals saved forecolor overlap bug
2020-03-27 20:45:13 +0200 • Add color support also to WDEF 0 zoom box drawing
2020-03-27 19:34:27 +0200 • Add color support to WDEF 0 growbox drawing
2020-03-27 16:36:51 +0200 • Add (partial) color QD support for ScrollRect
2020-03-27 15:18:16 +0200 • Add Loony Labyrinth test app to CMake JSON configs
2020-03-27 15:17:43 +0200 • Implement SaveFore/Back & RestoreFore/Back
2020-03-27 02:46:11 +0200 • Fix (again) AnimatePalette
2020-03-27 01:36:19 +0200 • Set default palette in GetNewWindow/GetNewCWindow
2020-03-26 23:12:07 +0200 • Implement ReadPartialResource in ResourceDispatch
2020-03-26 22:26:03 +0200 • Fix HCreateResFile (dirID mishandled)
2020-03-26 21:02:04 +0200 • Improve StdText CGrafPort/GWorld compatibility
2020-03-26 21:00:46 +0200 • Fix CloseResFile stack frame mismatch
2020-03-26 20:11:11 +0200 • Implement SetPixelsState and AllowPurgePixels
2020-03-26 19:54:40 +0200 • Implement GetPixelsState selector in QDExtensions
2020-03-26 19:46:06 +0200 • Implement SetGWorld selector in QDExtensions
2020-03-26 19:33:15 +0200 • Implement GetGWorldPixMap selector in QDExtensions
2020-03-26 19:16:17 +0200 • Implement GetGWorld in QDExtensions
2020-03-26 19:12:42 +0200 • Implement Palette2CTab
2020-03-26 18:45:36 +0200 • Add SimCity 2000 test app to CMake JSON configs
2020-03-26 17:24:03 +0200 • CopyBits improvements (fix Escape Velocity crash)
2020-03-26 02:59:02 +0200 • Add 32-bit to indexed color conversion to blitter
2020-03-26 02:57:00 +0200 • Fix rgb PICT data unpack for rowBytes > 250
2020-03-26 02:56:00 +0200 • Implement DisposeCIcon
2020-03-25 22:09:57 +0200 • Support 'PICT' packType=4 RGB data (run-packed)
2020-03-25 20:45:05 +0200 • Start collision check from current link, not next
2020-03-25 19:08:43 +0200 • Fix color blitter for <=32bit wide transfers
2020-03-25 18:35:49 +0200 • Conditionalize Paletter Manager debug log output
2020-03-25 18:34:59 +0200 • Handle collisions in inverse color table lookup
2020-03-25 14:08:12 +0200 • Validate input in SetEntries & clear cached fonts
2020-03-25 03:01:34 +0200 • Fix UInt16/SInt16 RGB delta bug in palette update
2020-03-25 01:13:22 +0200 • Add missing A6 setup for the CheckLoad wrapper
2020-03-25 01:05:40 +0200 • Add secret "CheckLoad" hook (AutoDoubler support)
2020-03-25 00:57:35 +0200 • Add color Lemmings JSON to CMake test apps configs
2020-03-24 22:34:47 +0200 • Clamp cursor hotspot between [0, 15]
2020-03-24 22:34:15 +0200 • Fix color CopyBits thePort/dstBits comparison bug
2020-03-24 19:55:58 +0200 • Extract color QD rect blitter to own module
2020-03-24 19:30:09 +0200 • Implement DisposeGDevice (used in DisposeGWorld)
2020-03-24 14:47:56 +0200 • Implement color QD version of ClosePort
2020-03-24 04:24:57 +0200 • Unreserve palette entry when cleared (single GD)
2020-03-24 04:23:41 +0200 • Set MemErr to noErr in ReservMem on success
2020-03-24 02:35:37 +0200 • Fix negative dstLeft corruption @ B/W stretch blit
2020-03-23 21:01:59 +0200 • Implement DeleteMCEntries
2020-03-23 20:50:33 +0200 • Paint window (and invalidate) on ActivatePalette
2020-03-23 20:49:14 +0200 • Draw desktop pattern for PaintOne(nil) case
2020-03-23 20:44:03 +0200 • Fix AnimatePalette for srcIndex > 0 cases
2020-03-23 01:41:36 +0200 • Fix GetCatInfo bug by previous fix (non-WDCB case)
2020-03-23 01:27:40 +0200 • Minor menu color entry manipulation tweaks
2020-03-23 01:25:58 +0200 • Fix monochrome QD compilation error
2020-03-22 23:36:53 +0200 • Implement SetEntryColor
2020-03-22 23:24:53 +0200 • Implement GetPalette trap for Palette Manager
2020-03-22 22:09:37 +0200 • Extract PaletteDispatch routines to own C module
2020-03-22 21:42:58 +0200 • Add Ultimate Doom test app to JSON configs
2020-03-22 21:42:24 +0200 • Add CTabChanged and (partial) DisposeGWorld
2020-03-22 07:33:06 +0200 • Give more CPU time for 68020+ mode
2020-03-22 06:46:10 +0200 • Fix buffer size bug in NewGWorld w/ pixelDepth = 0
2020-03-22 03:55:04 +0200 • Implement FCMPS in FP68K (SANE) for Wolf3D
2020-03-22 03:42:46 +0200 • Improve bits opcode (9x) for non-indexed support
2020-03-22 03:37:10 +0200 • Implement NoPurgePixels selector
2020-03-22 03:36:45 +0200 • Fix unassigned pmBounds.left bug in NewGWorld
2020-03-22 02:23:21 +0200 • Implement color QD version of NewGWorld
2020-03-22 02:22:18 +0200 • Resolve WDCB to DirID in GetCatInfo ioFDirIndex>1
2020-03-21 18:50:18 +0200 • Add 'qdrw' Gestalt selector (Quickdraw features)
2020-03-21 04:44:26 +0200 • Fix pixpat opcodes in DrawPicture
2020-03-21 04:42:32 +0200 • Implement unpacked pixmap data load in DrawPicture
2020-03-21 04:40:28 +0200 • Fix CloseWD crash (ignore ioNamePtr)
2020-03-21 03:43:35 +0200 • Implement CopyPixMap
2020-03-21 02:26:20 +0200 • Fix GetPenState bug (caused gray fills everywhere)
2020-03-21 01:33:43 +0200 • Implement color QD version of ScrnBitMap
2020-03-21 01:20:54 +0200 • Hack tmp SoundBase to make Glider 4 happy in color
2020-03-21 01:19:08 +0200 • Implement color CopyMask (untested!)
2020-03-21 01:17:37 +0200 • Fix missing argument deref in color pat conversion
2020-03-21 01:16:34 +0200 • Add 'vm ' Gestalt selector (returns 0 for no VM)
2020-03-21 01:14:12 +0200 • Add HWPriv & dummy FlushData/FlushInstructionCache
2020-03-20 19:18:33 +0200 • Fix colorQD highlight bug of radio/checkbox button
2020-03-20 19:09:02 +0200 • Implement grayishTextOr mode for StdText
2020-03-20 19:07:55 +0200 • Implement GetGray selector for PaletteDispatch
2020-03-20 19:06:06 +0200 • Tweak signature of rgb delta calculation to UInt16
2020-03-20 18:20:45 +0200 • Implement patBic mode in pattern rect blitter
2020-03-20 06:22:31 +0200 • Fix StdGetPic, handle byteCount as unsigned UInt16
2020-03-20 06:20:48 +0200 • Implement GetPixBaseAddr selector in QDExtensions
2020-03-20 05:27:15 +0200 • Fix masking bug in color stretch blitter
2020-03-20 03:38:11 +0200 • Add a bunch empty dummy SoundDispatch placeholders
2020-03-20 02:57:14 +0200 • Implement QDError trap
2020-03-20 02:54:26 +0200 • Implement FSpOpenResFile and FSpCreateResFile
2020-03-20 02:52:57 +0200 • Implement HCreateResFile
2020-03-20 02:29:20 +0200 • Add semi-dummy ResolveAliasFile selector
2020-03-20 02:08:52 +0200 • Add Escape Velocity test app to cmake configs
2020-03-20 02:08:30 +0200 • Add missing file from previous commit
2020-03-20 02:08:18 +0200 • Add Pack12 & Fix2SmallFract+SmallFract2Fix+RGB2HSL
2020-03-20 00:06:06 +0200 • Fix signature of SwapMMUMode
2020-03-19 23:25:45 +0200 • Fix text styling buffer overflow in color QD
2020-03-19 23:22:36 +0200 • Apply kernMax in color font renderer
2020-03-19 19:18:59 +0200 • Update & re-seed GDevice pmTable in SetEntries too
2020-03-19 16:01:13 +0200 • 4-bit debug palette view
2020-03-19 16:00:59 +0200 • Implement SetPortPix trap
2020-03-19 01:26:06 +0200 • Add fake SwapMMUMode trap
2020-03-19 01:24:19 +0200 • Add dummy 'snd ' Gestalt selector
2020-03-19 01:23:39 +0200 • Dummy SoundDispatch (& dummy SndPlayDoubleBuffer)
2020-03-19 00:40:09 +0200 • Add Maelstrom test app to cmake configs
2020-03-19 00:39:47 +0200 • Dispose auxCtlRec also in DisposeControl trap
2020-03-19 00:29:57 +0200 • Fix 'cctb' ID=0 bug
2020-03-19 00:15:34 +0200 • Implement ProtectEntry and ReserveEntry traps
2020-03-18 23:53:47 +0200 • Fix RS stack frame mismatch in FrameRect
2020-03-18 23:53:10 +0200 • Implement TestDeviceAttribute & SetDeviceAttribute
2020-03-18 23:44:13 +0200 • Implement GetCWMgrPort trap