Category Archives: Controls

Summer ’22 update

In attempt to increase frequency of status updates on the project after slow progress during the past year, here’s some information about what we’ve been working hard during the summer vacation.

Styled TextEdit updates

One of the most overlooked – but still very important – features has been the Styled TextEdit support. We already had started working on the foundations almost two years ago, and had last year got the drawing to work pretty well (mostly focusing on Marathon’s “computer terminal” screens) – but actual editing features of the styled text have been largely missing. Luckily SimpleText, with its fully-featured styled text editing features, provides a bunch of test cases for a number of them. Below is screenshot of some text styling at work:

Basic styled text editing in SimpleText

Right now, styled text can be finally entered (using various style parameters such as face, font, size), and SimpleText can also open various text documents with styling information. Below is one example, the READ ME file of Prince of Destruction:

Opening a styled text document in SimpleText

But a lot of work needs to be still done, as major features are still unfinished (such as hit-testing of styled text records, which is needed for both mouse click, arrow key and selection support).

“AppleDoubler” tool

Motivation to work on the “AppleDoubler” tool got boost by a question asked in the June on emaculation about our file system choices. We had planned for a long time to make tool for converting native Mac files to the ADF format, but hadn’t taken time to work on that until now. It didn’t actually take more than a couple hours to write (plus some random time to do some tweaks later), but as nice effect we are able now to convert applications for testing blazingly quickly (compared to the manual conversion process earlier). This has led to discovery of a number of bugs which were fixed, and missing special cases of existing features that have been tweaked.

The AppleDoubler tool will be available as soon as we sort out our binary distributions to work a bit better (until now, files have been hosted here on the WP blog, but due to a bunch of issues with executables, and the time-consuming progress of updating downloads page, we will look into more automated alternate solutions, to allow more frequent updates, and also more downloads to be available.)

Software cursor

One longtime “to-do” task has been proper software cursor implementation, which has been delayed mostly because SDL’s cursor API has handled the monochrome cursors quite well for most of the use cases. However, there have been three downsides of this approach:

  1. The “inverted” cursors (such as the I-beam, and Lemming’s cursors) don’t show up properly, as most modern host systems don’t support inversions in cursor graphics. Especially in lemmings this has been tricky in the monochrome mode, as the cursor would appear black on black background, making the game really hard to play
  2. The native cursors don’t show up when doing screenshots of windows, or when capturing in OBS using window capture. This has been mostly prominent on Twitch streams where mouse has been invisible
  3. Color cursor support has been unimplemented, as for proper ‘crsr’ display the mapping of cursor color table needs to be done

The final push for software cursor implementation came when we tried running Super Studio Session editor, which replaces a number of default cursor vectors with its own implementation (which it uses to align the “note” cursor on music sheet at certain spots). We saw that the cursor that application implemented all by itself worked mostly really well, but because of some ShieldCursor bugs, it was leaving trails at certain places. Below are screenshots of Super Studio Session (ignore the “THINK Pascal” window title, we don’t yet have proper general-purpose shell/desktop application yet, so we used the very practical “Transfer” feature of THINK Pascal to launch any application from the file system through Standard File dialog, without needing to do any extra work 😀 )

It took a couple days of work to get the software cursor to work (the work was sped up a lot by a number abstractions we had done earlier, related to VBL task execution etc), and adding color cursor support was not that tough as ‘crsr’ and ‘ppat’ resources share a common heritage, and thus their color table and depth expansion code could be shared. Below are some screenshots of Civilization, showing the color mouse cursor in action:

SoftWindows

As a curiosity, in progress of trying out various applications, we noticed that SoftWindows 1.x (the last 68k-compatible version of that application) seems to work pretty well. As it does have quite high memory requirements (considering the currently implemented 24-bit memory manager by default has only 8 megabytes of RAM), we did have to make a temporary hack to boost the RAM limit in the test configuration to 12 megabytes (leaving space for only 3 slots in the emulated slot address space – while the default configuration allows up to 7). This allowed us to actually boot into Windows 3.1 and run a number of games/apps on it (biggest limiting factor for what worked was that this version SoftWindows only emulates a 286, thus allowing only Standard mode in Windows 3, instead of the Enhanced mode required by a lot of applications). Below are some screenshots of what we tried out:

MIDI Manager research

As we knew that certain Sierra games do advertise MT-32 compatibility, we did some quick snooping around, and learned that at least Space Quest 1 does use Apple’s little-known MIDI Manager to handle the hardware MIDI playback (unlike Thexder, which appears to have its own serial driver for MIDI, choosing to use the serial port directly). This led to some curiosity about the MIDI Manager implementation, for which there is sadly very little documentation – an article about programming it on the always valuable MacTech archive and the universal headers. A couple articles from mid 90’s point to ARPA as source to buy the MIDI documentation and SDK from, which sadly is no longer available.

