Category Archives: HyperCard

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

TextEdit update: first styled text features added

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

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

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

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

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

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

HyperCard 2.0 Home stack with multistyled text

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

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

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

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

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

Full list of changes since last post

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