Category Archives: Toolbox

Second mid-summer update: Post-roadtrip, TextEdit progress, Clipboard…

Okay, so both members of development team have been busy being on vacation trips for the past few weeks, but we’re again back (although still on “kind of” summer break). To celebrate this we decided to each post a picture of what we’ve been up to, but to make this appropriate to topic of this blog, we do this by showing the photos using M.A.C.E running Photoshop 🙂

Road trip vacations

First, Pukka went on a road trip to Eastern Finland with his good old trusty Volvo station wagon for one week:

Pukka went on a road trip to Eastern Finland with his good old trusty Volvo station wagon for one week

Toni went on a two-week road trip to Northern Germany, visiting 12 cities in 14 days, including taking this amazing train from Hamburg to Kiel:

Toni went on a two-week road trip to Northern Germany, visiting 12 cities in 14 days, including taking this amazing train from Hamburg to Kiel

TextEdit progress (and Scrap Manager)

During this two weeks of visiting a lot of places, Toni had a couple evenings time to do some work on (non-styled) Text Edit, which now is nearly complete, and is able to run TeachText with almost all text editing features working:

TeachText works now on M.A.C.E.!

These are the notable features which work now in TextEdit:

  • Multi-line text display, with scrolling support (viewRect/destRect offsetting)
  • TEKey text input (still a bit hacky but functional)
  • TEClick with autoscrolling support, double-click word selection (using TEFindWord), and fExtend support for “shift-key”-type extending of selection, and recognition of left/right side of character for proper caret positioning
  • TextEdit hook support for nearly all TE Hooks (TEDoText, TERecalc, TEWordBreak, ClikLoop, TEFindWord, TEFindLine, TETrimMeasure, EOLHook, HighHook, etc…) which can be customized by 68K apps
  • Caret support with TEIdle blinking, TEKey cursor key movement (including multi-line support), and multi-line selection range support
  • Nearly all “quirks” of regular System 7.x TextEdit implemented as they work on real Mac; including the weird way caret gets positioned when moving across line boundaries using left/right arrow keys if previously clicked on right-hand side of a character, etc…
  • Dialog Manager edit field support, with System 7-type multi-line text support (i.e. edit fields with one line get extended horizontally 2x size, and scroll both horizontally and vertically, while multi-line edit fields only scroll vertically), “tabbing” between edit fields, and complete TEKey/TEClick support
  • Maybe some others I’ve forgotten to mention

Additionally, as TeachText wanted to use also Scrap Manager for edit functions, in parallel to implementing TECut/TECopy which use private TextEdit scrap, the implementation of generic Scrap Manager was finalized so that Clipboard file is fully supported (previously only in-memory state of scrap was implemented).

However, TEPaste still needs to be added for a 100% completion of “Edit” menu features for TeachText – and also, styled TextEdit work has not yet been started, which will be required in future to support more complex apps such as SimpleText and HyperCard 2.x.

Next up, on Toolbox API side, work is being done on Resource Manager’s resource fork write support, mostly just because after Scrap Manager was implemented, SuperPaint was able to progress a bit further in it’s startup, but wants to create “SuperPaint Prefs” file using Resource Manager’s functions, so might as well add that next. As of writing this, there’s already support for AddResource, ChangedResource and WriteResource, but we need to add resource fork compacting support to UpdateResFile to actually write the file properly. But we’ll get back to that later.

Bonus pic – for fun 🙂

Meanwhile, here’s a funny pic of what it looks when we run 28 M.A.C.E. instances at once 🙂 All quite responsive even though they’re all in full debug mode, although same can’t be said about the old Mac Pro when it was running them… 😀

28 individual M.A.C.E. applications (in debug mode) running at once 🙂

Mid-summer update: TextEdit progress

We’re still on summer “break”, but there has been a few evenings time to work on some TODO items, lately especially on the TextEdit implementation. It’s still far from complete (the basic, single-style TextEdit – Styled TextEdit is another undertaking on its own!), but there has been some progress that has already some visible effects.