The work on MIDI Manager support is still ongoing, but we feel it might be relatively easy to write a layer that emulates MIDI Manager’s patching features, and wrap the MIDI driver as a abstract device that could pass the MIDI packets to host OS’ native MIDI interface (in Mac OS X case, the CoreMIDI). All MIDI Manager calls go anyway through the same SoundDispatch trap like a number of Sound Manager calls, so tapping to that interface is really easy. (Another question, though, is how well timing will work, and whether default MIDI synthesizer (or the SC-55 midi hardware) will handle Space Quest’s MIDI output that expects an MT-32…)

Various other updates

As mentioned before, there have been a ton of fixes and updates, but here is mention of a couple ones that might be of interest:

Popup Control CDEF (and TextEdit) fixes: There were a number of bugs in both the Popup Control drawing (and TextEdit setup) code, which manifested quite visually in the HyperCard script editor. Below are screenshots of “before” and “after” to show what kind of effects the fixes had:

Menu Bar Pattern Control Panel: As another curiosity, we tried this one old Control Panel from early 90s, to see what would happen – and seems that whatever magic it uses to draw patterns behind menu bar, it seems to be 100% compatible:

Menu Bar Pattern Control Panel

FracSin/FracCos: The After Dark module called “Spotlight” (not to be confused with the OS X search tool) was the first case that needed FracSin/FracCos implementation to work, so we used it as a test case for those traps and got it working pretty well:

After Dark “Spotlight”

Palette fixes: There were a number of bugs & missing features in Palette Manager code (for example, SetEntries had bug that made it fail incorrectly with cProtectErr, which caused a number of issues around the place). Here is Lode Runner: The Legend Returns editor, which had weird color issues before the fix (ignore the palette debugger in bottom right):

Lode Runner: The Legend Returns level editor

BitmapToRegion: This trap was already before used by Escape Velocity, but as that game needs a couple other improvements to reach playable state, Snood worked out pretty well as a use case for this (as it uses it for practically all of its sprites to convert their masks to regions for drawing). After a couple hours, the game seems to be quite happy with the routine (Snood 1.x pictured):

Snood using sprites with masks defined by BitmapToRegion

Default MDEF ‘cicn’ support: While trying out Snood, we noticed that Snood 2 was the first use case of color icons (‘cicn’s) in menu items. As the MDEF already had almost-working handling for this case, we added some temporary code to the Icon Utilities module and got nice color icons in menus now:

Color icons in Snood 2.x Players menu

More blitter fixes/improvements: There were numerous fixes to basic blitters too, which affected test cases such as 3 in Three, “Spotlight” (when brightness was other than 0%), Shanghai II mahjong, etc). Here’s some screenshots of what we got working with the improvements:

Next step

We will continue working on the missing features as always, trying to reach the goal of a generic runtime release as soon as possible. We also will try to find solution for the binary file distribution in near future, so anybody interested trying the new features out could do that as soon as possible (especially considering the last released binaries are already getting quite old). We will keep you updated on this blog on our progress as always.

Full list of changes since last post

