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
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:
One of the major features of phase #2, as we originally wrote in the milestone and phase plan two years ago, is adding support for Color QuickDraw emulation. Even though a lot of APIs considered part of phase #1 are still incomplete, the application compatibility and overall progress of project appears good enough to justify starting the work on that particular feature at this point. Nevertheless, all missing phase #1 features will be worked on simultaneously as they come up when testing the applications.
Adding color support will eventually allow us to test a huge number of new applications and games, and it will also allow trying out the existing ones in color modes. Especially games from the early 1990s have very good support for multiple color depths, so it should be interesting (for example, Civilization’s support for 1-bit and 256 colors, Railroad Tycoon’s 1-bit and 16 color support, Glider’s 16-color art, etc…)
First steps: The slot-based architecture
Originally Apple’s Mac II lineup had a quite different architecture from the old “classic”-type compact macs, which also reflects on how Color QuickDraw operates. Instead of dividing the memory space into four regions as in “classic” Macs (4mb RAM, 4mb ROM, 4mb I/O and 4mb VIA space), the slot-based models (in original 24-bit model) divide memory into 1mb “slots”, which are more dynamically assigned. For example, IM:Memory 3-6 describes the following model (in 24-bit mode):
0x900000-0xEFFFFF: Nubus slot addresses
That particular model fits quite well with the currently implemented 24-bit memory manager, so we use that as a starting point for Color QuickDraw machine emulation. It also allows us to partially emulate slow manager APIs (as slot numbers $9 through $E match their address space as on real Macs), and allows possibility for emulating multiple screen using multiple “virtual” slot manager cards, one for each screen. The drawback of this, though, is that only one megabyte is assigned for each video device in 24-bit mode, which limits usable VRAM to that 1 megabyte. What this practically means, is that these are the approximately maximum supported “standard” resolutions for each color depth:
1-bit (black & white): 3840 x 2160 (4K)
2-bit (4-color): 2560 x 1440 (QHD)
4-bit (16-color): 1920 x 1080 (FHD)
8-bit (256-color): 1280 x 720 (HD)
16-bit (32K colors): 832 x 624 (Mac 16″)
32-bit (16.7M colors): 512 x 384 (Mac 12″)
Of course, when we later someday add 32-bit memory manager support, we will have 256 megabytes per video device, and can get rid of this limitation.
The slot driver
One key component between the “virtual” slot-based video device emulation, and the Color QuickDraw, is the device driver for the slot device. In our case, we added the .Display_Video_MACE_FB driver (following Apple’s naming convention for slot drivers), which is used by QuickDraw’s and Color Manager to control video modes, color table, etc.
On real Macs slot manager would be responsible for iterating parsing sRsrc:s and other slot-specific data structures, but we forego those hardware-specific details and address the native video device data (currently SDL) through our platform-abstraction interface.
The DRVR calls are still important to implement properly, as they were quite standard on real Macs, and there might be apps using them directly, even though well-behaving apps should always use GDevice, Color Manager and Color QuickDraw API calls.
Platform abstraction for color video
As we already had prepared for adding color support when starting the project two years ago, most of the support for it existed already in the platform abstraction layer. There were a couple tweaks needed, but most work was just adding the output renderers for each of the new color depths (originally there was only 1-bit blitter, as it was the only color depth supported on classic Macs). This also included adding the color lookup tables in the pipeline, so that we are ready for Palette Manager when we get to the point of implementing it.
As there may exist any number of screens, with any resolution and various color depths, Color QuickDraw added the concept of GDevices. Each GDevice represents one screen/video card attached to the system, with its own screen buffer, color & gamma tables, etc.
Color QuickDraw allows drawing to all of these devices at once using the standard toolbox API, doing all the color conversion and addressing for the user. This is what we need to implement next also in our emulator.
One key component of Color QuickDraw is Color Manager, which is responsible for managing the color tables for each GDevice. What this means, that it creates and manages the inverse color lookup tables (which are used to map RGB colors to indexed colors), and handles those lookups. It also keeps track of seed values for color tables, which are used to determine when color tables have changed, which is important especially if a previously expanded pattern is drawn after a new color table has been activated. For now, we implemented a very basic ITable generation for allowing RGBColors to work on indexed color modes.
Inverse color-lookup table
As meantioned above, one key feature of Color Manager is the generation and management of ITab data structures, which are used to map RGB Colors back into color table indices in indexed video modes (2-, 4- and 8-bit depths). The generator is run in MakeITable trap handler, which takes handle of color table, handle of output inverse table, and desired channel resolution as arguments.
The inverse table is actually a RGB cube, where the cube’s channel size is defined by the number of bits given as the resolution; so for example resolution of 4bits gives 2^4 = 16, and the entire RGB cube would take 16x16x16 bytes which is 4096 bytes, or 4K of memory. As in three-dimensional XYZ space, RGB cube can be thought of in the same way; Each R, G, B coordinate are used to locate index in the cube’s 3-dimensional table.
When Color QuickDraw wants to get for example, index of RGB color #E39EA0, Color Manager would convert first the RGB components into cube’s resolution range (in this case, result would be (14, 9, 10]), and use those values of index the ITab data to get the value.
When the cube is generated by MakeITable, it is initially empty, but is given the seed values from the source color table; each seed value is the color lookup table index, placed at the RGB coordinate which it specifies. After this, the seed values are progressively iterated, so that each value “spreads” into adjacent RGB cube slots in any of the six axis directions (+R/-R, +G/-G, +B/-B). This is repeated as long until there are no longer any unfilled slots left in the RGB cube. This is familiar method from basic pathfinding, and some maze generation algorithms, and ensures that each RGB cube slot contains the index of color lookup table which is the closest available approximation for that particular RGB color.
PixMaps (and PixPats)
As BitMaps only supported 1-bit graphics, Apple added PixMap in Color QuickDraw to allow representing graphics of any bit depth using a standard data structure. Additionally, the GDevices use PixMap to represent the VRAM buffers, and PixPat (multi-color patterns) structure also uses PixMap as storage for the pattern data. And they also are by default implemented as Handles, which means they can be moved in the heap during compaction to prevent memory fragmentation (but require locking in certain cases).
The first step: Using legacy GrafPorts with Color QuickDraw
As Color QuickDraw has a lot of layers to provide backwards-compatibility for older applications, the first step was to start from the most basic one, legacy GrafPort support. As the very first call done to QuickDraw is to gray out the screen at startup, we focused on getting the most basic case for FillRect working at first. With adding support for pattern expansion to any pixel depth, and adding new srcCopy blitters, we got this fist monochrome output result after a couple weeks of coding:
When emulating the old-style GrafPorts, of of their interesting features to simulate was support for the 8 old-style QuickDraw colors (which map mostly to the colors used in ImageWriter printers with CMYK ribbon). With proper color mapping, and a couple days of banging the head against desk, we ended up with this result:
Second step: CGrafPort support
As mentioned earlier, the old-style GrafPorts were limited to only displaying those 8 colors, so to get the full range of RGB colors displayed, we had to add a proper CGrafPort support. This included implementing OpenCPort and InitCPort, and initialization of all related data structures. For example, all patterns in CGrafPorts are PixPat patterns, so we had to do a Pattern-to-PixPat conversion.
Most importantly, the fgColor/bkColor no longer represented the old-style color constants, but instead needed to be mapped to bit-depth specific index (on indexed device modes) or pixel value (on direct device modes). To control these colors, we implemented the RGBForeColor/RGBBackColor traps, which map the RGB values to the mode-specific values.
After a couple of days of more hard work, we now have the RGB colors working in CGrafPorts:
There is still A LOT of things to do before we can get much beyond simple rectangles on the screen, but the tasks should get easier as we go along. A lot of the routines (such as color mapping) can probably be shared as-is with most of other Color QuickDraw APIs. Some of the tasks next up are:
Adding region masking variant to the color blitter
Adding other pattern modes beyond patCopy
Adding source transfer modes (only patCopy done at the time of writing this)
Color versions of the special horizontal single-scanline blitters
A lot of other stuff
Full list of changes since last post
2020-01-31 18:02:57 +0200 • Basic support for "oldPat" PixPats in CGrafPorts 2020-01-31 16:35:14 +0200 • Implement InvertColor (default gdCompProc only!!!) 2020-01-31 13:47:55 +0200 • Some progress on CGrafPort colormapping & bugfixes 2020-01-30 02:10:42 +0200 • Add ColorQD Fore/BackColor & RGBFore/BackColor 2020-01-30 01:25:49 +0200 • Init default ColorQD PixPat patterns in InitCPort 2020-01-29 20:06:33 +0200 • Implement NewPixMap and NewPixPat 2020-01-29 01:42:41 +0200 • Initialize WMgrCPort (color port) in InitWindows 2020-01-29 01:41:59 +0200 • Implement OpenCPort and (mostly) InitCPort 2020-01-29 00:48:03 +0200 • Implement GetPixPat and GetCCursor colorQD traps 2020-01-28 22:12:56 +0200 • Implement DisposePixPat trap handler in color QD 2020-01-28 01:46:18 +0200 • Fix non-default colored patterns in 1-bit mode 2020-01-28 01:11:02 +0200 • ColorQD compatible GlobalToLocal/LocalToGlobal 2020-01-27 20:22:27 +0200 • Fix palette alignment issue in 8- and 15-bit modes 2020-01-27 20:20:38 +0200 • 15-bit (thousands of colors) SDL rendering support 2020-01-27 20:20:04 +0200 • 2-bit SDL output rendering support 2020-01-27 20:19:27 +0200 • Disable grayscale flag for now, test&fix it later 2020-01-27 20:18:37 +0200 • Fix last palette entry missing (zero-based count) 2020-01-27 13:33:46 +0200 • Add support for direct colors in color mapping 2020-01-27 13:26:34 +0200 • Set GDevice's gdType properly at initialization 2020-01-27 10:38:45 +0200 • GDev CLUT setup & rendering (first colors output!) 2020-01-27 09:44:47 +0200 • ColorQD ForeColor/BackColor in old-style GrafPorts 2020-01-27 09:43:56 +0200 • Fix initialization of QDColors low-mem global 2020-01-27 04:59:25 +0200 • Use Color2Index in color mapping for correct color 2020-01-27 04:56:41 +0200 • Set GDevice's gdResPref in the InitGDevice handler 2020-01-27 04:39:29 +0200 • Color2Index proto (no hidden color handling yet) 2020-01-27 04:36:27 +0200 • Fix the one-entry off "black-most black" index bug 2020-01-27 04:11:57 +0200 • Finish the first proto of MakeITable 2020-01-27 03:19:38 +0200 • Remove unneeded mitq resource from build 2020-01-27 03:18:51 +0200 • "Plant" seeds for the ITab generator from the clut 2020-01-26 00:24:21 +0200 • Start work on MakeITable 2020-01-26 00:23:50 +0200 • Tweak pattern blitters, preparing 8-bit support 2020-01-26 00:22:14 +0200 • Dummy Color2Index stub, prep use in colormapping 2020-01-25 17:05:21 +0200 • Hack 4- and 8-bit (16 & 256-color) output support 2020-01-25 17:01:45 +0200 • Fix old-type pattern to 8-bit conversion 2020-01-25 16:55:25 +0200 • Fix mask calculation for non-1-bit rectangle blits 2020-01-25 02:21:23 +0200 • First simple non-region FillRect case for ColorQD 2020-01-25 02:20:38 +0200 • Block attempting to post events before InitEvents 2020-01-25 02:19:04 +0200 • Fix the "dummy buffer" string RSAlloc overflow 2020-01-24 02:35:50 +0200 • Some progress on color blitter rectangle culling 2020-01-24 02:34:20 +0200 • Add QDErr low-mem global 2020-01-24 00:05:55 +0200 • Do CQD old 1-bit pattern to b&w GrafPort expansion 2020-01-23 00:18:35 +0200 • First CQD color mapping pass for old-type GrafPort 2020-01-22 17:53:29 +0200 • A bit of work on the color QD color mapping 2020-01-21 01:32:09 +0200 • Implement portBits to PixMap conversion to colorQD 2020-01-21 01:30:38 +0200 • Init lot of lowmem globals for default videodevice 2020-01-21 01:27:42 +0200 • Fix byteswap bug on device depth in CVGetVidParams 2020-01-20 15:02:02 +0200 • Refactor QD a bit in preparation of color support 2020-01-20 02:34:13 +0200 • Disable for now dirtyrect optimization in color QD 2020-01-20 02:22:37 +0200 • ColorQD versions of InitPort and OpenPort 2020-01-20 01:33:36 +0200 • Save LastMode/-Fore/-Back/-Depth in FMSwapFont 2020-01-20 01:32:29 +0200 • Fix two indexing bugs in ColorVideoInitOneSlot 2020-01-20 01:30:00 +0200 • Implement most of InitGDevice trap for color QD 2020-01-20 01:28:50 +0200 • Add empty stub for MakeITable trap 2020-01-19 23:29:53 +0200 • Add GetDeviceList trap 2020-01-19 20:37:49 +0200 • Add grayscale flag to video devices 2020-01-19 14:36:11 +0200 • Fill in GDevice's VPBlock from color video driver 2020-01-19 14:35:34 +0200 • Fill in DCE slot info in Open call for slot device 2020-01-19 05:03:02 +0200 • Add one more missing ROM clut resource 2020-01-19 05:02:32 +0200 • Add DisposePixMap, New/InitGDevice, GetNextDevice 2020-01-19 04:59:55 +0200 • Use cmake source_group TREE to clean up projects 2020-01-19 04:59:08 +0200 • Add MacVideo header 2020-01-18 23:54:18 +0200 • A couple more CQD resources (gama, mitq, cluts) 2020-01-18 05:51:16 +0200 • Add unit table debug dump tool to device manager 2020-01-18 05:50:37 +0200 • Add "virtual" slot DRVR installation support 2020-01-18 04:29:39 +0200 • Tweak video driver name & fix default slot amount 2020-01-18 04:26:22 +0200 • Implement DoVBLTask trap (untested) 2020-01-17 17:27:46 +0200 • Add SlotManager module + slot queue initialization 2020-01-17 01:52:09 +0200 • Implement color version of InitGraf 2020-01-17 01:28:37 +0200 • Add GetCTSeed/GetCTable/DisposeCTable to ColorMgr 2020-01-17 01:18:38 +0200 • Add TableSeed and HiliteRGB low-mem globals 2020-01-17 01:17:59 +0200 • Add default 'clut' tables to color ROM resources 2020-01-16 01:50:16 +0200 • Clean up linker errors for missing color QD stubs 2020-01-16 01:43:16 +0200 • Add setup of menubar 'mctb' color table (untested) 2020-01-16 01:35:33 +0200 • Empty stubs for GetCIcon, PlotCIcon & DisposeCIcon 2020-01-16 01:27:38 +0200 • GDevices module & GetMainDevice/GetMaxDevice stubs 2020-01-16 01:20:13 +0200 • Add empty stub for _ActivatePalette 2020-01-16 01:15:39 +0200 • Empty stubs for Delete/SetMCEntries & InitPalettes 2020-01-16 01:06:12 +0200 • Tweak ClassicSound to not fail colorQD compilation 2020-01-16 00:56:30 +0200 • Tweak some CMake configs for color-only apps 2020-01-16 00:55:31 +0200 • Refactor VBL code out of VIA + add slot# to video 2020-01-15 02:52:16 +0200 • Improve compilation of QDExtensions with color QD 2020-01-15 02:41:14 +0200 • Improve Menu Manager color QD compatibility 2020-01-15 02:40:40 +0200 • FMSwapFont color QD tweaks & LastSPExtra type fix 2020-01-15 02:36:37 +0200 • Fix ClassicSound compile error w/o Sound driver 2020-01-15 00:49:29 +0200 • Separate Mono & Color fake roms + add 32-mode flag 2020-01-15 00:47:24 +0200 • Add the DRVR 120 (.Display_Video_MACE) to fake rom 2020-01-15 00:45:59 +0200 • Add color video initialization call to boot code 2020-01-15 00:44:02 +0200 • Add stub for the color video driver 2020-01-15 00:42:54 +0200 • Add symbol name to binary-to-C converter
As mentioned in the earlier posts, a large amount of this Christmas vacation was spent on the Windows version of M.A.C.E. runtime, and creating something for Windows users to try out. Now all the core work has been done, and we have the first prototype of the Windows port of runtime – with all of the existing test applications now available also as Windows executables. Now, there are a couple important points:
The windows executables are currently built only for the 64-bit x64 architecture
They have only been tested on Windows 10 (and only on Toni’s brand new 3.06Ghz Xeon W3550, and whatever processor Pukka’s new PC has). We have no idea on what other computers they work (or do not work)
You might want to avoid running them under certain virtualization software applications, as at least on Toni’s VirtualBox the performance was… not very stellar, at least compared to a physical PC without virtualization.
The PC keys are (for now) mapped permanently as follows:
Left alt = Left command
Left ctrl = Left option
Right alt = Right command
Right ctrl = Left control
Under windows 10, the “windows square” key (between Ctrl and Alt) cannot be used by the emulator as command or option key, because the Windows OS doesn’t seem to allow it to be fully captured (only partially).
AltGr key does NOT work as Right alt, because on Windows AltGr actually simulates Left Ctrl + Left Alt key presses. We need to investigate this more in the future.
The filesystem package is cached under Users -> username -> AppData -> Roaming -> MACE, with individual cache folder for each pre-packaged test application. So, if you for example create cool Continuum Galaxy files, this is where you’ll find them. And as AppleDouble files, they are exchangeable between M.A.C.E. on Windows, M.A.C.E. on Mac OS X, and theoretically (but not tested) with the Executor emulator which also uses AppleDouble files.
Below is a screenshot of the currently available test apps running on Windows 10:
If you have Windows, you can right now try them out in the Downloads section on this page.
Screen mode control: Full-screen mode and pixel doubling
Another neat new feature that was added to the new M.A.C.E. runtime version, besides the Windows compatibility, is the ability to switch between windowed/fullscreen modes on the fly, and also toggling the pixel-doubling feature. The shortcuts for these are:
Cmd+Shift+1: Toggle pixel doubling mode
Cmd+Shift+2: Switch between windowed and full-screen modes
These keyboard shortcuts were chosen (for now) as they should conflict very little with existing Mac applications, as they were used as disk eject FKEYs on real Macs.
This new feature has been both updated into the existing Mac OS X test app bundles, as well as in the new Windows versions.
Full list of changes since last post
2020-01-07 00:39:56 +0200 • Skip unwanted packaged VFS entries
2020-01-06 23:40:32 +0200 • Don't cache OSX 10.6 vs 10.9 target in CMake
2020-01-06 20:32:52 +0200 • Fix typo in scaline range check in _StretchBits
2020-01-06 19:10:24 +0200 • Bump runtime version & tweak version info format
2020-01-06 07:08:39 +0200 • Load package VFS from Win32 resource on Windows
2020-01-06 07:07:18 +0200 • Include dynamically generated .rc in win32 targets
2020-01-06 07:06:34 +0200 • Fix encoding of special symbols in two test apps
2020-01-06 06:05:01 +0200 • Add extracting VFS archive in initialization code
2020-01-05 04:30:25 +0200 • Add file archive reader, and clean up CMake files
2020-01-04 23:20:46 +0200 • Sign-extend <32bit args to prevent ARM optimizat..
2020-01-04 04:18:12 +0200 • Try fix Raspberry hMenu bug, enforce 16-bit menuID
2020-01-03 22:22:10 +0200 • Lock SDL window data during screen mode switch
2020-01-03 21:52:42 +0200 • Refactor display toggles to use DynamicConfig keys
2020-01-03 21:50:30 +0200 • Add first part of DynamicConfig system (UserPrefs)
2020-01-01 17:54:41 +0000 • Disable JSON parser tests from build
2020-01-03 01:20:14 +0200 • Fix DynamicConfiguration JSON dependency + bin dir
2020-01-03 00:39:24 +0200 • Merge branch 'master' of
2020-01-03 00:39:21 +0200 • Add missing header search path for JSON lib
2020-01-03 00:36:54 +0200 • Fix OSX target, CMP0066 and set SDL2 debug/release
2020-01-02 23:08:12 +0200 • Merge branch 'master' of
2020-01-02 23:08:06 +0200 • Specialize OSX Cmake config to 10.6 and 10.9 bases
2020-01-02 20:36:10 +0200 • Add JSON parser to the MACE runtime (for configs)
2020-01-02 19:09:33 +0200 • Also fix the Mac icns for previously invalid icons
2020-01-02 18:51:14 +0200 • Add stub for DynamicConfiguration module
2020-01-02 18:50:30 +0200 • Sanitize Windows key mappings to be more usable
2020-01-02 04:13:26 +0200 • Add ICO files to EXEs, & use console only in debug
2020-01-02 04:11:18 +0200 • Use debug/release SDL2 lib depending on app target
2020-01-02 04:09:56 +0200 • Reconvert Windows ICO files
2020-01-02 04:09:39 +0200 • Fix incorrect icon assignments of couple test apps
2020-01-02 04:08:20 +0200 • Make SDL2-static compile on VC release mode
2020-01-02 00:51:30 +0200 • Add processing of Windows ICO files
2020-01-01 23:49:58 +0200 • Fix trap glue generator to use new byteswap macros
2020-01-01 23:48:56 +0200 • Refactor cmake to use offline icon conversion
2020-01-01 20:39:58 +0200 • Add lpng 1.6.37 to ThirdParty external libraries
2020-01-01 17:10:36 +0200 • Force redraw of screen on SDL expose events
2020-01-01 15:38:09 +0000 • Haiku compilation fixes
Okay, so both members of development team have been busy being on vacation trips for the past few weeks, but we’re again back (although still on “kind of” summer break). To celebrate this we decided to each post a picture of what we’ve been up to, but to make this appropriate to topic of this blog, we do this by showing the photos using M.A.C.E running Photoshop 🙂
Road trip vacations
First, Pukka went on a road trip to Eastern Finland with his good old trusty Volvo station wagon for one week:
Toni went on a two-week road trip to Northern Germany, visiting 12 cities in 14 days, including taking this amazing train from Hamburg to Kiel:
TextEdit progress (and Scrap Manager)
During this two weeks of visiting a lot of places, Toni had a couple evenings time to do some work on (non-styled) Text Edit, which now is nearly complete, and is able to run TeachText with almost all text editing features working:
These are the notable features which work now in TextEdit:
Multi-line text display, with scrolling support (viewRect/destRect offsetting)
TEKey text input (still a bit hacky but functional)
TEClick with autoscrolling support, double-click word selection (using TEFindWord), and fExtend support for “shift-key”-type extending of selection, and recognition of left/right side of character for proper caret positioning
TextEdit hook support for nearly all TE Hooks (TEDoText, TERecalc, TEWordBreak, ClikLoop, TEFindWord, TEFindLine, TETrimMeasure, EOLHook, HighHook, etc…) which can be customized by 68K apps
Caret support with TEIdle blinking, TEKey cursor key movement (including multi-line support), and multi-line selection range support
Nearly all “quirks” of regular System 7.x TextEdit implemented as they work on real Mac; including the weird way caret gets positioned when moving across line boundaries using left/right arrow keys if previously clicked on right-hand side of a character, etc…
Dialog Manager edit field support, with System 7-type multi-line text support (i.e. edit fields with one line get extended horizontally 2x size, and scroll both horizontally and vertically, while multi-line edit fields only scroll vertically), “tabbing” between edit fields, and complete TEKey/TEClick support
Maybe some others I’ve forgotten to mention
Additionally, as TeachText wanted to use also Scrap Manager for edit functions, in parallel to implementing TECut/TECopy which use private TextEdit scrap, the implementation of generic Scrap Manager was finalized so that Clipboard file is fully supported (previously only in-memory state of scrap was implemented).
However, TEPaste still needs to be added for a 100% completion of “Edit” menu features for TeachText – and also, styled TextEdit work has not yet been started, which will be required in future to support more complex apps such as SimpleText and HyperCard 2.x.
Next up, on Toolbox API side, work is being done on Resource Manager’s resource fork write support, mostly just because after Scrap Manager was implemented, SuperPaint was able to progress a bit further in it’s startup, but wants to create “SuperPaint Prefs” file using Resource Manager’s functions, so might as well add that next. As of writing this, there’s already support for AddResource, ChangedResource and WriteResource, but we need to add resource fork compacting support to UpdateResFile to actually write the file properly. But we’ll get back to that later.
Bonus pic – for fun 🙂
Meanwhile, here’s a funny pic of what it looks when we run 28 M.A.C.E. instances at once 🙂 All quite responsive even though they’re all in full debug mode, although same can’t be said about the old Mac Pro when it was running them… 😀
This previous weekend, while helping Pukka to fix a mysterious coordinate calculation bug in Fool’s Errand intro, I decided to experiment with one weird idea: How about adding support for System Extensions and Control Panels? Therefore, yesterday I added the After Dark ‘cdev’ control panel to MacPaint app’s build settings to be included in the System Folder, and took some time to look what it would take to make it work.
Basically, INITs and cdevs are loaded during the startup by Mac OS by checking a few bits (such as file type, visibility, etc), opening the resource map of each file, and executing the first ‘INIT’ code resource found. At this experimental stage, we don’t yet have full INIT/cdev scanning, but instead have just a hard-coded filename to load INIT code from which works ok enough for this test case.
Our boot-time heap wasn’t quite properly set up yet, as the boot stack was too high, not leaving enough space between MemTop and BufPtr, which on the first attempt of running the INIT caused After Dark’s InitZone call to actually end up at top of the stack, causing all sorts of havoc. Besides that, there were a ton of bugs/improvements:
68k-to-68k trap calls did not work correctly (i.e. calling a trap patched with 68k from 68k code)
InitZone parameter block handling was completely broken from the last year’s trap refactor, so it was fixed
Memory Manager’s Handle validation had not taken into account the case where handle’s “relative handle” field would point to invalid memory location in some “fake” handles (as one in After Dark), for which validation was added
Empty stubs were added for Notification Manager calls to allow After Dark to call them during activation/deactivation of screen saver
Locking of 68k mutex was not done early enough, so After Dark’s VBL handler was making the initial call Launch trap to have invalid register values
After Dark uses grafProcs to call QuickDraw, so one missing case used by it was added (ovalProc for ovals)
After that bunch of minor tweaks, we have now at least After Dark working nicely!
Although the INIT code itself works, there is not yet any UI for displaying cdevs (Control Panels), so modules cannot be configured yet, and thus only the default “Starry Night” built-in module is displayed.
There’s also a short video to demonstrate After Dark running:
Although not very usable feature at the moment, this will definitely allow interesting possibilities in the future, as theoretically we should be able to run applications requiring certain application-specific extensions to be present in the System Folder. This experimenting with After Dark has anyway allowed us to find a number of important bugs (as previously mentioned), and also works as a very good “compatibility” test to see how well our Toolbox API and 68k implementation can handle one very quirky control panel, as it patches a ton of toolbox traps and does a lot of low-level stuff which all appear to be compatible with our emulation.
This week we reached a major milestone! From the encouragement on the work on HyperCard on 68KMLA forums, we got inspired to attempt tackling one major obstacle that was preventing it from working – file system write support!
As we mentioned earlier last year, when we last fall added the file system API, we did so using abstraction on top of AppleDouble file format. As Mac file system has the special dual nature of being split to data and resource forks, the AppleDouble format helps managing this in the emulated file system. Data fork, as mentioned earlier, is saved directly in its own file, while resource fork is merged with other file metadata in the AppleDouble header file. With this distinction, adding support for writing to data forks was really just trivial mapping of file manager write calls to the data file. Resource fork writing is a bit tricky, but we currently force the AppleDouble headers to keep resource fork as last element in the file, which allows us to offset also write operations from the beginning of resource data, and allows us to expand/shrink file easily, as end of resource fork is the actual end of header file. (One side note, setting EOF of files doesn’t have a standard C file operation, so we’re for now using the POSIX extension “ftruncate” which works at least on Mac OS X, but may lead to portability issues.)
Currently there’s very limited set of features for writing to file system implemented, basically just “Create” and “Write” file manager calls. For example, resource manipulation does not yet work as it will require a number of routines added to the Resource Manager to support it. However, one test application that directly benefited from this new feature was our beloved MacPaint, as it requires two scratch files to be present on startup volume/folder to function. This was nice, as it allowed us to add a few other missing features, such as PackBits (which also benefitted other apps and picture recording).
Although all tools don’t yet work perfectly, most of basic drawing functions are solid enough to not only allow drawing, but the experimental file writing also allows saving of MacPaint files, which appear to be readable by the Preview application in development host system Mac OS X 10.12!
Additionally, many other applications have seen improvements from this, as now we can save Civilization games and continue playing them! (Although Standard File package is still using hard-coded SFReply records).
The past week we’ve been busy working on optimizations on the 68k CPU and various improvements to the toolbox API. One of the improvements has been adding support for Apple’s MacApp MethodDispatch routine, which is used by Object Pascal and C+- (yes, that’s “C plus minus”, Apple’s proprietary C++ version which was briefly out before official C++ came to Mac). Basically, MethodDispatch is the virtual function table dispatcher commonly seen in C++ programs, but instead of being bundled in the application, it is actually implemented by the operating system as a toolbox trap – although with special calling convention, which cannot be called directly through A-line traps, but needs to be invoked through jump from 68k code. It handles selecting the correct implementation for class functions which can be inherited and overridden.
With the new MacApp method dispatching support, we should now be able to try running any MacApp-based applications – one cool such application, which is written in Objective-Pascal, is the first version of Adobe Photoshop:
Most of the dialog boxes appear to display (almost) correctly, although color picker, text input and popup menu support are missing so there’s little that can be done here:
And just to test out how it works, we did a quick “Hello world” drawing using Photoshop drawing tools inside MACE:
Although implementing the method dispatching routine was fairly trivial, some time was taken by other features used by Photoshop, such as crude International Utilities/Script Manager support, PrGlue dispatcher for printing (or as in current case, telling application that printers are not available), proper Gestalt support, and various bug fixes even to some fairly low-level things as handling of empty regions in UnionRgn calls, rewriting the 80-bit “Extended” floating-point format conversion in SANE, etc… A few other test applications did benefit of those additions, but we’ll post more about them later!
Ps. In case you are interested how MacApp-based application code looks like, the original Object Pascal source code for the first Mac Photoshop was at some time ago published as open-source and is available on github: https://github.com/amix/photoshop