For example, one of the games we’ve been testing emulation with, Scarab of RA, relies EXTREMELY lot on TextEdit, including quest log, inventory (which includes selecting items with text selection highlight included), help/hint, about, and score dialogs. Some of these work in very interesting ways, for example quest log and inventory assemble text by concatenating text from individual segments – for example, “16 ounces of food” line in inventory is assembled one by one from strings “16”, ” “, “ounce”, “s”, ” of food”, and carriage return. The game also appears to use the internal line start offsets to intercept clicks in inventory, highlighting individual lines using text selection by itself.

The game is already approaching playable state, but there are still a few issues – most notably, recalibration of line start offsets does not update last line offsets correctly when removing, causing removed lines to sometimes leave “trashed” text at end of text edit boxes. Here’s some screenshots of how it looks like now:

Scarab of RA gameplay screen, with inventory selection highlighted
Multi-line text highlighting of recent message in quest log

Additionally, a few other games (Lemmings, Simcity) can now proceed past copy protection screens, as we can finally use the VERY hacky TEKey implementation to enter correct answers to the protection questions (SimCity also required a bunch of new selectors to be added to the FP68K SANE dispatcher):

Lemmings can now proceed to gameplay, which appears to work perfectly, including sound & music output using Sound Driver
SimCity (black & white version) can also proceed to game, although sound does not yet work as it still has the weirdly mixed up sound completion routine method signature which crashes the device manager if sound is not disabled

EDIT: Here’s a video of first 15 minutes of Mac Lemmings gameplay:

Lemmings running on M.A.C.E.

There is also some effect on productivity apps:

Text object can now be created in MacDraw
Hypercard at userlevel 5

As the “message” window in HyperCard 1.x is now able to accept commands, we can use “set userlevel to 5” command to actually modify the included stacks! Still a lot of things broken there, but yet a lot new functionality unlocked… We haven’t though had time to play with them, but it should soon be much more usable!

EDIT: After minor tweaking with SDL TextInput API, MacPascal can also now accept text input, compile and run Pascal code:

Some test code entered, compiled and run in MacPascal

In general, TextEdit still has a lot of important features unfinished or to be implemented:

  • No caret display yet (teCaret in TEDoText)
  • TEClick not yet implemented, thus using mouse for selecting text does not work yet
  • TEKey is VERY hacky, needs for example arrow key control, backspace support, etc
  • Dialog Manager keyboard input does not yet handle default items/clipboard commands etc
  • The keyboard driver is still passing key events through scancodes without real mapping to actual MacRoman characters, preventing modifiers/host operating system keyboard layout from having effect
  • Line start recalibration has still sometimes issue when removing lines from middle of text
  • Selections have still some visual glitches, especially when typing text in dialogs
  • Styled TextEdit support still completely missing…for now
  • Probably other things too which I can’t remember…

And now back to the summer break…

Experimenting with INIT/cdev support

This previous weekend, while helping Pukka to fix a mysterious coordinate calculation bug in Fool’s Errand intro, I decided to experiment with one weird idea: How about adding support for System Extensions and Control Panels? Therefore, yesterday I added the After Dark ‘cdev’ control panel to MacPaint app’s build settings to be included in the System Folder, and took some time to look what it would take to make it work.

Basically, INITs and cdevs are loaded during the startup by Mac OS by checking a few bits (such as file type, visibility, etc), opening the resource map of each file, and executing the first ‘INIT’ code resource found. At this experimental stage, we don’t yet have full INIT/cdev scanning, but instead have just a hard-coded filename to load INIT code from which works ok enough for this test case.