2022-07-31 00:45:08 +0300 • Implement colorizing srcOr rectangle blitter
2022-07-30 23:49:00 +0300 • Implement colorizing srcBic rectangle blitter
2022-07-30 13:34:42 +0300 • Fix missing handle derefence bug
2022-07-30 13:47:58 +0300 • Implement SaveEntries trap for Palette Manager
2022-07-30 04:09:17 +0300 • Disable potentially invalid check in Entry2Index
2022-07-30 03:08:06 +0300 • Stretching subPin blitter + improve call interface
2022-07-30 03:07:01 +0300 • Reinforce zone checks for handle operations
2022-07-30 01:27:53 +0300 • Fix AppendMenu/InsertMenuitem legnth > 127 cases
2022-07-30 01:14:39 +0300 • Implement a rudimentary PlotCIconHandle (for MDEF)
2022-07-30 00:39:04 +0300 • Merge branch 'master' of
2022-07-30 00:38:58 +0300 • Proper implementation for BitmapToRegion QD trap
2022-07-26 23:16:20 +0300 • Add dummy MIDIManager (+ MIDISignIn & MIDIAddPort)
2022-07-26 20:35:26 +0300 • Merge branch 'master' of
2022-07-26 20:35:16 +0300 • Implement PaletteDispatch ResizePalette selector
2022-07-26 18:28:13 +0300 • Fix timer thread race condition issue
2022-07-26 15:53:28 +0300 • Implement color QD opDefHilite PICT opcode
2022-07-26 15:52:42 +0300 • Implement opPnLocHFrac PICT opcode
2022-07-26 15:52:06 +0300 • Fix edge case of shielding cursor in classic mode
2022-07-26 14:51:53 +0300 • Fix GetNew(C)Window autopositioning code
2022-07-26 14:07:53 +0300 • Fix TESetStyleScrap (StyleDataPtr -> TextStylePtr)
2022-07-26 05:35:47 +0300 • Version 9 compressed resource support (+fixes)
2022-07-26 03:05:37 +0300 • Add dummy ReplaceText selector stub for ScriptUtil
2022-07-26 00:46:57 +0300 • Add TESetStyleScrap (needs still some work)
2022-07-25 03:33:36 +0300 • Update line start for redraw when setting heights
2022-07-24 14:12:29 +0300 • Implement styled TESetSelect
2022-07-24 14:11:48 +0300 • Partial implementation of styled TEInsert
2022-07-24 06:08:06 +0300 • Merge branch 'master' of
2022-07-24 06:05:17 +0300 • Work on styled text (TEContinuousStyle selector)
2022-07-24 06:03:22 +0300 • Implement AdMin blend mode in color region blitter
2022-07-23 22:33:53 +0300 • Call vector #4 for unimplemented instructions
2022-07-23 02:07:22 +0300 • AppleDoubler: cleanup tool console output logging
2022-07-23 01:40:40 +0300 • AppleDoubler: add timestamps,buildscript & cleanup
2022-07-21 16:26:26 +0300 • Fix incorrect cProtectErr check in SetEntries
2022-07-21 15:32:55 +0300 • Implement FracSin and FracCos traps
2022-07-19 15:40:00 +0300 • Only mark arc dirty, if drawn on the screen port
2022-07-19 15:02:32 +0300 • Fix some compiler warnings (missing QD includes)
2022-07-19 15:00:12 +0300 • Use bullet (0xA5) as mark in popupUseWFont CDEF 63
2022-07-19 14:58:54 +0300 • Fix one-off error in MBDF hittest (crashed popups)
2022-07-19 06:45:32 +0300 • Fix saving of port state in TextEdit calls
2022-07-19 06:44:33 +0300 • Fix warnings in cursor module
2022-07-19 06:13:22 +0300 • Merge branch 'master' of
2022-07-19 06:12:48 +0300 • Add color QD hilite & fix font state in CDEF 63
2022-07-18 21:14:00 +0300 • Merge branch 'master' of
2022-07-18 21:13:52 +0300 • Cleanup: Refactor cursor code out of Mouse module
2022-07-18 04:12:22 +0300 • Support also function key (F1-F15) key codes
2022-07-17 07:38:02 +0300 • Fix incorrect ShieldCursor offsetPt in CopyBits
2022-07-17 07:27:27 +0300 • Implement DefaultSetCCursor (for 'crsr' support)
2022-07-17 07:26:49 +0300 • Fix MCallSetCCursor (called wrong vector)
2022-07-17 07:26:03 +0300 • Fix handle resizing bug in GetCCursor
2022-07-17 06:15:09 +0300 • Fix cursor left-side clipping
2022-07-17 02:36:52 +0300 • Color QD monochrome software cursor implemented
2022-07-11 23:12:03 +0300 • Use DoVBLTask do update cursor in color QD mode
2022-07-11 23:09:54 +0300 • Implement AddIconToSuite selector in IconDispatch
2022-07-11 21:56:20 +0300 • Implement NewIconSuite selector for IconDispatch
2022-07-11 19:40:19 +0300 • Implement AttackVBL trap
2022-07-11 14:27:11 +0300 • More color vs b&w QD cursor code specialization
2022-07-11 02:43:18 +0300 • Cleanup Cursor module code
2022-07-11 02:42:49 +0300 • Specialize Color QD case in ShieldCursor
2022-07-11 02:35:42 +0300 • Init cursor at startup
2022-07-10 14:29:23 +0300 • Redraw software cursor in SetCursor, if changed
2022-07-10 13:13:16 +0300 • Fix clamping of mouse in DefaultCrsrTask
2022-07-10 04:07:45 +0300 • Merge branch 'master' of
2022-07-10 04:07:02 +0300 • Implement software cursor for "classic" QD mode
2022-07-10 04:05:22 +0300 • Fix DefaultShieldCursor (it did not erase cursor)
2022-07-10 03:58:34 +0300 • Fix CrsrObscure handling in the DefaultCrsrTask
2022-07-10 03:57:44 +0300 • Only setup AllocCursor and SetCCursor in color QD
2022-07-10 03:56:18 +0300 • Increase screen buffer refresh rate temporarily
2022-07-10 03:55:34 +0300 • Fix mouse native window clamping (-1 from bounds)
2022-07-08 02:35:07 +0300 • Merge branch 'master' of
2022-07-08 02:35:00 +0300 • Vectorize SetCCursor (& fix some setup bugs)
2022-07-08 02:17:30 +0300 • Merge branch 'master' of
2022-07-07 20:25:22 +0300 • Fix ShieldCursor bugs
2022-07-05 23:44:59 +0300 • Fix Serial.h
2022-07-05 02:56:01 +0300 • Merge branch 'master' of
2022-07-05 02:55:56 +0300 • AppleDoubler: Fix OSX's weird swap of ':' and '/'
2022-07-04 16:50:27 +0300 • Fix LoadSeg 32K+ offset wraparound (use unsigned)
2022-07-04 16:29:48 +0300 • Merge branch 'master' of
2022-07-04 16:29:41 +0300 • Add dummy serial driver stub (AIn/AOut/Bin/BOut)
2022-07-04 15:04:51 +0300 • Fix UPP call signature of JShieldCursor
2022-07-04 04:28:09 +0300 • Merge branch 'master' of
2022-07-04 04:27:59 +0300 • AppleDoubler: Also encode folder names
2022-07-04 02:16:46 +0300 • Fix byteswap bug in font size check
2022-07-04 02:00:14 +0300 • Fix FOND style lookup: start at 1st match,not last
2022-07-04 01:56:59 +0300 • Add Oregon Trail (1.x) to test app configs
2022-07-03 14:05:54 +0300 • Implement QDDone selector for QDExtensions
2022-07-03 13:56:22 +0300 • Merge branch 'master' of
2022-07-03 13:56:16 +0300 • Add (no-op) LockRange & UnlockRange in FSDispatch
2022-07-03 04:29:30 +0300 • Add first version of AppleDoubler converter tool
2022-07-02 06:13:32 +0300 • Handle NFSGetDirInfo errors in NFSCreateFileHook
2022-07-02 06:12:36 +0300 • Implement DateToSeconds
2022-07-02 04:06:13 +0300 • Add SoftWindows test app to JSON configs
2022-07-02 04:05:42 +0300 • Implement GetGWorldDevice selector in QDExtensions
2022-06-18 02:05:16 +0300 • Add ZPC to test app config JSONs
2022-04-28 04:01:02 +0300 • Fix crash in TECallCharByte utility routine
2022-04-28 04:00:57 +0300 • Add missing header file from previous commit
2022-04-28 03:57:54 +0300 • Tweak naming of some private TE data structures
2022-04-28 01:18:54 +0300 • Fix GetCTable crash of locked 'clut' in 24bit mode
2022-04-23 22:04:03 +0300 • Implement styled TESetStyle
2022-04-23 21:42:07 +0300 • Work a bit on InitScripts (load smRoman 'itlb' 0)
2022-04-23 13:55:03 +0300 • Add Font2Script & implement FontScript+IntlScript
2022-04-18 11:28:33 +0300 • Temporary fail-safe in _Enqueue
2022-04-18 02:06:31 +0300 • Finish faster non-MeasureText path in NPixel2Char
2022-04-17 22:52:23 +0300 • Use NPixel2Char in TextEdit (FindLine etc)
2022-04-17 22:50:50 +0300 • First version of working NPixel2Char in Script Mgr
2022-04-16 21:08:10 +0300 • Implement SndControl (classic SM2)
2022-04-15 05:03:02 +0300 • Prep TEHitTestHook calls to work with NPixel2Char
2022-04-15 04:59:57 +0300 • Handle 0x2C (font) and 0x2E (glyph state) in PICTs
2022-04-13 16:20:10 +0300 • Fix Munger ptr2=nil & len2=0 case (search)
2022-04-13 02:41:36 +0300 • Allow bypass of ampCmd and timbreCmd in snth 4101

