This is just a quick & short status update to let everybody know we’re still alive. This past month has just been really busy in the real work, life and with other things, so not much progress has been done in this period.
However, to give some essence for this update, on this weekend we went through a bunch of potential candidate applications to test emulation with, and although many of them still show the need for work to be done, we did get at least one game to partially work in this short time, Flight Commander 2, so here’s a bunch of screenshots of it for your enjoyment:
The game itself is only playable until first enemy move, after which seems that some bug, possibly in SANE emulation, is causing the game to get stuck in an infinite loop. Will look into that in the nearby future.
Besides slow month of May, the early summer will also be a little slow, but we’re still very focused on working on the project. But certainly this small break will give us the energy and motivation to continue with full speed later in the summer. And we will also do some other cool 68k Mac stuff if we have time – we will be giving more details when we get more progress in things.
Full list of changes since last post
2020-06-01 00:41:01 +0300 • Add FLOG2X to Elems68K
2020-06-01 00:16:42 +0300 • Fix wideopen region expansion (crashed in DiffRgn)
2020-05-31 23:50:07 +0300 • Add StandardGetFile selector(6) to Pack3(StdFile)
2020-05-31 23:47:14 +0300 • Add Flight Commander 2 Demo test app to cmake json
2020-05-31 23:46:53 +0300 • Add Warlords 2 Demo test app to cmake json configs
2020-05-31 22:33:07 +0300 • Ignore dotfiles in mac icon converter
2020-05-31 13:23:28 +0300 • Add in-progress CDEF 1 color support (unfinished!)
2020-05-31 13:23:03 +0300 • Disable some truetype font assertions in font mgr
2020-05-31 13:22:32 +0300 • Add (unfinished) str2dec conversion, to fix later
2020-05-31 13:21:28 +0300 • Add Lode Runner(TLR) test app to cmake JSON config
2020-05-31 13:21:02 +0300 • Add Warcraft II Demo test app to cmake JSON config
2020-05-31 02:34:57 +0300 • And also fix selector def of HMGetBalloons, 0 args
2020-05-31 02:33:37 +0300 • Fix GetGray selector definition in PaletteDispatch
2020-05-31 02:32:04 +0300 • Add dummy HMGetBalloons to Help Manager (Pack14)
2020-05-31 02:31:05 +0300 • Check the default mode in SetDepth for result code
2020-05-31 02:30:08 +0300 • Add Warcraft Demo to test app cmake JSON configs
2020-05-31 02:29:52 +0300 • Add PowerPong to to test app JSON configs
Since the last update, there has been progress on many features, but especially on the following ones to highlight:
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):
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:
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.
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!
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)
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:
Also, here’s video of Wolfenstein 3D running (the lag is from QT video capture, game itself runs quite smoothly):
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
The ongoing epidemic in the world these days is sadly the focus of the news and is touching in some way all of us, and we hope the people reading this will stay safe and healthy during these challenging times. Although our close ones have not (yet) been affected directly by the situation, the impact on our daily lives is already taking effect, as some of us are currently working remotely from home, borders are being closed, and toilet paper is being stockpiled.
One way for us to deal in these times when our lives are getting limited, is to focus our energy on the things we love, one of which for us is working on this project. And hopefully our ongoing efforts will encourage others to look forward into the future with positive thoughts.
Since last post, the focus has been on improving color support on multiple fronts, and testing the new functionality on color-capable test applications. Last month, we already got gameplay to work in KYE, and now two more games are starting to give good results; Railroad Tycoon and Prince of Persia.
Font rendering & window widgets
One important part missing from KYE (and all apps in general) was the font rendering. This was visible as the absence of menu items and window titles, which works now for the basic cases:
Also the window widgets finally work, which can be seen in the above screenshot as the goAway box is visible in topleft corner of the Window. The WDEF 0 supports all ‘wctb’ parts now as the original System 7 WDEF did, and colorizes them using a method which should visually give nearly equal results.
At the time of writing this, text rendering in color mode only works for non-styled, and non-scaled text. The styling requires use of an extra offscreen buffer, which we haven’t yet had time to implement for the color version, and scaling requires stretching color blitter, which is not yet implemented.
Menu, Dialog and Alert color tables
As the basic text rendering works now, one interesting game to try it out with is Railroad Tycoon, because that game utilizes heavily custom color tables for menus, windows, dialogs and alerts:
The above screenshot demonstrates all of those features in one picture:
The blue menus are colorized using ‘mctb’ resources
The red dialog background comes from ‘dctb’ resource (which is equal to both ‘actb’ and ‘wctb’ resources in both structure and usage)
The white text in labels (and red background for them) comes from ‘ictb’ resources
Color ‘PICT’ Pictures
Another new feature is the (partial) support for color pictures, that is, PICT resources containing pixmap data in addition to 1-bit bitmap data and methods for controlling the color-specific features in CGrafPorts. With a couple opcodes improved with color support, we got this:
The picture data reading and blitting works nicely, except that the Railroad Tycoon logo has some glitches on left and right edges. It might be related to unfinished region clipping code, but I suspect we might also need to double-check the alignment handling. The main menu in Railroad Tycoon looks a bit messed up at the moment, as the pen pattern setting is probably having some minor issues (it should have solid black pattern, but defaults to 50% gray-dither pattern at the moment).
And the Glider 4.0 main screen also works now with the picture rendering code:
One thing that was a bit off in the Railroad Tycoon intro and main menus was also the color table, because the game actually uses a custom palette for a nice sepia tone. This meant that next up was the implementation of Palette Manager, as up until now only the default system color lookup table (‘clut’ resources for individual color depths) was used to colorize everything.
The first use case, as mentioned above, was Railroad Tycoon, which was a bit easier to deal with, as it uses ‘tolerant’ colors in its palette. The palettes in the game are actually 16-color palettes, replacing the entire color lookup table, but they work also nicely in the 256-color mode which we tested:
On the left, you can see that the skin and map have highly ‘carroty’ orange shade, while on the right, with correct palette, they appear in nice sepia tones as intended. We also added a small palette debug feature to show state of color lookup tables. In this case, the ‘tolerant’ colors replaced the closest matches in the system ‘clut’, making it appear nearly same.
Another game which uses palettes heavily, is our beloved Prince of Persia game. Unlike Railroad Tycoon, PoP uses actually ‘animated’ colors, as it depends on AnimateEntries/AnimateEntry to do color animation, AND nice fade-to-black palette effect.
The above screenshots show the progress made during ‘animated’ color implementation. There were a lot quirks and stumbles along the way, but here are key findings of Palette Manager regarding Prince of Persia:
It uses ‘animated’ palette entries to do color animation (fade-to-black, twinkling stars, flash effects)
The black & white entries of palette are manually set by the game as ‘tolerant’ to allow mapping them to correct black & white at indices 255 and 0 respectively
The game maps each of the 200+ colors dynamically to the ColorTable indices using PmForeColor, and polling the resulting color index
It appears to convert the images itself to correct indices using the mapping data it gathered
The CopyBits calls to blit graphics depend highly on a “same bit-depth, same color table seeds and uncolorized” optimization, where we skip creation of color translation table in the blitter. This is also one part which requires the black to be mapped correctly at index 255, as it allows detecting that using combination of white background (index 0) and black foreground (index 255) skips the need for colorizing
The game almost works now, and is actually playable, but encountered a strange crash inside VBL handler during the first level (VBL queue got corrupted, the screenshot above is from the moment when the crash happened). We need to investigate that further in the near future.
Prince of Persia color intro video
To celebrate the advancements made in M.A.C.E., we made a short video of how the color version of emulator looks like when running Prince of Persia:
Note that the bottom-right corner shows the rather ‘hacky’ palette debugger, which nicely demonstrates how the game is using AnimateEntries to do color fades & effects.
There are a lot of things still to do, but the progress seems promising. For example, we need to get menus to actually work (the saving & restoring menu background is not yet adapted to support color mode), text rendering needs the support for styling, QDExtensions needs desperately GWorld routines, region blitter needs to be finished, etc. This is a short breakdown which is blocking what test apps:
Glider 4.0: Needs CopyMask, etc.
Indy 3: Needs TestDeviceAttribute, etc.
Siege of Darkwood: Needs FillCRgn, etc.
Crystal Quest: Needs blitter improvements, etc.
Railroad Tycoon: Needs font styling, CopyMask, etc.
Civilization: Needs GWorld routines
Wolfenstein 3D: Needs GWorld routines
When we get those tasks to advance, we should be able to run more color games in the near future. Stay tuned!
Full list of changes since last post
2020-03-18 03:28:52 +0200 • Implement colorizing srcBic pixel blitter 2020-03-18 03:27:51 +0200 • Implement AnimateEntry (used in PoP flash effect) 2020-03-18 02:29:02 +0200 • Tweak debug palette display 2020-03-18 02:27:32 +0200 • Implement SetEntryUsage (part of the PoP fixes) 2020-03-18 02:24:11 +0200 • No color translate if seeds match (fix PoP colors) 2020-03-18 02:19:39 +0200 • Implement AnimatePalette 2020-03-17 19:40:11 +0200 • Fix MakeITable buffer size bug at 5-bit resolution 2020-03-17 02:14:27 +0200 • Fix Entry2Index for animated palette entries 2020-03-17 01:09:16 +0200 • BIG PaletteMgr commit - first ActivatePalette pass 2020-03-17 01:05:39 +0200 • Implement (most of) SetEntries Color Manager call 2020-03-17 00:03:48 +0200 • Use TheGDevice defaults in MakeITable w/ zero args 2020-03-12 22:01:48 +0200 • 8bit clut debug overlay (to debug Palette Manager) 2020-03-12 21:56:06 +0200 • Implement (most of) PmForeColor/PmBackColor 2020-03-12 19:11:35 +0200 • Implement (most of) Entry2Index 2020-03-12 19:09:51 +0200 • Handle both index & sequence cluts in video driver 2020-03-12 17:25:54 +0200 • Add some missing color QD error numbers 2020-03-12 17:24:56 +0200 • Implement Index2Color in Color Manager 2020-03-11 03:19:45 +0200 • Update trap generator source CSV file too 2020-03-11 03:19:24 +0200 • Implement (most) of ActivatePalette (no updte yet) 2020-03-11 03:18:39 +0200 • Fix IODone invocation for SlotVideo DRVR driver 2020-03-11 03:17:46 +0200 • Fix byteswap bug in Color QD PortList insertion 2020-03-11 03:16:47 +0200 • Switch SetPalette to NSetPalette to use SInt16 arg 2020-03-11 03:16:25 +0200 • Implement (most) of SetPalette (no update yet) 2020-03-11 00:58:34 +0200 • Implement DisposePalette 2020-03-10 04:58:59 +0200 • Clear TmpResLoad at SetResLoad exit 2020-03-10 04:58:16 +0200 • Add empty stub for SetEntryUsage & AnimatePalette 2020-03-10 02:34:26 +0200 • Add gestalt function for 'vers' selector 2020-03-10 02:33:55 +0200 • Fix plotting of color icons in Dialogs 2020-03-10 02:32:49 +0200 • Add dummy SetEntries to Color Manager 2020-03-10 02:32:25 +0200 • Add PaletteDispatch & dummy Entry2Index & HasDepth 2020-03-10 01:52:01 +0200 • Add color QD old-style pattern patXor rect blitter 2020-03-10 01:51:09 +0200 • Add cmake JSON config for wolfenstein 3D 2020-03-10 01:10:52 +0200 • Update QDExtensions selector source csv too 2020-03-10 01:10:20 +0200 • Fix bug handling of version opcode in DrawPicture 2020-03-10 01:09:36 +0200 • Fix signatures of QDExtensions selectors 2020-03-10 01:08:09 +0200 • Add dummy SetCCursor for Glider 4 and Civilization 2020-03-10 01:07:09 +0200 • Add dummy HMGetHelpMenuHandle and Help Mgr module 2020-03-09 23:47:50 +0200 • Add $AB03 trap for 32-bit QuickDraw detection 2020-03-09 23:46:39 +0200 • Add cmake config for Color VETTE! 2020-03-09 22:21:59 +0200 • Partial DrawPicture bits opcode $9x color support 2020-03-09 22:13:15 +0200 • Add empty dummy MakeRGBPat placeholder 2020-03-08 21:32:21 +0200 • Make PICT opcodes $00 through $0B color-compatible 2020-03-08 21:29:45 +0200 • Fix WDEF 0 forecolor bug in monochrome mode 2020-03-08 03:03:28 +0200 • Support control colors in 'ictb' resouces also now 2020-03-08 03:00:51 +0200 • Add color QD Std/Fill/Frame/Paint/Erase/InvertOval 2020-03-08 02:41:23 +0200 • Init DrawPicture playback state for color ports 2020-03-08 02:39:59 +0200 • Fix invalid item index given for text colorization 2020-03-07 17:43:39 +0200 • Restore old colors after menu title draw 2020-03-07 17:14:45 +0200 • Load cctb in GetNewControl & call SetControlColor 2020-03-07 17:13:01 +0200 • Empty stubs for PmForeColor and PmBackColor 2020-03-07 16:48:05 +0200 • Fix swapped fore/background color in menu titles 2020-03-07 16:46:21 +0200 • Implement GetGDevice and SetGDevice 2020-03-07 16:24:30 +0200 • Dialog text & editfield 'ictb' color table support 2020-03-07 15:37:12 +0200 • Paint window background using 'wctb' wContentColor 2020-03-07 15:19:54 +0200 • Fix fallback of missing wctb entry to default wctb 2020-03-07 15:01:12 +0200 • Temporary placeholder for color desktop painter 2020-03-07 15:00:20 +0200 • Improve color QD CopyBits 2020-03-07 04:49:17 +0200 • Fix CopyBits case for WDEF 0 widgets 2020-03-07 04:02:30 +0200 • Makes text colorization work, but breaks CopyBits 2020-03-07 01:09:07 +0200 • Improve CDEF 0 colorQD support (cctb colorization) 2020-03-06 02:41:55 +0200 • Fix detection of color mode in WDEF 0 2020-03-06 01:57:51 +0200 • Draw colorized goAway box in WDEF 0 2020-03-06 01:44:48 +0200 • Implement partial CopyBits color QD compatibility 2020-03-06 01:03:42 +0200 • Improve WDEF 0 color compatibility (in progress) 2020-03-05 18:45:48 +0200 • First proto of color font renderer (srcOr mode) 2020-03-05 18:44:11 +0200 • Export QDRepeatPixels helper 2020-03-05 18:40:48 +0200 • Fix source scanline alignment bug in color stretch 2020-03-04 00:21:02 +0200 • Fix byte-swap bug in 1-to-32-bit pattern expansion 2020-02-26 22:52:01 +0200 • Extract B&W text renderer into a separate module 2020-02-26 22:49:52 +0200 • Move B&W rectangle blitter code to a new folder 2020-02-26 04:47:18 +0200 • Tweak RS local variables names to avoid conflicts 2020-02-26 04:46:38 +0200 • Abstract StdText for color QD & 255+ char support 2020-02-26 04:42:59 +0200 • Don't allocate storage for debug string in release
It is now two years since we started this project, and so far the progress is looking promising. At this point, it is good to take a brief overall look at where we are right now… so far, we have a lot of phase #1 goals accomplished:
Good enough 68000 emulation to run majority of games designed to use that CPU.
Majority of “classic” QuickDraw traps implemented to allow black & white games which needs them to work. Also hardware-level VIA page-swapping support for double-buffered games such as Dark Castle and Continuum.
Complete “.Sound” driver functionality, including ~99% coverage of low-level sound hardware emulation to allow games such as Dark Castle, Tetris and Pirates! to have working sound.
External file system emulation with HFS metadata support abstracted to ADF files, with almost all read/write operations tested working (except delete/rename, which have so far been rarely needed)
Basically implemented most of toolbox calls needed to, get out of the 87 test applications, 78 to work in at least somewhat usable way, and 43 to function near-perfectly.
Ability to run (or try running) the test applications/games as native OSX application bundles (and now with Windows support, also as windows EXE files), with full mouse/keyboard support, fullscreen/windowed and pixel-double support. Sound also mostly works but the SDL buffering needs some tweaking especially on windows…
As the toolbox is quite large, and there is a large number of traps/selectors which are rarely needed, and have not been encountered in the applications we have been testing vigorously. These APIs are still unimplemented, but they will be eventually added to the emulation. However, because these missing phase #1 features have such minor impact on most test applications, we also have started to work on some phase #2 features which are not only beneficial for a lot of current test suite, but which also will allow a huge number of new applications to be added to our tests:
68020/030/040 emulation, which Pukka has already done a lot of progress on.
Color QuickDraw support, which was started after Christmas (more about that later in this post – very important for getting color games to work!)
Some preliminary progress on System 7.x APIs (FSSpec calls, Folder Manager, Time Manager, Script Manager, etc.).
Because of the fact that as we are implementing new features in a parallel fashion, we don’t have any fixed schedule for milestones. But realistically we expect to get a lot progress on the color support during the spring, which is the biggest bottleneck for getting much larger test application coverage. The downside of this is, however, that a “generic” emulator release will get delayed, because we want it to be as complete as possible, so that you won’t have to suffer from the incomplete features until we get everything polished. You can always follow the test application coverage (and overall progress) on our status page at https://mace.software/status/.
Color QuickDraw progress & first color game (somewhat) playable: KYE!
Since the previous post, majority of work as focused on getting source-mode blitting to work within the color hardware and Color QD API emulation. One of the easiest test cases for that purpose is a fun game called KYE, which was one of personal favorites of Toni on his LC II in early 90’s. The reason why this particular game is nicely suited for this early-stage testing is the fact that it uses mostly just PlotCIcon to draw all of its “sprite” graphics. Thanks to this, we did not have to work on a huge number of different calls at once, but were able to focus on getting that single call working. That way we could get something visible progress on the screen, instead of the invisible “under-the-hood” type of progress which has more impact on the long term.
For curiosity, below is a set of screenshots taken during the PlotCIcon development, which shows how the bugs were squished one by one until the rendering was finally okay:
Here’s a screenshot of latest stage of PlotCIcon functionality in KYE:
As you can see in the screenshot, icon rendering is working nicely, but text rendering is still completely missing. We also updated the WDEF 0 to have most of color support, so it uses now shading from the default ‘wctb’, leading to authentic System 7-style look and feel. Because of early stage of implementation, the color blitter has right now following limitations:
Blitter only works on “indexed” targets (1-8 bit pixmaps), i.e. not on “direct” (16/32-bit) screens
Only supports indexed sources too
Only simple srcCopy and srcOr modes supported (non-colorized)
No stretching support yet (only 1:1 scaling)
No arithmetic modes yet
Focus at this stage is on accuracy – that is, getting the output results to look exactly same as on the original, “real” Color QD – so performance is far from optimal for now. Leaves a lot of space for blitter optimization in future though…
Probably a lot of other use cases which I can’t recall right now…
Below is also a short video of level 2 gameplay:
Anniversary bonus! PT-109 gameplay video
To celebrate the two-year anniversary, we also recorded 90 minutes of PT-109 gameplay to show the current state of that game’s compatibility with M.A.C.E. below:
This video shows what to expect when we get the “generic” emulator released some day in the future. For now, we can only share the video of this awesome game as it is sadly copyrighted – but we have a bunch of freely available games at our downloads page at https://mace.software/files for both Mac OS X and Windows 64-bit.
If you are interested in keeping up with our progress (now that we start the third year with full speed) you can follow this blog, or one or more of the following:
It’s again the Christmas season, and time again for the annual holiday update, now for the second time! As our greeting to you, here’s the (apparently now traditional) Christmas tree easter egg screenshots from Dark Castle running the latest M.A.C.E. version (it appears only when the game notices that the system time is set to 25th of December in UTC time):
Dark Castle was one of the first games we actually tried M.A.C.E. on over one year ago, and it was already working quite well on the previous Christmas. At that time, the CPU bugs were preventing FireBall levels from being played, but luckily those issues were fixed during this summer, and now all the levels are in playable state.
There are however still minor hiccups, such as weirdly behaving robots, dungeon key being always on the right-most side in the Trouble 3 level, Mutants spawning too quickly, Burning Eye not shooting fireballs, etc. Pukka thinks a common denominator for these issues might be some random number generation code in Dark Castle, but it still needs to be analyzed further.
To celebrate the progress, we recorded a short video of Dark Castle gameplay (with Christmas tree in The Great Hall) on this Christmas Day for your entertainment – all rooms were visited, but sadly I was not lucky enough to topple the Black Knight off his throne this time, even after two tries:
Teasers for 2020
Sadly the holiday season has been very busy, which has also slowed down the project progress a little bit. There’s still some teasers for upcoming features which are almost complete, but not yet ready for release:
After we tested Bolo in M.A.C.E., we got inspired by the network support it has and had a idea about trying to implement a simple MacTCP driver in M.A.C.E., which would allow us to try out Bolo’s network gameplay we used to play with long time ago. However, the non-standard IODone mechanism, and Bolo’s tricky network performance measurement code, there is still a bit of work to be done to get that into playable state. However, MacTCP Ping seems to be working already quite well, including the DNS resolver:
There is though a “record route” option in “Options” menu, which we could not test because for some reason even using the same option on the real ping (ping -R) on Mac OS X causes the echo packets to get lost.
A more proper introduction about how this all works will be added later when we get the entire driver to work. For now, at least UDP calls to the .IPP driver seem to be working on an “okay” level, although they have so far been really tested only with Bolo, and only for the very first couple UDP packets exchanged by it.
As many people have requested, we are already experimenting with adding a third platform into the build system, Windows (from Microsoft, the notorious arch-enemy of Apple Computer 🙂
We already fixed a couple thousand build errors, but there is still a lot of work to be done. For example, the MSVC compiler has a lot of source-code level differences in the C compiler, which need to be abstracted to allow the code to compile both with LLVM/GCC and MSVC targets. Additionally, the networking, file system APIs – and a bunch of other things we have – are POSIX/Unix-only at the moment, which need Win32/64 equivalents to be implemented.
Beyond those two work-in-progress features, we are also still working on increasing stability through bug fixing and debugging. You can always follow the progress on this blog, and check the list of compatible applications in the “Status” page. Thank you for you interest in our efforts, have a merry Christmas!
Full list of changes since last post
2019-12-21 14:09:25 +0200 • Fix VerticalRetraceMgr byteswap bug in inVBL flag
2019-12-21 14:08:18 +0200 • Add UDPWrite implementation to MacTCP emulation
2019-12-20 03:14:50 +0200 • First successful UDPRead in MacTCP call (w/ Bolo)
2019-12-20 01:00:52 +0200 • Implemented UDPCreate for MacTCP driver
2019-12-20 00:01:36 +0200 • Add MacWWW test app (not working, needs color QD!)
2019-12-20 00:00:21 +0200 • Make MacTCP ipctlEchoICMP support async operations
2019-12-19 23:57:26 +0200 • Improve DA/DeviceMgr enums (accXXX, ioInProgress…)
2019-12-19 23:55:07 +0200 • Fix byteswap bug of dCtlDelay in SystemTask
2019-12-18 19:22:56 +0200 • Disable unused 128-bit float test code
2019-12-17 04:29:47 +0200 • Reinforce interrupt safety of device manager calls
2019-12-17 04:02:39 +0200 • Don't close the MacTCP driver
2019-12-15 05:23:27 +0200 • Add very primitive foundation for MacTCP driver
2019-12-15 03:42:24 +0200 • Add a couple more kCStackBased mixedmode handlers
2019-12-15 03:40:51 +0200 • Add missing prWrErr from earlier PRAM modification
2019-12-15 03:39:53 +0200 • Make RSReturnValue argument safe for function call
2019-12-15 03:37:15 +0200 • Add the DRVR 22 MacTCP (.IPP) driver to fake ROM
2019-12-15 03:35:32 +0200 • Add MacTCP Ping test app to CMake JSON config
2019-12-15 02:48:56 +0200 • Fix indexing for GetFileInfo/SetFileInfo
2019-12-15 02:45:45 +0200 • Start work on kCStackBased MixedMode routine type
2019-12-15 02:44:19 +0200 • Fix off-by-one-byte bug in FindFolder fld# handler
2019-12-13 03:25:39 +0200 • Add dummy ReadXPRam and WriteXPram for Bolo
Since the previous update, focus has been mostly on improving the compatibility and stability of existing test applications through debugging, bug fixes and finishing some partially implemented features. This has so far had mostly effect on Excel, THINK Pascal and Fokker Triplane Flight Simulator:
Microsoft Excel 3.0 progress
Seems that Excel was complaining the out of memory error only because it could not locate the ‘PACK’ 6 resource (IntlUtils package). Adding a ‘PACK’ wrapper resource to System file, in similar fashion to the one which was added earlier for ResEdit as ‘PACK’ ID = 0, allowed this check to pass. After that a couple of new IntlUtils selectors were needed, with a couple file manager tweaks, and now Excel is able to start up successfully (albeit with a alert about not finding Excel, which can be passed).
It seems that a lot of tools and features are already functional, including basic worksheet creation, cell selection/modification, shape drawing, basic formatting etc. However, the most important feature, text input to allow entering data to worksheet cells, still requires TEDispatch to be implemented.
THINK Pascal 4.0 progress
One application which surfaced a lot of bugs and issues was THINK Pascal 4.0, here’s a rough summary of the issues found & ‘fixed’:
Reallocation of resources was not working properly in ChangedResource. Resource Manager did not save & restore active resource entry when measuring space available between current and next resource, which caused the new resource allocation in growth case to end up in wrong resource entry in the map (the next one was reallocated instead of current).
Removing name was attempted even if no name existed, causing resource names to get corrupted
RmveResource was not offsetting the types properly when removing the last instance of a given type.
The internal routine RGetResourceCount was trashing the resource entry pointer in resource manager’s stack state, causing some resources to be skipped altogether in iteration.
SetHandleSize was allowing locked blocks to move during the operation, which was explicitly told in Inside Mac documentation would not happen. This bug caused sometimes locked memory to move, with dereferenced pointers becoming invalid, causing crash during pascal code compilation.
A very rough approximation of MoveHHi was added. It works well enough to allow THINK Pascal to move resources out of the way to not prevent heap fragmentation from growing size of locked handles – but still causes sometimes fragmentation enough to surface this issue. However, this is for now enough to get the projects compile roughtly 2 to 3 times in one session before memory fragmentation kicks in and crashes the compiler.
The resource copy phase of THINK Pascal surfaced a bug in CountResources/GetIndResource, where CurMap was used instead of TopMap (CurMap should only be used when operating on 1-deep versions of the calls, Count1Resources/Get1IndResource). With this fix, the resource file copy phase succeeds.
Using “Transfer” command in THINK Pascal can be used to launch another app – in most cases, the application that was just compiled. However, the application zone teardown was – and still is – largely unfinished, having a number of issues. One that was fixed, was that resource manager attempts to release and purge all font caches with allocations in the application zone, which would be invalid upon launching the new program.
GetScrap trap had a minor issue, in which the case of hDest being nil it would crash, instead of just returning the scrap size as it was supposed to. This fixes the clipboard to (almost) work in THINK Pascal.
Now even a bit more complex programs can be compiled using THINK Pascal, for example one of Toni’s old games from as early as 1998. However, there are still minor glitches in various places:
Sometimes clipboard operation does not work on the first attempt.
Replacing existing application with “Build application” & replace dialog does not yet work because _Delete trap is still unfinished.
Sometimes text editing has very tiny minor selection glitches (when doing “Search again” in source code, where previous hit was selected and visible in area which was scrolled only little up, the old selection is left on when highlighting the new one).
Because resource map compaction is (still) unfinished, each time resources are updated and/or written in resource files, the file size grows indefinitely (by size of modified resource).
Compiling only works a couple times (2-3) on large projects, before heap fragmentation crashes the compiler.
The “Go” option does not yet work, because when running applications inside the THINK Pascal IDE, it does not actually launch a separate applications process for it. Instead, it loads the application “on top” of the pascal IDE, and in order to do this, it wraps a lot of its handlers to toolbox routines, and to do this, it manipulates the trap tables directly. This however assumes the toolbox trap table is located at 0xC00 on mac plus (0x75)-type machine, while it is currently located at 0xE00 (later machines). Because some currently used low memory globals overlap this area in non-compatible ways (for example, cursor device), they need to be adjusted a bit to behave differently on “Classic” type environment (like on real Mac Plus), and other way on later (slot-based / color-QD) environment.
Fokker Triplane Flight Simulator
It seems that the only issue causing Fokker Triplane to freeze upon starting new game was actually the lack of low-level interrupt handler emulation. The game attempted to override system VBL handler by adding its own VBL interrupt handler in the Lvl1DT low memory area containing the list of VIA’s Level 1 interrupt handler table, and as it was never called, caused the lock-up. The VBL, and 1-second timer, have now proper handlers in this low memory area, which is checked upon triggering the emulated VBL interrupt. This also includes the familiar performance optimization, where unpatched handlers skip the MixedMode interface with direct method call. It seems that with this change, the game is now fully playable with sound effects (although not thoroughly tested).
Full list of changes since last post
2019-11-16 04:08:45 +0200 • Lowlevel VIA interrupt handler for Fokker Triplane
2019-11-13 03:50:11 +0200 • Tweak SndNewChannel to not crash ResEdit
2019-11-09 09:03:38 +0200 • Dummy OpenDeny/OpenRDeny (=>paramErr for local FS)
2019-11-09 07:51:53 +0200 • Workaround for mapping wideOpen Rgn in DrawPicture
2019-11-09 07:49:02 +0200 • Move File Manager commands to separate module
2019-11-09 07:47:37 +0200 • Move SoundDriver test code to separate module
2019-11-09 02:29:58 +0200 • Add dummy BitMapRgn trap for aWorm
2019-11-06 05:40:10 +0200 • Respect port clipRgn in CopyBits
2019-11-06 04:31:42 +0200 • Fix edge cases in UnpackBits
2019-11-04 21:32:35 +0200 • If GetScrap argument hDest = nil, return only size
2019-11-04 11:31:38 +0200 • Clear font caches when closing res file w/ fonts
2019-11-04 04:16:41 +0200 • Add IUMagString & improve Transliterate for Excel
2019-11-04 03:09:38 +0200 • Fix Count…/GetIndResource to begin at TopMap
2019-11-04 02:15:21 +0200 • Add memLockedErr enum missing from previous commit
2019-11-04 02:14:56 +0200 • (HACK) MoveHHi added - works, but not as in specs!
2019-11-04 02:12:08 +0200 • Fix SetHandleSize for locked blocks (don't move)
2019-11-04 02:06:36 +0200 • Fix tail check in the zone check
2019-11-04 02:04:53 +0200 • Fix name allocation in AddResource
2019-11-04 02:03:14 +0200 • StdFile: No "New folder" button in old dialogs
2019-11-03 05:53:37 +0200 • More verbose heapcheck & optional free space debug
2019-11-02 18:13:37 +0200 • Fix possible TextEdit calibration memory move bug
2019-11-02 17:40:30 +0200 • Fix resource map validation for maps with no names
2019-11-01 17:55:35 +0200 • Add dummy cstr2dec and pstr2dec selectors in Pack7
2019-11-01 17:54:15 +0200 • Don't trash ResourceEntry ptr in RGetResourceCount
2019-11-01 02:30:02 +0200 • Dummy IUMagWString & Transliterate(Text) for Excel
2019-11-01 00:43:41 +0200 • Add 'PACK' 3,4,5,6&7 mapping (Excel now starts up)
2019-10-31 21:33:21 +0200 • Resource fork compact placeholder code
2019-10-31 01:01:48 +0200 • Fix RmveResource offset bug at last item of a type
2019-10-30 21:56:35 +0200 • Don't try to remove name if entry doesn't have one
2019-10-30 21:55:55 +0200 • Add map checks to Resource Manager calls for debug
2019-10-30 04:54:54 +0200 • Fix reallocation of resource in ChangedResource
It’s not that long since the previous news update, but there are a couple changes that are especially important:
Application bundle writable file system support
One problem with the app bundles was that by nature, their contents have read-only privileges to prevent unwanted modifications. However, as the emulator’s virtual filesystem needs to be able to not only create new files, but also modify existing ones (such as highscore saving in ZeroGravity and Continuum), using the files directory from inside the app bundle was not suitable.
To make the virtual file system writable, the emulator now relocates it to a safely writable location at /Users/<username>/Library/Application Support/MACE/<application-name>/vfs. This has a couple of neat features:
On every launch, any original files which are either not present or zero-length are copied from the app bundle to the writable location. This includes the initial launch, during which the entire filesystem gets replicated there.
Holding down the “Shift” key performs a “soft-reset” of the writable filesystem, meaning that all originals files are replicated even if they exist already in the writable filesystem. This is handy in cases if the original system or application files get damaged and would cause the emulation to fail to start. NOTE: There is not yet any prompt when performing the “soft-reset”, but there is plan to add a confirmation dialog (including a option for “hard-reset” feature) later at some time.
Any files modified or saved by user are fully accessible through this folder in AppleDouble format, which can be exchanged between applications and/or other emulators (or with appropriate conversion, real Macs).
MacOS Catalina support tweaks
As the new macOS Catalina was released recently, it was discovered that there was a unnecessary privilege used by the SDL2: It was listening to background key presses solely to track state of the caps lock key. Luckily, there was already a patch for this issue in SDL 2.0.10, so updating the SDL2 library (and adjusting some caps lock support code) fixed this problem.
(Please note that there will still be warning for unsigned applications, as to remove this Apple requires not only signing, but since 10.15 also notarization of any downloaded MacOS applications, both which require the paid Apple Developer Program membership.)
New test application: Continuum 1.04
Thanks to the personal permission by Brian Wilson, in combination with the writable bundle support we added this weekend, we have now Continuum 1.04 available as a fully functional MACE app bundle (including planet editor):
You can try the game out by visiting the downloads section. If you would like to know more about Continuum and its history, you can also visit the Continuum web page Brian Wilson has created here.
Other new test applications: Mac Concentration and GunShy 1.3
Thanks to the small fix done to the bug in SANE FP68K trap’s FMULD selector, Mac Concentration now works perfectly (it was previously stuck in game board generation loop due to the messed up multiplication results).
With the writable file system support, GunShy 1.3 is also finally feature-complete as a application bundle, as players need to be able to save & load games.
Like Continuum, these two new app bundles are available freely for trying out in the downloads section.
Full list of changes since last post
2019-10-27 07:49:25 +0200 • Relocate VFS to writable path on Mac OS X startup
2019-10-27 04:52:17 +0200 • Update Alice, Continuum and GunShy JSON configs
2019-10-27 04:45:56 +0200 • Adjust CapsLock check to work with new SDL version
2019-10-27 04:44:03 +0200 • Update to SDL2.0.10 to remove scary Catalina popup
2019-10-27 04:21:42 +0200 • Tweak InvalRgn/InvalRect to work better in Conti..
2019-10-26 05:17:58 +0300 • Update cmake JSON config for MacConcentration
2019-10-26 04:25:41 +0300 • Adjust VBL routine call order for sound refresh
2019-10-26 03:50:40 +0300 • Fix FMULD bug (param1 not assigned correctly)
We had this week a rather interesting thing happen by accident, which was rather unusual: While trying out a couple potential test applications with the emulator, we ran into an application which was infected by nVIR A type virus ( https://en.wikipedia.org/wiki/NVIR ). What makes this interesting, is that it apparently was able to infect the System file of that application’s bundle, as we now have near-complete resource write support:
Above is partial output of the System file’s resource map debug dump (and Rezilla screenshot of infected System file), and the ‘nVIR’ and ‘INIT’ resources were actually written into the System file by the virus in infected application – and the system resource map seemed to be (mostly) still functional! I only found this out because a bug in resource writing corrupted Geneva font, causing the infected application to crash. A kind of controversial achievement, having good enough compatibility for even viruses to work in the toolbox emulation…
One of the positive sides of the current per-application bundling of files as isolated file systems, is that the infection never was able to break out of the application bundle. We have also scrubbed through all the disk images and Mac files downloaded we use for development and testing, to make sure there will not be any risk of infection at later time (and run Disinfectant on the source Macs/emulators regularly). These viruses are ancient, but can awake up at any time it seems…
New test application: IAGO
After we got the infection sorted out and everything back to normal, we experimented with a couple of new test applications, and found out that IAGO, which is a public domain game written by David Reed in 1984.
We were able to identify one bug in ROXLI.L instruction, which caused the game timer to not advance correctly. After it was fixed, the game works as smoothly as it does on a (fast) real Macs. It is now also available for testing as application bundle in the downloads section.
Even though a lot of bugs were fixed, there are still test cases which do not pass, and will be fixed soon. However, with the fixes already done to the bugs that were found thanks to the test suite, Dark Castle and Beyond Dark Castle appear to be stable in rooms that used to crash before:
New relative mouse mode
A long-time task that has been waiting implementation has been the relative mouse mode, in which M.A.C.E. captures mouse cursor entirely, and instead of using the absolute position given by the host operation system, calculates mouse motion itself using the mouse delta vectors. This both prevents stray clicks outside emulated desktop window, and allows long delta swipes such as required to control helicopter in Apache Strike. As a result of this, Apache Strike can now be played, as previously it would immediately crash into the wall – and Pirates! no longer hangs in the swordfight at beginning – both which depended on certain low-level mouse low memory globals being emulated correctly:
Another fun feature which we added to complement the relative mouse mode as experimenting with game controller input API of SDL, which took about 30 minutes to do and works quite OK as seen on this video:
Another issue that was fixed was missed clicks problem with “Tap to Click” MacBooks, which now should generate mouseDown events correctly.
Currently the cursor itself is still displayed using SDL “hardware” cursor API, but with the recent changes adding support for software cursor should not be a big problem – One that might be required to have decent cursor is certain games, where the cursor visibility depends on the cursor having ability to “invert” depending on underlaying graphics (such as the crosshair on black background in lemmings), which the SDL hardware cursor does not support.
Keyboard text input rewritten with proper character mapping
In first iteration of keyboard handler, we only had scancode support with minimal MacRoman mapping (without modifiers), which although was working for the simple use cases, did not allow flexibility required for example to enter upper-case letters.
For second iteration, we attempted to utilize host operating system keyboard layout mapping by using SDL text input API, and although it worked nicely for TextEdit text input, broke command keys and other things (such as Dark Castle & Lode Runner controls) horribly.
For the latest, third iteration, we went back to scancode based input, but instead are simulating the exactly same type KCHR scancode to MacRoman mapping like on real Macs. This allows every key to work properly in text editing, game input and menu shortcut etc, but one downside is that for international layouts we will need to have separate KCHR resources, currently only having U.S. as default layout. However, as “dead keys” are also working, typing special characters such as accents, umlauts, etc is working nicely even on this layout.
ResEdit bug “treasure chest”
ResEdit proved to be a real “treasure chest” of bugs and improvements, as it used literally every possible List Manager routine, and it also surfaced some unexpected bugs in other places such as TextEdit, Dialog Manager, QuickDraw, and other already heavily used toolbox traps.
Some major improvements found through testing ResEdit:
Most of List Manager calls were implemented, including resizing lists, deleting rows/columns, searching data. Also some bugs were fixed, such as corruption of data offsets in some cases, etc.
Dialog manager edit field handling had a number of bugs, which surfaced in the DLOG editor, and there also were bugs in item hiding/showing which were also manifesting in Civilization.
TextEdit had some bugs in the MixedMode handling of special case calling conventions, which caused crash in the hex editor. After fixing them, not only the hex editor works, but also MacPascal editing bugs were fixed, as it also used custom TEDoText hooks.
The PACK 1 (“BitEdit”) package in ResEdit surface a couple QuickDraw bugs, such as random SeedFill memory corruption (using the paint bucket tool) and StretchBits memory corruption. These also make MacPaint more stable, which was also suffering from the SeedFill bug.
Some of these fixes had quite universal effects, such as improving the previously buggy behaviour of Lists and TextEdit in HyperCard 1.x:
Text scaling and measuring had some bugs, which were fixed so that MacPaint and Macwrite can display text of all sizes, faces and styles.
MacWrite now works, at least kind of…all other edition options are working (styling, page breaks, font sizes, fonts, rulers, etc), except adding newline using enter/return causes text to corrupt.
As the region corruption bug in polygon rendering was fixed, PT-109 appears now the be completely stable.
With “dummy” SetPalette trap implemented, Railroad Tycoon is now able to proceed past first “End of Fiscal Period” report
Scrollbar (CDEF 1) implementation (and related Control Manager TrackControl/DragControl stuff) were finally finished, so the indicator thumb dragging works now.
Prototype of font fractional width support added, only test case for this is curently Photoshop, which enables them. Right now only FOND width tables are supported, but extended width tables could be easily added as soon as some application needs them.
New test applications added
Also, we have now finally two new test app bundles that should be complete enough for trying out. These are ZeroGravity by Duane Blehm, and Blob Manager Demo by Paul DuBois. They are now available for trying out in the Downloads section.
Additionally, the old test application bundles have been updated with the new M.A.C.E. runtime, which includes all the bug fixes and improvements done since their last update. For example, Stunt Copter uses now the new relative mouse mode, and all apps have been updated to support the “Tap to Click” trackpad mode on MacBooks.
Full list of changes since last post
There are too many changes to detail in a single post, so as a new feature below is the version control log of all changes made since last update:
2019-08-19 22:54:49 +0300 • Add SetDialogDefaultItem/CancelItem/TracksCursor
2019-08-19 22:47:32 +0300 • Tweak TrackControl and LClick delay to 8 ticks
2019-08-19 18:15:47 +0300 • Save alert default item also in the DialogRecord
2019-08-19 16:23:03 +0300 • Partial support for default dialog StdFilter proc
2019-08-19 07:03:12 +0300 • Bumb the M.A.C.E. version number & use current date
2019-08-19 07:02:52 +0300 • Replace printfs with log, and add a few DEBUG #ifs
2019-08-19 07:00:17 +0300 • Fix the SDL window title for now by using EnvStartupFile
2019-08-19 06:59:57 +0300 • Tweak Blob Mgr Demo and ZeroGravity for release
2019-08-19 06:00:30 +0300 • Work on FOND widthtable and fractional size support
2019-08-17 03:17:27 +0300 • Work a little on resource map "shadowing" handling
2019-08-17 03:04:32 +0300 • Fix WaitMouseUp to not return 1 extra "down" state
2019-08-17 02:23:40 +0300 • Fix SeedFill random memory corruption case
2019-08-15 23:36:01 +0300 • Merge branch 'master' of
2019-08-15 23:35:56 +0300 • Fix TextEdit cursor right-side clamping
2019-08-15 22:55:05 +0300 • add xcode 6 project
2019-08-15 22:43:06 +0300 • Fix incorrect register usage in TEDoText overrides
2019-08-15 21:21:29 +0300 • Fix StretchBits stack buffer overrun
2019-08-14 23:46:30 +0300 • Fix scrollbar redraw bug in List Manager
2019-08-14 23:25:48 +0300 • SetPalette classic-QD dummy trap
2019-08-14 21:44:36 +0300 • Fix LSetSelect highlight bugs
2019-08-14 19:28:32 +0300 • Fix lNoNilHilite flag handling in LSetSelect
2019-08-13 03:14:24 +0300 • Fix value clamping in Control Manager
2019-08-13 03:11:51 +0300 • Tweak CloseWD stub to not crash
2019-08-13 03:11:28 +0300 • Implement LClrCell and proto of LDelRow/LDelColumn
2019-08-12 21:10:26 +0300 • Fix a couple byteswap bugs in lists (selection)
2019-08-12 17:39:11 +0300 • Fix one-cell delta calculation in list pageup/down
2019-08-12 15:03:44 +0300 • Fix maxIndex bug in LNew
2019-08-12 02:34:18 +0300 • List Manager LSize implementation
2019-08-11 05:12:39 +0300 • Finished LAutoScroll, another easy one for ResEdit
2019-08-11 04:56:40 +0300 • Implemented C_LFind, was simpler than I thought…
2019-08-11 04:46:28 +0300 • Finish LNextCell trap, work on LClick multiselect
2019-08-11 02:18:20 +0300 • Implement C_LClick scroll indicator handling
2019-08-11 02:06:55 +0300 • Fix dividend overflow in scrollbar CDEF 1 rounding
2019-08-11 01:43:52 +0300 • Implement DragControl, finish TrackControl & CDEF1
2019-08-10 03:41:37 +0300 • Fix caps lock usage in SDL key event handler
2019-08-10 02:01:37 +0300 • SDL gamecontroller support "hack" to Apache Strike
2019-08-09 20:45:44 +0300 • Add FSpOpenDF, FSpCreate, FSpDelete, FSpGetInfo, FSpRename & (dummy) _Rename
2019-08-09 18:08:02 +0300 • Hacked procinfo for UIMagIDString call in LSearch
2019-08-09 03:28:00 +0300 • Fix buffer overflow in GetVolParms
2019-08-09 02:42:54 +0300 • Added dummy GetVolParms selector to _FSDispatch
2019-08-09 02:00:31 +0300 • Add Jigsaw test app
2019-08-09 02:00:10 +0300 • Implement LSearch, and (dummy stub) IUMagIDString
2019-08-09 01:58:42 +0300 • Implemented 1-bit NewGWorld in QDExtensions
2019-08-08 17:10:34 +0300 • Fix allocation of key state buffer
2019-08-08 02:45:45 +0300 • C_KeyTranslate Deadkey support + fix mac scancodes
2019-08-07 18:30:41 +0300 • Fix dialog edit field handling
2019-08-07 12:13:26 +0300 • Fix picture recording of port fgColor/bkColor
2019-08-07 04:49:10 +0300 • Add git log generator, for fun 🙂
2019-08-07 04:21:32 +0300 • Tweak type of ScrapSize in low memory
2019-08-07 04:21:04 +0300 • Fix fromMode handling in Picture Line recording
2019-08-07 04:19:58 +0300 • Fix picture line recording Point saving
2019-08-07 04:17:59 +0300 • Fix Hide/Show dialog item bounds calculation
2019-08-07 04:15:36 +0300 • Prevent editfield citation replacements in dialogs
2019-08-06 19:43:28 +0300 • Fix Scrap Manager bugs
2019-08-06 19:41:31 +0300 • Clean up Mouse module a bit
2019-08-06 19:07:03 +0300 • Fix bug in DefaultShowCursor
2019-08-06 16:38:47 +0300 • Un-obscure cursor before _MDrawCursor in CrsrTask
2019-08-06 01:42:37 +0300 • Make phase-shift adjustment configurable
2019-08-06 00:20:31 +0300 • Move audio phase-shift from RAM to ClassicSound
2019-08-06 00:17:50 +0300 • Disable VM_MAP and reverse-page mapping
2019-08-05 20:44:39 +0300 • Disable a couple of mouse debug log calls
2019-08-05 00:10:21 +0300 • Updated some test apps with relative mouse mode
2019-08-05 00:09:22 +0300 • Refactor cursor to support relative motion mode
2019-08-04 00:30:38 +0300 • fix abcd, partially fix sbcd instruction
2019-08-03 23:20:09 +0300 • fix zero status for subx.b/w/l instruction
2019-08-03 00:40:07 +0300 • fix add.b, addx.b/w/l and negx.b/w/l status bits
2019-08-03 00:40:01 +0300 • Merge branch 'master' of
2019-08-02 00:05:57 +0300 • Fix TEIdle blinker
2019-08-01 23:10:07 +0300 • Implement LLastClick and tweak trap glue generator
2019-08-01 16:03:22 +0300 • Disable the extra log debug trace of heap compact
2019-08-01 16:02:28 +0300 • Reduce logging in MixedMode calls
2019-08-01 16:01:44 +0300 • Fix size bug in WriteResource
2019-08-01 16:00:47 +0300 • Fix resProtected flag check in ChangedResource
2019-08-01 15:58:51 +0300 • Fix dialog edit field disabled check + others
2019-08-01 05:19:49 +0300 • Add missing lowmem changes for CurActivate bug fix
2019-08-01 05:19:04 +0300 • Work on KeyTranslate KCHR mapping (fix keyboard)
2019-07-31 01:21:08 +0300 • Add MacConcentration test app
2019-07-31 01:20:39 +0300 • Implement FADDD & fix major 64-bit float SANE bug
2019-07-31 01:08:21 +0300 • fix lsl and lsr instruction for shift > 31
2019-07-30 22:53:46 +0300 • fixes for m68k tester
2019-07-30 21:50:19 +0300 • move x68k xcode6 project to x68k root
2019-07-30 21:48:42 +0300 • add m68k tester
2019-07-30 21:46:25 +0300 • make kemu lib c++ compatible
2019-07-29 15:51:21 +0300 • Tweak GunShy config to use version 1.3
2019-07-28 04:54:27 +0300 • Fix window activation handling
2019-07-27 04:36:27 +0300 • Fix GetFontInfo for scaled fonts
2019-07-27 04:22:21 +0300 • Fix bug in fast-case of text blitter
2019-07-27 02:13:56 +0300 • Set Lo3Bytes lowmem global properly
2019-07-27 02:12:01 +0300 • Implemented ReadDateTime and (dummy) SetDateTime
2019-07-27 01:26:28 +0300 • Fix LActivate
2019-07-27 00:46:46 +0300 • Fix cursor leak
2019-07-26 18:29:56 +0300 • Tweak InitResources to be (again) re-callable
2019-07-26 17:32:20 +0300 • Fix UPP ProcInfo of DABeeper callback
2019-07-26 15:46:55 +0300 • Implemented LActivate selector in List Manager
2019-07-26 05:45:33 +0300 • Fix bug in resource manager name remove code
2019-07-26 05:44:44 +0300 • Add Glider4 test app
2019-07-26 05:44:24 +0300 • Fix possible bug in SetVol NFS handler
2019-07-26 05:43:07 +0300 • Setup CurrentA5 during boot stage 2 for INITs
2019-07-26 02:55:49 +0300 • Re-fix PurgeSpace to also return correct D0
2019-07-26 01:52:59 +0300 • Optimize FramePolygon case
2019-07-26 01:43:57 +0300 • Actually update the existing ADF header
2019-07-26 01:36:18 +0300 • Finish SetFileinfo handler in NativeFS
2019-07-26 01:35:28 +0300 • Fix region corruption bug in polygon drawing
2019-07-25 23:16:56 +0300 • Fix MapRgn duplicate inversion point bug
2019-07-25 23:07:21 +0300 • Fix MapPt negativity check
2019-07-25 22:08:06 +0300 • Fix size of ScriptUtil selector
2019-07-25 22:02:10 +0300 • Fix edge case bug in UnpackBits
2019-07-25 21:02:00 +0300 • Fix ADF file create bug, mixed up rsrc and data
2019-07-25 19:27:32 +0300 • Also reserve space for mapping in the stack after packBuffer
We’re still on summer “break”, but there has been a few evenings time to work on some TODO items, lately especially on the TextEdit implementation. It’s still far from complete (the basic, single-style TextEdit – Styled TextEdit is another undertaking on its own!), but there has been some progress that has already some visible effects.
For example, one of the games we’ve been testing emulation with, Scarab of RA, relies EXTREMELY lot on TextEdit, including quest log, inventory (which includes selecting items with text selection highlight included), help/hint, about, and score dialogs. Some of these work in very interesting ways, for example quest log and inventory assemble text by concatenating text from individual segments – for example, “16 ounces of food” line in inventory is assembled one by one from strings “16”, ” “, “ounce”, “s”, ” of food”, and carriage return. The game also appears to use the internal line start offsets to intercept clicks in inventory, highlighting individual lines using text selection by itself.
The game is already approaching playable state, but there are still a few issues – most notably, recalibration of line start offsets does not update last line offsets correctly when removing, causing removed lines to sometimes leave “trashed” text at end of text edit boxes. Here’s some screenshots of how it looks like now:
Additionally, a few other games (Lemmings, Simcity) can now proceed past copy protection screens, as we can finally use the VERY hacky TEKey implementation to enter correct answers to the protection questions (SimCity also required a bunch of new selectors to be added to the FP68K SANE dispatcher):
EDIT: Here’s a video of first 15 minutes of Mac Lemmings gameplay:
There is also some effect on productivity apps:
As the “message” window in HyperCard 1.x is now able to accept commands, we can use “set userlevel to 5” command to actually modify the included stacks! Still a lot of things broken there, but yet a lot new functionality unlocked… We haven’t though had time to play with them, but it should soon be much more usable!
EDIT: After minor tweaking with SDL TextInput API, MacPascal can also now accept text input, compile and run Pascal code:
In general, TextEdit still has a lot of important features unfinished or to be implemented:
No caret display yet (teCaret in TEDoText)
TEClick not yet implemented, thus using mouse for selecting text does not work yet
TEKey is VERY hacky, needs for example arrow key control, backspace support, etc
Dialog Manager keyboard input does not yet handle default items/clipboard commands etc
The keyboard driver is still passing key events through scancodes without real mapping to actual MacRoman characters, preventing modifiers/host operating system keyboard layout from having effect
Line start recalibration has still sometimes issue when removing lines from middle of text
Selections have still some visual glitches, especially when typing text in dialogs
Styled TextEdit support still completely missing…for now