Our boot-time heap wasn’t quite properly set up yet, as the boot stack was too high, not leaving enough space between MemTop and BufPtr, which on the first attempt of running the INIT caused After Dark’s InitZone call to actually end up at top of the stack, causing all sorts of havoc. Besides that, there were a ton of bugs/improvements:

  • 68k-to-68k trap calls did not work correctly (i.e. calling a trap patched with 68k from 68k code)
  • InitZone parameter block handling was completely broken from the last year’s trap refactor, so it was fixed
  • Memory Manager’s Handle validation had not taken into account the case where handle’s “relative handle” field would point to invalid memory location in some “fake” handles (as one in After Dark), for which validation was added
  • Empty stubs were added for Notification Manager calls to allow After Dark to call them during activation/deactivation of screen saver
  • Locking of 68k mutex was not done early enough, so After Dark’s VBL handler was making the initial call Launch trap to have invalid register values
  • After Dark uses grafProcs to call QuickDraw, so one missing case used by it was added (ovalProc for ovals)

After that bunch of minor tweaks, we have now at least After Dark working nicely!

After Dark icon displayed during loading of MacPaint

Although the INIT code itself works, there is not yet any UI for displaying cdevs (Control Panels), so modules cannot be configured yet, and thus only the default “Starry Night” built-in module is displayed.

“Starry Night” (default module) running in After Dark inside MacPaint application bundle

There’s also a short video to demonstrate After Dark running:

Although not very usable feature at the moment, this will definitely allow interesting possibilities in the future, as theoretically we should be able to run applications requiring certain application-specific extensions to be present in the System Folder. This experimenting with After Dark has anyway allowed us to find a number of important bugs (as previously mentioned), and also works as a very good “compatibility” test to see how well our Toolbox API and 68k implementation can handle one very quirky control panel, as it patches a ton of toolbox traps and does a lot of low-level stuff which all appear to be compatible with our emulation.

HyperCard 1.0.1 works now (kind of)

As mentioned in the previous post about file system write support, one major motivation for experimenting with it this point was the interest about getting HyperCard to work on MACE. So, after we added it a few days ago, and after fixing a few bugs, we already got quite a few default stacks (included with HyperCard) to at least open up and display something! Below is a HyperCard screenshot extravaganza what we can do right now (click on pictures to see full size!!!):

As you can see, there’s a lot of stuff appearing correctly, but also a lot of things still broken and needing work. Cool stuff that works:

  • Most of cards open up and actually do sensible stuff
  • Most of drawing tools work (see the mess we made in the Home card!). I think they also share a lot of code with MacPaint tools, as some have same toolbox bugs present in both MacPaint and HyperCard

Stuff that needs a lot of work still:

  • Corrupted texts appearing here and there around places (such as between months in calendar & weird mess in some lists)
  • Bunch of error messages popping up here and there
  • Font setup dialog is not displaying font names correctly as using some still unimplemented selectors at least in List Manager
  • Cannot get back to Home stack, which apparently does not close correctly and cannot be reopened without restarting entire HyperCard application
  • HyperCalc stack does not appear to work well at all, all fields are empty and the “help” popup does not appear
  • File system writing needs improvements, especially to add the Standard File package so we wouldn’t anymore have to use the hard-coded filenames
  • TextEdit support is not yet complete, so most of text input does not yet work (with the exception of text drawing tool, which like MacPaint does not use TextEdit)
  • A bunch of other misc bugs here and there

Anyway the current status looks quite promising, and as eventually bugs will get hunted down & features added, the state of this application should improve over time.

File system write support (and MacPaint kind of works)

This week we reached a major milestone! From the encouragement on the work on HyperCard on 68KMLA forums, we got inspired to attempt tackling one major obstacle that was preventing it from working – file system write support!

As we mentioned earlier last year, when we last fall added the file system API, we did so using abstraction on top of AppleDouble file format. As Mac file system has the special dual nature of being split to data and resource forks, the AppleDouble format helps managing this in the emulated file system. Data fork, as mentioned earlier, is saved directly in its own file, while resource fork is merged with other file metadata in the AppleDouble header file. With this distinction, adding support for writing to data forks was really just trivial mapping of file manager write calls to the data file. Resource fork writing is a bit tricky, but we currently force the AppleDouble headers to keep resource fork as last element in the file, which allows us to offset also write operations from the beginning of resource data, and allows us to expand/shrink file easily, as end of resource fork is the actual end of header file. (One side note, setting EOF of files doesn’t have a standard C file operation, so we’re for now using the POSIX extension “ftruncate” which works at least on Mac OS X, but may lead to portability issues.)