Happy new year! First M1 benchmarks, and other fixes

First tests on Apple Silicon

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

Here’s breakdown of the scores:

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

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

Color support for scrollbar controls

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

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

Boolean bitmap color blending fixed

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

Master of Orion with text blending issue fixed

Trying out a couple more new games

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

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

68k TRAP instructions and THINK Pascal LightsBug

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

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

Other stuff

Here’s a couple other things that were fixed:

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

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

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

Full list of changes since last post

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

Standard File Package

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!

Features

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.
  • Most of SF items/hooks implemented:
    • Items: sfItemOpenButton, sfItemCancelButton, sfItemVolumeUser, sfItemEjectButton, sfItemDesktopButton, sfItemFileListUser, sfItemPopUpMenuUser, sfItemDividerLinePict, sfItemFileNameTextEdit, sfItemPromptStaticText, sfItemNewFolderUser,
    • Hooks: sfHookFirstCall, sfHookCharOffset, sfHookNullEvent, sfHookRebuildList, sfHookFolderPopUp, sfHookOpenFolder, sfHookLastCall, sfHookGoToDesktop
    • Not yet implemented: sfHookOpenAlias, sfHookGoToAliasTarget, sfHookGoToNextDrive, sfHookGoToPrevDrive, sfHookChangeSelection, sfHookSetActiveOffset
  • File type filtering supported, both by typeList and FileFilterProc
