This is just a quick status update to celebrate the new year 2020. As teased in the Christmas update one week ago, there has been some progress on the cross-platform ports of M.A.C.E., and this update is just to give a brief glimpse of the state of Windows and Raspberry ports (with a new year celebration theme):
Platform port status: Raspberry PI
Thanks to the hard to work and big efforts done by Pukka on the Raspberry PI port this year, we finally got it to the stage where Toni was able to integrate the platform into CMake build system, and create working builds for the test applications. Pukka found some performance issues in the SDL rendering, which motivated Toni to also get a Raspberry PI to help debug and identify the problem.
It was figured out, that the SDL2 graphics implementation we had previously used had serious issues, and was rewritten mostly to remove dependency on SDL surfaces, using instead SDL texture for the rendering. With this change, the performance on Raspberry improved to the point of matching the Mac (and Windows) platforms. Additionally, we took this opportunity to improve the fullscreen & pixel-double rendering code to the point that they are also almostready for public testing.
However, for some reason sound does not yet work on the builds done by Toni on Raspbian 10, although they seem to work on Pukka’s Raspbian 8. This need some more investigation, alongside some other issues on the platform. The basic X11 view driver + software renderer driver combination seems to offer however a good solution for the time being.
Platform port status: Windows
The Windows port, which we teased one week ago in the Christmas update, has advanced quickly and will soon be ready for testing. It took in total one week (the Christmas vacation) for fixing the code for MSVC compiler compatibility (a couple thousands errors), and getting the builds to run. The changes we needed to make include:
Fixing problems with zero-size struct arrays
Lack of typeof(x) macro leading to need to refactor all byte-swapping and RSAlloc macros (and places where they were used)
A couple header changes (such as alloca being defined in different headers on POSIX vs. MSVC)
Adding some Windows API code for file system iteration and manipulation alongside of POSIX/Std C code
Fixing some bugs that were surfaced by the new port, but were affecting all platforms
Other minor changes (clock API, refactoring unistd references, tweaking CMake configs, etc…)
The remaining tasks for first Windows test release are still integration with Windows executable resources, and storage of the NativeFS data on windows builds.
The year 2020 should definitely bring us to the point of releasing a more generic way to run M.A.C.E., including additional platform support, and compatibility with much more applications. At the moment the focus is – beside adding the new platform support – on getting as many of the known issues in the current test applications fixed (which you can follow in our status page). But looking forward to the stage #2 of project, we also hope to start work on Sound Manager and Color QuickDraw implementation in the second half of 2020.
Full list of changes since last post
2020-01-01 02:31:53 +0200 • Fix order of debugger setup in environment headers
2020-01-01 02:18:32 +0200 • Set MemErr to noErr if GetHandleSize succeeds
2020-01-01 02:17:18 +0200 • Add Finnish Apple Macintosh Basics as test app
2019-12-31 22:49:19 +0200 • Fix byteswap sign bug in CalcMask/SeedFill
2019-12-31 04:47:15 +0200 • Only grab input in fullscreen mode
2019-12-31 04:12:39 +0200 • Merge branch 'master' of
2019-12-31 04:12:34 +0200 • Fix GCC byteswap macros for raspberry pi
2019-12-31 03:59:25 +0200 • Use left control as command key on windows
2019-12-31 01:46:39 +0200 • Refactor SDLPlatform to use Textures, not Surfaces
2019-12-31 00:07:32 +0200 • Merge branch 'master' of
2019-12-31 00:07:13 +0200 • Update CMake configs and MacTCP for raspberry pi
2019-12-30 22:25:41 +0200 • Merge branch 'master' of
2019-12-30 22:24:27 +0200 • Fix buffer overflow in StretchBits dstScanlineBuf
2019-12-30 21:43:20 +0200 • Fix case-sensitive FS filename issue in CMake file
2019-12-30 02:07:02 +0200 • Fix+optimize pixel-double and fullscreen rendering
2019-12-29 22:41:31 +0200 • Merge branch 'master' of
2019-12-29 22:41:21 +0200 • Fix Windows build audio issue (SDL buffer format)
2019-12-29 22:39:38 +0200 • Fix crash: Add missing Open/OpenDeny error checks
2019-12-29 03:57:01 +0200 • Fix debug strcat in AVLTree.c for Mac version
2019-12-29 03:33:38 +0200 • Refactor byteswapping (& clean up lot of warnings)
2019-12-29 03:25:58 +0200 • Enable console mode for now in MSVC (for debug)
2019-12-29 03:25:18 +0200 • Fix signature of argc argument in main method
2019-12-28 23:36:15 +0200 • Fix bug in path separator conversion in MSVC build
2019-12-28 17:32:02 +0000 • Fix some sign bugs, 1000 miles now starts on Win32
2019-12-28 17:29:58 +0000 • Use MSVC built-in byteswap macros for byteswapping
2019-12-28 17:28:21 +0000 • Fix SDL main & set executable as a Windows GUI app
2019-12-28 15:25:55 +0200 • Fix malloc.h/alloca.h header includes for MacOS
2019-12-28 15:02:36 +0200 • Merge branch 'master' of
2019-12-28 15:02:31 +0200 • Clean up misc debug macros etc before win32 merge
2019-12-28 02:22:10 +0000 • A MAJOR Windows and MSVC compatibility update
2019-12-27 21:59:06 +0000 • Fix potential timestamp conversion shift overflow
2019-12-27 21:56:14 +0000 • Fix byteswap bug in fractional pen location init
2019-12-27 00:39:38 +0000 • Don't try to return value from void function
2019-12-27 00:00:32 +0000 • Fix wrong data size in low-mem Rect setter macro
2019-12-26 23:00:41 +0000 • Merge branch 'master' of
2019-12-26 23:00:27 +0000 • Ignore MacOS-specific files in MSVC cmake targets
2019-12-26 22:58:38 +0000 • MSVC compatible SDL clock (and rotate macros)
2019-12-27 00:09:04 +0200 • Init PortList and ChunkyDepth
2019-12-26 21:18:10 +0200 • Improve InitApplZone, add some CQD low-mem globals
2019-12-26 21:09:34 +0200 • Add proper alpha to SDL RGB output (->pixeldouble)
2019-12-26 21:08:03 +0200 • Add temporary IODone stack hack for MacTCP driver
2019-12-26 21:04:59 +0200 • Use new enum for killCode in Sound Driver
2019-12-26 21:04:20 +0200 • Add more logging to .IPP driver
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
Recently, somebody was asking on Emaculation forums, what would happen if Apple’s Finder would be attempted to run in M.A.C.E.? That was an interesting question, which motivated us to try it out.
Mac System Software architecture
To think about what would make Finder work, let’s consider the classic Mac system software as an architecture consisting of roughly three layers (in real Macs):
ROM: Most of Toolbox APIs, ROM resources and stage 0 boot loader.
System: Patches to ROM, extensions, system zone, the so-called “kernel” of old MacOS.
Finder: The “desktop metaphor” front-end running as a regular Mac application.
This categorization is very naïve, does not consider details such as role of hard drive drivers in boot process, etc. Additionally, M.A.C.E. combines roles of ROM and System as a single entity implemented in native code.
The interesting part to highlight is how Finder is basically “just another” application running on the System, and was even replaced by alternate startup applications on the old Macs (such as MiniFinder, MultiFinder, or other applications using the “Set Startup” option). As such, especially on System 6.x and older, the undocumented dependencies between System and Finder might be few in number, if any.
The first run
So, the question was, what would happen if we would try to run it? Well, we got this far on the first attempt, and with a couple minor fixes to progress further:
So, almost there. What we needed was a couple new (missing) routines and some fixes:
Fixed the 0x16 and 0x17 csCodes for .NativeFS driver, which return the logical/physical ICN# data for the volume icon (as seen on the desktop). We actually had that icon already one year ago, but this was the first time anything wanted to access it. 🙂
Added working directory indexing to GetWDInfo, which Finder uses to close all open working directories, presumably left open by misbehaving applications under System 6.x.
Fixed a buffer overflow bug in GetVolInfo (in volume name).
Implemented File locking APIs, which Finder wants to use to maintain the Desktop file.
Getting to the desktop
After a long and tedious session of debugging, it was discovered that due to a stupid bug in GetWDInfo Finder was crashing upon attempting to enumerate volumes. After that fix, we got nice Finder desktop, and a lot of functionality already working:
Operating on the Finder windows added need to implement a couple other missing traps, although as dummy versions for now (SetCatInfo and SetVolInfo, which Finder attempts to use to write metadata about modifications done in the spatial finder windows, icons, etc). Some points:
Finder and system icons appear as documents, but that might be because those don’t yet exist in the System file. Not sure about that yet.
It’s nice to see how a Finder 6.1.8 from Apple’s real System 6.0.7 behaves nicely even though M.A.C.E. System declares being version 7.0. 🙂
For some reason, doing “Get Info” on our Hard Drive turns our custom icon returned by the .NativeFS DRVR to a generic floppy icon.
It’s interesting how Finder considers at the moment our custom Hard Drive as “AppleTalk” device, but that might be because we’re hooking into the ExtFS file manager hooks which *I think* were used by AppleTalk in the real System 6.x. Just another thing which needs more investigation.
The modification and creation dates shown in “Get Info” (and list-style finder windows) use International Utilities date & time formatting functions, which are still placeholders. And as such, they only display mostly the numeric value of date-time instead of the proper, human-readable format.
Making the Desktop file work
At this point, we didn’t yet get the proper application and document icons to appear, so we did a bit more debugging on what was happening with the Desktop file – which Finder uses to keep track of known application creator & types, file comments, etc. It turned out, that we accidentally had all the “hasBundle” (0x2000) bits turned off in applications, which is why they were not detected by Finder.
As this issue was fixed, Finder started to process the applications properly, and quickly needed a some improvements to Resource Manager APIs. Mostly, it wanted to use UniqueID to allocate unique IDs for resources inside the Desktop file’s resource fork (to avoid conflicts). After that, updating Desktop file seems to work quite nicely, resulting in some fancy icons now appearing in the Finder under M.A.C.E.:
For now, running the real Finder remains as a curiosity, but nevertheless works as a great test case for a various number of Toolbox File Manager APIs which still need work (among some other minor bugs). The summary of the major known issues is:
The launching of programs “almost” works. Everything else appears to be fine, but it suffers from the same issue as previously found out using the “Transfer” command in THINK Pascal: The Font Manager data caches do not clear completely, leaving some dangling handles/pointers to the old application zone, which cause crash on attempting to reference them after the zone has been reinitialized for the new application.
Getting back to Finder (or any shell) is not yet possible, as ExitToShell is still hard-coded to terminate the entire emulator, instead of launching LMGetFinderName() application. Getting this to work would also encourage researching the Emscripten and Process Manager compatibility, as all of those features share a common need for a better in-emulator process management.
SetCatInfo/SetVolInfo are still dummy placeholders, so Finder is trying to use them to update metadata, though it is not yet saved.
Folder creation (_DirCreate), File/Folder deletion (_Delete), renaming (_Rename) are not yet implemented, so attempting those operations on Finder will still fail.
The _Eject trap is not yet implemented (and in any case you will not be able to eject the NativeFS drives).
As previously pointed out, Date & Time formatting does not yet work
The “Rebuild Desktop” operation (though using option + cmd keys at startup) does not yet seem to do the actual rebuild on a “fresh” start (i.e. if Desktop file has been wiped). Additionally, attempting that operation while old Desktop file exist will error out because _Delete is unimplemented, and old file cannot be removed out of the way.
Maybe other issues too, those are just the ones found out in the quick testing.
The “generic” M.A.C.E. environment might benefit of this though, as a replacement shell and/or program launcher, that could be optionally used by the end-user.
Full list of changes since last post
2019-12-12 18:19:41 +0200 • Add UniqueID/…1ID, to allow Desktop file updates 2019-12-12 17:49:18 +0200 • Add Disk Initialization Pack2 to keep Finder happy 2019-12-12 17:46:55 +0200 • Fix byteswap bug in NativeFS _Allocate handler 2019-12-12 15:00:12 +0200 • Add missing NativeFS.c changes for previous commit 2019-12-12 04:34:28 +0200 • Add dummy SetCatInfo and SetVolInfo selectors 2019-12-12 04:02:48 +0200 • Fix GetWDInfo bug (ioVRefNum & ioWDVRefNum mixed) 2019-12-09 02:58:47 +0200 • Fix memFullErr check in SetApplLimit 2019-12-08 06:31:06 +0200 • Fix filename overflow in GetVolInfo NativeFS call 2019-12-08 06:30:06 +0200 • Implemented CloseWD 2019-12-08 06:29:03 +0200 • Add WD indexing to GetWDInfo 2019-12-08 06:27:20 +0200 • Add Finder test app to cmake configs 2019-12-08 06:27:01 +0200 • Implement icon csCodes in NativeFS Control call 2019-12-08 06:25:52 +0200 • Make more macros in memory manager MSVC friendly 2019-12-08 06:25:18 +0200 • Add dummy SetFilLock and RstFilLock 2019-12-08 06:23:36 +0200 • Fix FinderName lowmem global 2019-12-06 23:44:06 +0200 • Add Bash Big Blue to cmake config for testing 2019-12-04 21:21:36 +0200 • Fix QD_LOG to respect debug settings 2019-12-04 20:48:17 +0200 • Add Cairo ShootOut! to cmake config for testing 2019-11-30 02:02:05 +0200 • Fix empty VA_ARGS problem in MaceLog macro 2019-11-29 23:55:30 +0000 • Make SWAP and MIN/MAX macros MSVC compatible 2019-11-29 23:54:08 +0000 • Made vararg ellipsis parameters MSVC compatible 2019-11-29 23:52:21 +0000 • Make Memory Manager return macros MSVC compatible 2019-11-29 23:51:27 +0000 • Make ROMScratch macros MSVC compatible 2019-11-29 23:50:08 +0000 • Move SwapPoint to MacQuickDraw.h to make it inline 2019-11-29 23:48:05 +0000 • Change void* to UInt8* in fake ROM (for MSVC) 2019-11-29 23:46:50 +0000 • Make SANE conversion macros MSVC compatible 2019-11-29 23:33:03 +0000 • Merge branch 'master' of 2019-11-29 23:32:43 +0000 • WinAPI EndianXX_Swap macros 2019-11-30 01:30:54 +0200 • Add UInt128 type to EmuMacTypes.h
Before Macintosh was created, there was a computer architecture called IBM PC. With Intel 8086 processor, it was incompatible with the Motorola 68000 family used in Macintosh computers – and thus, no IBM PC software would work in Macintosh. But there were some really smart people, who created a special application called SoftPC in mid-80’s, which interpreted Intel’s x86 instructions on the fly, and emulated enough PC architecture and BIOS ROM to allow those programs to run on Macintosh. And now, SoftPC finally also works on M.A.C.E.
SoftPC 2.51 architecture
The version of SoftPC we got to run is 2.51, which happened to be compatible with the “Classic”-type 68000 Macintosh computers, one which M.A.C.E. aims to emulate in the Phase 1. That is, it works on 68000 processor, supports the 1-bit “classic” QuickDraw on 512×342 screen, and appears to be compatible with System 6 level Toolbox calls.
The IBM PC architecture which SoftPC 2.51 emulates is IBM XT with 640 kilobytes of RAM, and a CGA monochrome display. It also supports two serial ports (although M.A.C.E. serial port drivers are still unfinished to try them out), a printer port (no printing support for us yet), two hard drives (through disk images), and two physical floppy drives (which we don’t either emulate yet).
The XT memory map
The challenging part of getting SoftPC to work was ingenious way it emulates the PC memory map. As everybody knows, IBM PC has physically 20-bit addressing scheme (through 16-bit segment and offset register pairs, which give 4+16 bits of usable virtual address space, as there is overlap between segments). This 20 bits equals 2^20 = 1048576, or 1 megabyte of address space. What SoftPC does, is that it allocates this entire 1 megabyte area to be linearly accessible throughout the physical Macintosh address space, but it saves memory by allowing this area to have “holes” in it for the non-used areas of the PC memory map. This is basically the layout it creates:
0B8000-0DDFFF: CGA video memory
0F0000-0F4FFF: ROM BIOS #1
0FE000-100000: ROM BIOS #2
The steps it uses to ensure this linear layout is created is quite unique, and a good challenge to test the memory manager implementation:
For starters, the availability of large enough linear memory space is ensured by doing allocation of 1048576+32 bytes of memory using NewPtr. If this fails, it will know that there won’t be enough memory.
The allocated space is shrunk down to the 640K+32 RAM size using SetPtrSize. (The 32 bytes extra is used for aligning the actual addresses inside allocations to 16-byte boundaries for apparently memory access speed optimization on later Macs).
The three other blocks (CGA memory and two ROM areas) are allocated at correct locations using the following algorithm:
The size of “hole” preceding the allocation is calculated. For example, having video memory at B8000 would leave 18000 bytes space between A0000 and B8000.
Two pointers are allocated after each other using NewPtr: one for the hole (using calculated hole size), and the actual memory block (+32 bytes for alignment).
Now this is where the magic happens: If the latter allocated block’s start would not be within alignment range of the required offset (in CGA case B8000) from start of RAM (the 640K block), the size of hole would be decremented with 16 bytes, the two blocks would be disposed, and allocation re-attempted at step 3-2.
After repeating steps 3-2 through 3-3 enough so that required range is reached, the pointer to the allocated hole block is saved, and next one of the three blocks is allocated starting from step 3-1. (It should be noted, that because of a very minor bug in M.A.C.E. memory manager, the allocation size failed to decrease, and this loop would be terminated after 64 attempts, with incorrect block left allocated.)
After all three blocks have been allocated at correct offsets, the holes preceding each of them would be disposed using DisposePtr. This part of process leaves space inside the emulated PC address space, which the Toolbox can use for any regular memory allocations – pointers and handles, even resources. It is not 100% certain, but it may be that SoftPC may optimize performance in such way, that writing to PC address space at these holes might actually even cause native memory to get corrupted, BUT for now we did not try to see if that might happen.
The issue with Memory Manager in step 3-4 was, that as the DisposePtr call on the two blocks actually creates two adjacent “free” blocks, the allocation of new block using NewPtr right after that with only 16 bytes smaller size, would actually not return a physical block with smaller size. This was, because the block allocation routine checks if the space between allocated and next block would be less than minimum allowed block size (for creating new “free” block between allocation and next block), it would actually merge that small bit of space back to the physical allocation. The bug in Memory Manager was, that the when allocating block in free space, it was supposed to always merge the next “free” block after the allocation, and slice the new “free” space from that. A real Mac merges only one extra “free” block after allocation, but in M.A.C.E. for simplicity we fixed this by merging all free space in one run, thus at the same time reducing clutter of having many adjacent free blocks.
With this fix in Memory Manager, SoftPC is now finally able to boot up. Thanks to the Standard File Package implemented earlier this autumn, we could not only configure the hard disk image (C:/), but also set up a “shared” network disk (E:/) through a folder inside emulated Mac file system. This allows easy access of files (and thus DOS applications) from the M.A.C.E. file system, including some games. The shared disk access routines, however, surfaced luckily a couple File Manager bugs, related to the ioNamePtr handling in _GetCatInfo and _GetFileInfo calls, which possibly also improve compatibility of other applications too.
Below are some screenshots of the configuration dialogs of SoftPC (click for larger image):
And here is DIR command output right after booting up:
Also, there was GWBASIC included with the DOS installation, so we can run GWBASIC compatible BASIC programs:
And also some games work nicely. The Monochrome CGA emulation has interesting approach of emulating the 320×200 resolution with 1.5x scaling as 480×300 pixel bitmap display. The four CGA colors are also mapped into distinct vertical stripe patterns, which might also have been used on some old monochrome CGA displays:
Of the two above games, SOPWITH appears to be quite responsive and playable, but ALLEYCAT controls are very laggy. Also Sierra adventure games seem to run:
The Black Cauldron (pictured above) seems to work just fine, although for some reason the function keys were not working, while they did work in GWBASIC earlier (opening of doors with F6, for example). Also, none of the games produced any sound although the SoftPC boot beep works, so it might be that SoftPC may lack actual PC speaker emulation in this particular version (beyond the beep).
Other issue that we also fixed while working on this was a bug in Scrap Manager, which caused the clipboard to misbehave when working in “on-disk” mode (after _UnloadScrap was called). This allows Copy-Paste operations to work nicely in SoftPC, and it also improves clipboard functionality in other applications.
Only remaining issue with SoftPC is that some routine, possibly in SANE and most likely related to converting PC date & time, is causing divide overflow error to popup at random times, which appears to be related to the actual date & time. This needs to be investigated still at later point.
Full list of changes since last post
2019-11-27 00:34:43 +0200 • Fix a Scrap Manager bugs, fixes SoftPC copy+paste
2019-11-26 23:06:55 +0200 • Fix ioDirFlag to be 4 which appears to be correct
2019-11-26 23:06:27 +0200 • Don't crash on invalid zone in Handle validation
2019-11-26 04:01:31 +0200 • Fix register-based 68k->native UPP calls' D0 nuke
2019-11-26 03:57:20 +0200 • Don't overwrite *ioNamePtr if not indexing files
2019-11-22 03:41:15 +0200 • Add FREMS selector to SANE's FP68K dispatcher
2019-11-22 03:40:22 +0200 • Force merge of free blocks at end of BlockFindSize
2019-11-19 22:59:13 +0200 • Fix bug where everything left of a list got erased
2019-11-19 22:55:27 +0200 • Redraw modified cell in LSetCell
2019-11-19 01:42:03 +0200 • Add support 23 new native 68k exception handlers
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)
It’s been quite a while since last update, which is due to combination of us being busy real-life jobs, and focusing work on this project on a monolithic feature, which in this case is nothing less than getting the Standard File Package to work!
This is list of the features which the M.A.C.E. Standard File Package emulation is currently capable of:
All 8 selectors for Pack3 (SFPutFile, SFGetFile, SFPPutFile, SFPGetFile, StandardPutFile, StandardGetFile, CustomPutFile, & CustomGetFile). The ones tested are highlighted, but others should work too.
Support for custom file dialogs (with assorted hacks to convert MFS-style dialogs, such as the “Save” dialog in MS-BASIC 2.00, to the new HFS-style format)
Supports both SFReply and StandardFileReply outputs
File listing using List Manager, which displays currently System 6-style SICNs, but with System 7.1+ style spacing (later expandable to use the real icons, when we get Desktop Manager interface)
Path popup menu, visually and functionally like on real System 7.x
Desktop folder support
Focus on selected items (including file list with highlight frame), alterable by mouse or tab key
Most of common SF key shortcuts: Clipboard shortcuts, Cmd+S (Save), Cmd+O (Open), Cmd+N (New folder), Cmd+D (Go to desktop), Cmd+Up (Go to parent), Cmd+Shift+Up (Go to root/desktop), Cmd+Down (Open folder), (Cmd+Left/Right to browse volumes not yet implemented)
Filename field input filtering (prevents “:” from being used in filenames, which is path separator). Also, copy-pasted filenames will be filtered with proper alert messages.
Not yet implemented: sfHookOpenAlias, sfHookGoToAliasTarget, sfHookGoToNextDrive, sfHookGoToPrevDrive, sfHookChangeSelection, sfHookSetActiveOffset
File type filtering supported, both by typeList and FileFilterProc
Although most of the Standard File Package is functional, and usable, there are still some issues left:
Because DirCreate is not yet implemented in NativeFS layer, FindFolder cannot create the Desktop Folder/Trash folders to the file system, thus at least Desktop Folder needs to exist to allow access to “Desktop” level in the SF dialogs. This also prevents “New folder” from actually creating the folders.
Eject button does not yet do anything, as the NativeFS volumes are non-ejectable
There are minor differences to real System 7.x style SF dialogs, for example with certain elements being a few pixels off their intended locations, and popup menu’s width not always expanding
Some custom dialogs don’t yet work exactly as they should, for example THINK Pascal 4.0 “Add files” dialog erases left edge of the applications own custom list located below the SF file list, and for some reason it allows attempts to add folders as source files…
Location of the SF dialog is sometimes not correct (for example, Railroad Tycoon’s “Save game” dialog is partially under the menu bar)
We cannot yet create app bundles for the currently working freeware/shareware applications that use StandardFile, because when sandboxed the bundle file system is read-only, and thus attempting to save anything to it would straight out fail. To work around this, we need to implement certain changes to the way file system in bundled applications is handled, but we are already working on that for the next release
Other improvements made for Standard File
There were a couple features that were implemented as part of Standard File Package implementation, some of which were necessary to make it work
NativeFS AVL tree balancing and iteration support
One important feature was the need for catalog iteration, which is used by Standard File dialogs to enumerate the files in current folder to be displayed in the file list. This allows for example GetCatInfo to use ioFDirIndex in the parameter block to index specific files inside given directory.
Also, this gave a good excuse to finally implement the actual AVL balancing algorithm in the NativeFS file system, which until now had behaved mostly as a dummy binary tree. Below is a screenshot of how the file system structure was changed by the balancing algorithm:
On the right-hand side, is the unbalanced “dummy” binary tree, and on left-hand side is the same file system, when using AVL balancing algorithm to do the insertions. The deepest nodes were reduced from, in this case, from way over 100+ key comparisons into a rough maximum of 10+.
Popup Menu Control
One important feature of the HFS-style Standard File dialogs is the navigation aid provided by the path popup menu. For this, the Popup Menu Control CDEF 63 was implemented. On real Macs, this was originally part of Communications Toolbox, before it was merged to the System 7.x at some point. The Standard File dialogs use only a subset of its features, but foundation for most use cases was built at the same time, so taking it into more common use should be quite easy. As it uses the Menu Manager’s PopUpMenuSelect trap call, the actual menu selection was already there.
One fun and tricky part though was the need to add MDEF “wrapper” for SF popup path menu, to ensure that the opened popup menu would never be narrower than width of the popup control. To do this, the control imitates how the real Macs did this by adding temporarily a MDEF “wrapper”, which injects modified menuWidth value to the menu after it receives a mSizeMsg message from the Menu Manager, thus modifying the resulting popup menu size.
Picture Button Control
The CDEF 61, picture button, was implemented just to allow adding the “New folder” button to the “put” dialogs. It is quite simple, at least in monochrome version, just drawing a PICT resource as content of a regular push button
Dialog Manager improvements
The StdFilter, which is also used by Standard File dialogs, was improved to add features used by it:
Outlining default button with FrameRoundRect
Handle “cancel” item’s shortcut key as escape/cmd+dot
Track cursor to turn it into i-beam over enabled textedit fields
Handle update events for default items
Also, the default shortcut keys (Cmd+X/C/V for Cut/Copy/Paste) were also implemented in DialogSelect trap.
Other news: 68020/68040 support
In other news, Pukka has also been busy adding 68020/68040 support, which includes:
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.
The past few weeks have mostly gone to improving performance of the runtime environment. Although all the apps have been running smoothly without any issues, there was not much focus on improving the actual CPU usage of the host system.
Unlike hardware-based emulators such as Mini vMac, where everything including applications, ROM, and system software run on 68K, in M.A.C.E. there is distinct separation of execution between 68K based code, and the Toolbox code written in native C. This creates some minor issues with managing performance, as especially in regards of early software – QuickDraw routines would be much slower on real 68000 hardware, and thus games depending on certain 68000 execution speed would experience certain slowdown of using those QuickDraw (and other Toolbox) routines.
However, in M.A.C.E., the native code always runs at full speed, and those expectations break down as experienced in Stunt Copter, Zero Gravity, Harrier Strike Mission II, Brickles among some other applications. To mitigate this, there is an artificial slowdown that the emulator can optionally enable delay throttle in GetNextEvent, which we have so far used to make most of the aforementioned applications usable.
68K emulation throttle
Pukka added an experimental throttle to the 68K emulator, which attempts to slow down applications which do for example busy-looping and polling of TickCount to perform timing. In the old non-multithreading MacOS, this kind of timing was pretty common especially in games that required precise control on the CPU resources. This should in future help CPU usage in programs heavy on 68K code in game loops, such as Dark Castle and Apache Strike. This however does not help the cases which rely a lot on Toolbox, such as the applications which benefit of the GetNextEvent delay throttle.
SystemTask and execution yielding in Toolbox routines
As some may remember, when Apple transitioned from Mac OS 9 to X, one way to yield execution was to add SystemTask calls to blocking loops (in cases where WaitNextEvent would not be desirable). As the Toolbox in M.A.C.E. is completely implemented in C, we have the power to choose yielding strategy ourself, and for that we are experimenting at the moment with very small delays of 1 millisecond on each call to SystemTask, and any other busy-looping toolbox routines, which include:
MenuSelect and PopUpMenuSelect
TrackControl and DragControl
DragTheRgn (affecting DragGrayRgn and DragWindow), GrowWindow and TrackBox
Delay (it had earlier implementation used by the GetNextEvent hack, but was implemented in a rather stupid way which ended up as a busy-loop on host CPU…)
File Manager synchronous command queueing
Device Manager synchronous command execution, and driver close
Video rendering and dirty-rectangle detection
Another optimization feature was the addition of detection of video memory “dirty rectangles”, which define which areas of video memory have changed, so that only those would need to be drawn to the screen. This optimization is being experimented especially to improve the future fullscreen and pixeldouble modes (which are not yet enabled due to requiring still some work), and depending on the machine and application, there is varying degree of performance improvement, but not very much (which is to be expected as the 512×342 screen with 1-bit colors does not require a lot of the CPU in regards of pixel format expansion and SDL surface updates).
With these changes, we got CPU usage of 100% to drop to around 7-10% on a Mid-2010 Mac Pro, and 9-12% on 2015 MacBook Pro of the currently bundled applications. Of course, some test applications we are experimenting with still require further work to gain these benefits, but this should help at least keep those fans more quiet on MacBook computers 🙂
We have also updated the test application bundles with these new optimizations in the downloads section on this blog.
Hierarhical menus and PopUpMenuSelect
In addition to performance optimizations, we also finally added the hierarhical menu and popup menu support which was for a long time waited to make especially Railroad Tycoon way more playable.
There was a bit of tweaking, bug fixing, polishing, more bug fixing and tweaking to get those two features to work, but now they appear to work exactly like on a real Mac (timing, positioning, mouse tracking behaviour, screen buffer saving, etc). Sadly we don’t have yet any bundled test applications to demonstrate this, but at least the applications we are using internally all work perfectly.
These are again another major features which gets us closer to the “general classic replacement” release, although there is still lot of work needed to get us there. The progress is however very promising at current pace.
Full list of changes since last post
2019-09-05 01:47:24 +0300 • Add dirty rectangle visualization to debug build
2019-09-05 00:35:24 +0300 • Update runtime version in cmake script
2019-09-04 12:44:03 +0300 • Fix offset of minimum-intersection dirty-rectangle
2019-09-04 03:38:02 +0300 • Finally fix that darn StretchBits…
2019-09-04 03:14:55 +0300 • Improved, faster dirty rectangles with bit-o-magic
2019-09-03 22:35:25 +0300 • Implement GetItemIcon and SetItemIcon traps
2019-09-03 22:21:14 +0300 • Add pixel-double support also to windowed mode
2019-09-03 22:20:11 +0300 • Fix uninitialized mouse loc in PopUpMenuSelect
2019-09-03 01:27:55 +0300 • Implement prototype dirty-rectangle video renderer
2019-09-02 22:42:44 +0300 • Add EnvRunBackgroundTasksReleaseCPULockWithYield
2019-09-02 20:43:19 +0300 • Fix hit-testing of hierarchical menus in MBDF
2019-08-30 22:31:02 +0300 • Fix mouse button check in relative mouse mode
2019-08-30 03:13:25 +0300 • Update trap list XLS/CSV
2019-08-30 03:06:21 +0300 • Implement basic non-styled TEPaste
2019-08-30 02:56:58 +0300 • Fix two masking bugs in CopyMask
2019-08-30 02:07:25 +0300 • Implement pic opcodes 0x1A & 0x1B (RGBColor fg/bg)
2019-08-30 02:04:08 +0300 • Fix popup menu crash
2019-08-30 01:13:42 +0300 • Initial fullscreen (and pixel-double) support
2019-08-28 22:25:51 +0300 • Enable delay hack in Brickles test app
2019-08-28 22:25:34 +0300 • Add execution yield for 1ms to SystemTask
2019-08-28 21:54:36 +0300 • Fix the earlier video update limiter adjustment
2019-08-28 13:31:18 +0300 • Experimental change to lower CPU usage, has issues
2019-08-27 23:54:36 +0300 • usleep logic to m68k helper
2019-08-27 05:04:18 +0300 • First proto of PopupMenuSelect, has bugs
2019-08-27 00:32:21 +0300 • Merge branch 'master' of
2019-08-27 00:32:17 +0300 • Also handle shortcut keys for submenus in _MenuKey
2019-08-26 21:46:33 +0300 • Merge branch 'master' of
2019-08-26 21:45:28 +0300 • revert unwanted modification
2019-08-26 17:02:42 +0300 • Fix left-hand side hierarchical menu handling
2019-08-26 03:13:36 +0300 • Fix icon alignment in default MDEF 0 item drawing
2019-08-26 02:30:48 +0300 • Merge branch 'master' of
2019-08-26 02:30:42 +0300 • Add "bermuda triangle" to hierarchical menus
2019-08-25 20:36:24 +0300 • move pc increment away from instructions + some optimizations
2019-08-24 23:38:22 +0300 • Update instructions.c
2019-08-24 23:17:34 +0300 • some optimizations and ea macros
2019-08-24 15:33:05 +0300 • Improve hierarchical menu tracking
2019-08-24 01:12:35 +0300 • Fix GetItemMark/Cmd/Style result byteswap bug
2019-08-23 19:41:36 +0300 • Fix drawing of hierarchical menu items
2019-08-23 04:36:38 +0300 • Merge branch 'master' of
2019-08-23 04:35:57 +0300 • First rough proto of hierarhical menu support
2019-08-22 21:51:52 +0300 • fix cmpm instruction with FAST_ADDRESSING
2019-08-21 00:30:28 +0300 • Add cmake config for Brickles, which was missing
2019-08-20 02:31:00 +0300 • Use rb fallback in NFSOpenFileHook is r+b fails
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