Currently there’s very limited set of features for writing to file system implemented, basically just “Create” and “Write” file manager calls. For example, resource manipulation does not yet work as it will require a number of routines added to the Resource Manager to support it. However, one test application that directly benefited from this new feature was our beloved MacPaint, as it requires two scratch files to be present on startup volume/folder to function. This was nice, as it allowed us to add a few other missing features, such as PackBits (which also benefitted other apps and picture recording).

Hello from MacPaint!

Although all tools don’t yet work perfectly, most of basic drawing functions are solid enough to not only allow drawing, but the experimental file writing also allows saving of MacPaint files, which appear to be readable by the Preview application in development host system Mac OS X 10.12!

FatBits and some test pixels drawn (including ‘hello’ done with the MacPaint text tool)

Additionally, many other applications have seen improvements from this, as now we can save Civilization games and continue playing them! (Although Standard File package is still using hard-coded SFReply records).

Civilization stress test

There’s not much news for the past days, as half of the entire development team has been bedridden by a spring flu, which luckily is improving. However, during this period we did a stress test to hunt a nasty memory corruption bug found in Civilization:

Hunting bugs with Civilization

Eventually the memory heap corruption bug was reproduced, and thanks to extensive debug logging, the culprit was a double-release of color table handle in window manager auxiliary window list entry which was not implemented correctly. With additional checks in memory manager handle “handling”, we’re working on fixing this issue and hopefully will catch similar issues faster in the future with the added handle validation code.

Other notable improvements done in the past weeks include:

  • Near-completed scrollbar (CDEF 1) support
  • Bug fixes to Control Manager (which was using dereferenced handles after calling routines which move memory, causing random crashes)
  • List Manager bug fixes (alignment of items, scroll working, and scroll bar support, incorrect bit masking, etc.)
  • Fixed FCOSX interpreted accidentally as FLOGBX. They both had same selector, but different trap (FP68K vs Elems68K). This allows ZeroGravity to display force indicator correctly, and fixes Test Drive II: The Duel road rendering almost completely.
  • Other minor fixes & improvements (MapRgn trap implemented, OpenPicture pen hide bug, DeltaPoint byteswap bug, FindDialogItem trap implemented, ScrollRect was not calculating source address correctly in non-clipped downwards scrolling, etc.)
  • Somehow sound has started to work in Microsoft BASIC, so the “Music” sample app now plays music in BASIC without issues
  • Optimizations to the 68K emulator

Photoshop 1.0 (and MacApp support)

The past week we’ve been busy working on optimizations on the 68k CPU and various improvements to the toolbox API. One of the improvements has been adding support for Apple’s MacApp MethodDispatch routine, which is used by Object Pascal and C+- (yes, that’s “C plus minus”, Apple’s proprietary C++ version which was briefly out before official C++ came to Mac). Basically, MethodDispatch is the virtual function table dispatcher commonly seen in C++ programs, but instead of being bundled in the application, it is actually implemented by the operating system as a toolbox trap – although with special calling convention, which cannot be called directly through A-line traps, but needs to be invoked through jump from 68k code. It handles selecting the correct implementation for class functions which can be inherited and overridden.

With the new MacApp method dispatching support, we should now be able to try running any MacApp-based applications – one cool such application, which is written in Objective-Pascal, is the first version of Adobe Photoshop:

About box and intro screen of Adobe Photoshop 1.0

Most of the dialog boxes appear to display (almost) correctly, although color picker, text input and popup menu support are missing so there’s little that can be done here:

Color separation preferences dialog in Photoshop

And just to test out how it works, we did a quick “Hello world” drawing using Photoshop drawing tools inside MACE:

“Hello world” from MACE!