A GIF animation showing the progress done in the past month, from scratch to the latest version

Known issues

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:

“Before” and “After” debug visualizations of the NativeFS binary tree data structure (click for larger view)

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:

  • Bitfield instructions (bfins, bfset, bftst, bfchg, bfclr, bfextu, bfffo)
  • cas2.b/w/l instruction
  • divs.l/divu.l 32-bit division instructions
  • move16 instruction for 68040
  • Disassembler support for the new and improved instructions
  • Various other improvements

Full list of changes since last post

2019-10-21 02:25:22 +0300 • GetResource falls back to TopMap if CurMap invalid
2019-10-20 23:00:18 +0300 • Fix byteswap bug in LDEF -4000 (item font & size) 
2019-10-19 21:44:23 +0300 • Update ArmorAlley JSON config, it now almost works
2019-10-19 02:18:39 +0300 • Fix _Allocate, use ioFRefNum/FCB to get the vcbPtr
2019-10-19 02:06:57 +0300 • Make MemoryManager allocation alignment adjustable
2019-10-19 01:54:24 +0300 • Fix AddResource bug, ResErr not cleared on success
2019-10-19 01:44:31 +0300 • Implemented RmveResource                          
2019-10-18 17:44:45 +0300 • Set ioFDirIndex for GetCatInfo in SF popup refresh
2019-10-18 17:21:28 +0300 • Desktop folder support improved in SFUpdateReply  
2019-10-18 17:08:07 +0300 • Show files in Desktop Folders on desktop          
2019-10-18 16:25:39 +0300 • Update StdFile Eject button enable/disable state  
2019-10-18 03:39:11 +0300 • Close app resource file on exit from emulator     
2019-10-18 03:07:05 +0300 • Draw CDEF 63 popup triangle & hack to resize menu 
2019-10-17 00:07:14 +0300 • Fix StdFile dirID byteswap bug for popup menu item
2019-10-17 00:05:13 +0300 • Rough proto of autoTrack to CDEF 63 popup tracking
2019-10-16 23:28:35 +0300 • Add sfHookFolderPopUp trigger & handler to StdFile
2019-10-16 23:27:14 +0300 • Implement testCntl in CDEF 63 (& refactor headers)
2019-10-16 22:47:54 +0300 • Merge branch 'master' of  
2019-10-16 22:47:13 +0300 • Fix popup menu creation (fix title & set icon cmd)
2019-10-16 22:45:09 +0300 • Work on CDEF 63 (draw menu in the control)        
2019-10-16 22:44:10 +0300 • Implement mDrawItemMsg in MDEF 0                  
2019-10-16 22:40:13 +0300 • fix initializing 68040 processor type and linkin..
2019-10-16 04:50:31 +0300 • Implement mCalcItemMsg in MDEF 0                  
2019-10-16 03:59:46 +0300 • Implement calculation of popup bounds in CDEF 63  
2019-10-16 03:58:56 +0300 • Make Mac_GetMenu visible in public headers        
2019-10-16 03:58:31 +0300 • Fix bugs in StdFile path popup folder iteration   
2019-10-15 02:25:13 +0300 • Work on CDEF 63 init, dispose and calc messages   
2019-10-14 21:40:29 +0300 • disassembler fixes and support for bit field ins..
2019-10-14 02:50:31 +0300 • Work on CDEF 63: Init StdFile dir popup contents  
2019-10-13 07:21:56 +0300 • Fix filename in GetFileInfo for ioFDirIndex > 0   
2019-10-12 23:57:53 +0300 • Fix old-style StdFile filelist bounds byteswap bug
2019-10-12 23:56:36 +0300 • Fix ioFDirIndex>0 case for GetFileInfo in NativeFS
2019-10-12 04:29:25 +0300 • "New folder" dialog added, and many fixes & tweaks
2019-10-12 02:09:45 +0300 • Cmd+Down in SF & fix list arrow when no selection 
2019-10-11 22:40:18 +0300 • Handle Cmd+S, Cmd+O, cmd+D and cmd+N in StdFile   
2019-10-11 22:21:15 +0300 • Fix crash in CDEF 61 dispCntl message handler     
2019-10-11 05:12:59 +0300 • Enable "new folder" button in StdFile put dialogs 
2019-10-11 05:11:37 +0300 • Implemented CDEF 61 ('PICT' button control for SF)
2019-10-11 02:44:50 +0300 • Don't try to go to the parent of Desktop          
2019-10-11 02:39:49 +0300 • Open parent with cmd+up, desktop with cmd+shift+up
2019-10-11 01:49:34 +0300 • Implement cut/copy/paste handling in DialogSelect 
2019-10-11 00:08:41 +0300 • Fix inverted zonecheck result in handle validation
2019-10-11 00:06:45 +0300 • Finish IsCmdChar implementation (& fix signature) 
2019-10-11 00:05:16 +0300 • Fix KCHR load from ROM (RomMapInsert & TmpResLoad)
2019-10-10 22:27:30 +0300 • Cache KCHR 0 in script manager expand mem globals 
2019-10-10 10:32:50 +0300 • Handle escape key in StdFilter                    
2019-10-10 10:32:26 +0300 • Add dummy IsCmdChar to ScriptUtil dispatcher      
2019-10-10 02:43:08 +0300 • Handle iBeam cursor in StdFilter null/updateEvents
2019-10-10 02:25:40 +0300 • Frame default button in StdFilter (also disabled) 
2019-10-10 01:53:25 +0300 • Handle desktop folder and related buttons         
2019-10-09 22:58:06 +0300 • Use new defines for FindFolder folders in StdFile 
2019-10-09 22:57:33 +0300 • Call DirCreate in FindFolder when createFolder set
2019-10-09 22:56:44 +0300 • Add dummy DirCreate placeholder to FSDispatch     
2019-10-09 22:55:41 +0300 • Merge branch 'master' of  
2019-10-09 22:55:37 +0300 • Fix font strike size to inRec size scale ratio    
2019-10-09 22:20:59 +0300 • disassembler support for move16                   
2019-10-09 21:54:33 +0300 • remove unused sr_bits field from instruction data 
2019-10-09 21:33:53 +0300 • finish implementing move16 instruction            
2019-10-09 21:26:06 +0300 • update xcode 6 project                            
2019-10-09 17:23:48 +0300 • Fix FindFolder memory corrupt (ioNamePtr not set) 
2019-10-09 11:16:53 +0300 • Fix byteswap bug in fld# type comparison          
2019-10-09 11:15:00 +0300 • Fix fld# search to work on non-system folder lists
2019-10-09 03:46:40 +0300 • Add linecount script                              
2019-10-09 03:46:28 +0300 • Add empty desktop/trash folders to THINK Pascal   
2019-10-09 03:32:46 +0300 • AliasManager added, to implement FindFolder for SF
2019-10-09 02:42:02 +0300 • Implemented HOpenResFile                          
2019-10-08 00:43:44 +0300 • Implement sfHookCharOffset and sHookRebuildList   
2019-10-07 21:56:21 +0300 • Found hidden ListManager selector, used by StdFile
2019-10-07 21:55:09 +0300 • Add PageUp/Down and Home/End keys to SDL keymapper
2019-10-07 04:57:10 +0300 • Use inThumb also to draw control on SetCtlMin/Max 
2019-10-07 04:55:48 +0300 • Fix wrong zero-case part code bug in HiliteControl
2019-10-07 03:16:46 +0300 • Fix ignore dot & '%'-prefix items in InsertResMenu
2019-10-07 02:19:28 +0300 • Fix memory leak in DrawPicture                    
2019-10-07 02:18:10 +0300 • Fix conversion of uncompressed pixmap data to b&w 
2019-10-06 23:37:38 +0300 • fix divs.l, start implementing move16 instruction 
2019-10-06 00:00:12 +0300 • allocate move16 instruction                       
2019-10-05 23:07:36 +0300 • fixes for divs.l/divu.l instruction               
2019-10-05 22:00:21 +0300 • Merge branch 'master' of  
2019-10-05 21:59:44 +0300 • implement chk2.b/w/l instructions                 
2019-10-05 21:57:57 +0300 • Merge branch 'master' of  
2019-10-05 21:57:22 +0300 • Fix resource name remove bug                      
2019-10-05 21:27:28 +0300 • implement cas2.w and cas2.l instructions          
2019-10-05 20:34:46 +0300 • finish cas.b/w/l instruction implementation       
2019-10-05 04:50:14 +0300 • Fix bug in FindWindow (theWindow not initialized) 
2019-10-05 04:10:11 +0300 • Merge branch 'master' of  
2019-10-05 00:11:35 +0300 • make bsr instruction branchless                   
2019-10-04 23:43:40 +0300 • THINK Pascal def missing from root CMakeLists.txt 
2019-10-04 23:25:35 +0300 • register variants for bfins, bfset and bftst      
2019-10-04 23:05:14 +0300 • remove unused c16 param from bfxxx_read/write     
2019-10-04 22:42:22 +0300 • use read_pc_immediate for bit field extension     
2019-10-04 22:30:25 +0300 • fixes for bit field instructions                  
2019-10-04 01:06:20 +0300 • Add THINK Pascal 4.0 test app JSON config to CMake
2019-10-04 01:06:00 +0300 • Implemented MaxSizeRsrc                           
2019-10-03 22:25:37 +0300 • Reinforce fake handle handling in memory manager  
2019-10-03 22:21:15 +0300 • bfchg, bfclr, bfext, bfextu and bfffo instructio..
2019-10-03 22:09:06 +0300 • Revert "bfchg, bfclr, bfext, bfextu and bfffo in..
2019-10-03 22:08:15 +0300 • bfchg, bfclr, bfext, bfextu and bfffo instructio..
2019-10-03 04:04:45 +0300 • Escape MacRoman filenames & avoid UTF8 conversions
2019-10-03 00:27:19 +0300 • SF key filtering (max length, skip ':' & CR, etc.)
2019-10-03 00:26:24 +0300 • Support "autoKey" in keyboard and platform modules
2019-10-02 02:55:34 +0300 • Handle tab key in SFDialogFilter                  
2019-10-02 02:14:00 +0300 • Tweak list ListManagerClickTrackProc visible size 
2019-10-02 02:00:26 +0300 • Fix missing sfHookLastCall set on SF dialog close 
2019-10-02 01:58:50 +0300 • Escape characters in NFS (and fix full-path bug)  
2019-10-02 00:08:29 +0300 • Adjust Art Class JSON to use 68020 machine config 
2019-10-02 00:07:57 +0300 • Update SF reply records during event loop         
2019-10-02 00:07:24 +0300 • Handle invalid names and replace in "save" dialogs
2019-10-02 00:05:56 +0300 • Reduce keyboard debug logging                     
2019-10-01 22:34:26 +0300 • Fix missing origName in SFPutFile                 
2019-10-01 22:06:24 +0300 • Merge branch 'master' of  
2019-10-01 22:06:17 +0300 • Tweak Gestalt and fix M68kHelper for 68020 support
2019-10-01 21:35:17 +0300 • kemu header cleanup                               
2019-10-01 21:33:14 +0300 • update xcode6 project                             
2019-10-01 20:38:00 +0300 • 020 bit field instructions, optimizations, some ..
2019-10-01 17:01:23 +0300 • First successful "open" from Standard File        
2019-10-01 15:37:53 +0300 • Missing header update for no-read privilege flag  
2019-10-01 15:37:03 +0300 • Add missing part of previous LayerDispatch fix    
2019-10-01 15:36:20 +0300 • Handle cancel button & implement closing dialogs  
2019-10-01 15:20:57 +0300 • Handle opening of folder in file list             
2019-10-01 15:20:00 +0300 • Don't hilite disabled items in file list lDrawMsg 
2019-10-01 14:58:06 +0300 • Error dialog support for Standard File            
2019-10-01 14:57:19 +0300 • Add some more TODOs to StdFilter proc             
2019-10-01 14:56:52 +0300 • Fix bug in AutoPositionWindow lcParentWindow case 
2019-10-01 13:42:47 +0300 • Fix redraw bug in file list item selection        
2019-10-01 13:40:58 +0300 • Detect when a folder is opened instead of file    
2019-10-01 13:39:08 +0300 • Fix accidental file list framing in "Get" dialogs 
2019-10-01 03:24:36 +0300 • Update save/open button state (and title)         
2019-10-01 01:21:11 +0300 • Add Desktop Folder and Trash to TeachText config  
2019-10-01 01:20:45 +0300 • Add empty folder creation support to make.cmake   
2019-10-01 01:06:51 +0300 • Go to parent folder by clicking volume name       
2019-09-30 02:06:23 +0300 • Handle more events in SF(update, activate & mouse)
2019-09-30 02:02:42 +0300 • Fix byteswap bug in FindDialogItem                
2019-09-29 03:39:31 +0300 • SF activation handling: set reply & frame filelist
2019-09-29 03:35:48 +0300 • Fix more maxIndex bugs in LGetSelect and LSearch  
2019-09-28 03:54:21 +0300 • Add file type filtering & call custom file filters
2019-09-28 03:53:38 +0300 • Fix bug in Standard File dialog autopositioning   
2019-09-28 03:28:31 +0300 • Fix SF special folder detection bytes-wap bug     
2019-09-28 03:27:37 +0300 • Fix ioDrDirID for folders in GetCatInfo           
2019-09-28 03:08:52 +0300 • Handle list clicking in SF dialog event handler   
2019-09-28 03:08:12 +0300 • Fix maxIndex case in LClick selection clearing    
2019-09-28 03:07:09 +0300 • Set mouseLoc in ListRec in LClick                 
2019-09-28 03:05:32 +0300 • Fix ioDirFlg setup in GetCatInfo                  
2019-09-28 01:59:31 +0300 • Re-enable EraseRect calls in SF dialog item redraw
2019-09-28 01:57:24 +0300 • Fix ioNamePtr handling in GetCatInfo              
2019-09-28 01:56:01 +0300 • Draw volume icon & name in Standard File dialogs  
2019-09-27 15:40:16 +0300 • Finalize LDEF -4000 drawing for standard file list
2019-09-27 15:38:52 +0300 • Fix file type mapping bugs in standard file pack  
2019-09-27 15:37:44 +0300 • Add Scratch20 low memory global                   
2019-09-27 04:21:58 +0300 • First real filelist shown in Standard File Dialogs
2019-09-26 22:56:17 +0300 • Add balancing algorithm to the AVL tree (+debug)  
2019-09-26 22:54:32 +0300 • Add missing header from previous commit           
2019-09-26 22:53:19 +0300 • Finish volume/directory setup in SF initialization
2019-09-26 11:30:42 +0300 • Reset to VCBQHdr after last VCB in SF volume scan 
2019-09-26 04:06:05 +0300 • Work on volume state initialization in SF package 
2019-09-26 04:03:16 +0300 • Tweak FMGetDrive to allow passing nil driverRefNum
2019-09-26 04:02:01 +0300 • Support GetVolInfo calls with drvNum as vRefNum   
2019-09-26 04:01:13 +0300 • Add four flag bytes in front of DrvQEl in NativeFS
2019-09-25 04:33:14 +0300 • Set default SF volume&folder to application folder
2019-09-25 04:11:00 +0300 • Add indexing to GetCatInfo + fetch real ioDrNmFls 
2019-09-25 04:09:38 +0300 • Add rough iteration support to file system AVLTree
2019-09-22 13:09:58 +0300 • Refresh file list in StdFile dialogs              
2019-09-22 05:17:32 +0300 • First StdFile dialogs visible, not yet functional 
2019-09-22 05:15:58 +0300 • Support opcodes 0x12, 0x13 and 0x14 in pictures   
2019-09-22 04:41:36 +0300 • More progress on StdFilePack                      
2019-09-22 04:39:36 +0300 • Minor List Manager fixes and tweaks               
2019-09-22 04:37:15 +0300 • Placeholder for popup CDEF (63)                   
2019-09-19 23:06:31 +0300 • Finalize CheckWindow selector for LayerDispatch   
2019-09-19 03:25:17 +0300 • More work on Standard File Package                
2019-09-19 03:23:39 +0300 • Add two new selectors to LayerDispatch for StdFile
2019-09-18 03:58:15 +0300 • Some work on Standard File Package                
2019-09-18 03:54:32 +0300 • Use _RelString in IUMagIDString for now           
2019-09-13 01:48:34 +0300 • Mac OS X 10.6.8 compatibility                     
2019-09-11 21:30:30 +0300 • Enable GetNextEvent CPU throttle for Arkanoid     
2019-09-11 18:25:41 +0300 • Add Crystal Quest and Armor Alley test apps       
2019-09-09 01:31:04 +0300 • Bump up runtime version for new bundles           
2019-09-09 00:58:48 +0300 • Tweak IAGO cmake config                           
2019-09-07 14:04:32 +0300 • Add two more test app configs, IAGO and EveryMan 1
2019-09-07 14:04:02 +0300 • Add substitution for missing fonts in Font Manager