Although implementing the method dispatching routine was fairly trivial, some time was taken by other features used by Photoshop, such as crude International Utilities/Script Manager support, PrGlue dispatcher for printing (or as in current case, telling application that printers are not available), proper Gestalt support, and various bug fixes even to some fairly low-level things as handling of empty regions in UnionRgn calls, rewriting the 80-bit “Extended” floating-point format conversion in SANE, etc… A few other test applications did benefit of those additions, but we’ll post more about them later!

Ps. In case you are interested how MacApp-based application code looks like, the original Object Pascal source code for the first Mac Photoshop was at some time ago published as open-source and is available on github: https://github.com/amix/photoshop

StretchBits (and font scaling)

An important feature which was implemented a few days ago is the StretchBits trap. It was actually implemented for the first “Stunt Copter” prototype, but as it’s effects are visible in many places, I felt proper to write a separate blog entry for it just to demonstrate a few cases where it had big impact on the content:

Railroad Tycoon map & minimap AFTER adding StretchBits
Railroad Tycoon map & minimap BEFORE adding StretchBits

Before implementing StretchBits, calls to it were directed as a placeholder to StdBits, which would show the content partially depending on the context, but causing graphic glitches as can be seen. On the Railroad Tycoon map, the “Map” uses both double-size scaling to draw the map, and half-size scaling for the mini-map on the right hand side. Also, the “New Train” screen uses stretching to scale locomotive PICT resources to fit the List Manager list it uses:

Railroad Tycoon “New Train” screen AFTER adding StretchBits
Railroad Tycoon “New Train” screen BEFORE adding StretchBits

Also the text rendering benefits of this, as text can now be scaled to arbitrary sizes, which is quite important when drawing bitmapped fonts in non-exact resolutions, such as in Missile:

Missile AFTER adding StretchBits/font scaling

Missile BEFORE adding StretchBits/font scaling

The scaling algorithm has some room for improvement, as it for now only has the generic method for scaling bits one pixel at a time. For now, this seems to be enough to allow working on other missing features.

Desk accessory support

Tonight I was feeling whimsical, so I decided to quickly add something fun to the emulator: Desk accessory support.

We already had full support for device drivers (DRVR resources) needed for the “.Sound” and “.NativeFS” virtual file system drivers, and as everybody knows, pre-System 7 type desk accessories are basically just drivers with some bells and whistles added to make them fit in the Mac’s toolbox & event system.

This required adding of a few routines used for DAs (and drivers):

  • OpenDeskAcc
  • SystemClick
  • SystemEvent
  • SystemTask

(supporting menus also will require SystemMenu, but we’ll get to it later – this is enough to get Calculator DA to work).

Desk accessories in the Apple menu

This also required tweaking the test code in AppendResMenu to add the actual driver resources, which surfaced a bug in resource manager code which was fixed.

The *real&actual* Calculator DA (borrowed for now from System 6) running in the 68K emulator

This allows us to now use real DAs coded in 68K in the emulator – to test this we borrowed Calculator DA from actual System 6, and it seems to work pretty good. You can check it out on this video (check out bonus at the end!):

Video of Calculator DA in action. Audio bonus at end of video 🙂

We also had to add a few missing SANE selectors (FADDX, FSUBX, FDEC2X, and FX2DEC), and through that got introduced to the interesting “Decimal” format, which appears to be binary version of the E-notation used in the Scientific notation of floating point numbers. Hopefully the quickly hacked FX2DEC implementation is accurate enough, at least Calculator seems to be happy with it so far…

(Ps. Yep, the WDEF 1 is still missing close box – it was added super quickly tonight so not 100% complete yet…)

Multi-line TETextBox

After spending the weekend working on a bunch of TextEdit routines, we finally have multi-line support in the static TETextBox, which is used in dialogs to display the static text items. Until now, we only had single-line display working, while multi-lines were displayed as blanks.

Multi-line static text items in Stunt Copter’s “About” box
Multi-line static text item in Lemmings’ copy protection dialog

Another nice benefit is, that as TESetText, TECalText, TEUpdate and related hooks were implemented for non-styled text, we are much closer to having actual text input fields also working properly – although there’s still a lot more work to get there.