GUI programming on old Macs can be pretty painful.
For some background, I am relatively new to Mac programming but experienced with programming in general. I have been doing a fair amount of programming using the Retro68 console recently, but now I’m looking to create some more GUI-based applications, so they can feel more “Mac-like”.
I’ve been pouring through the books “Inside Macintosh: Macintosh Toolbox Essentials” and “Inside Macintosh: More Macintosh Toolbox” along with some other resources online, and have been playing around a bit manipulating the “MenuSample” test app from this blog post: http://www.toughdev.com/content/2018/12/developing-68k-mac-apps-with-codelite-ide-retro68-and-pce-macplus-emulator/.
I formed some opinions as I got started:
- programming against the Macintosh Toolbox is cumbersome, difficult to use
- for example, even creating a textbox to handle input on the screen requires multiple steps across multiple files (res file definition + handling in code and the code is non-trivial compared to how one might do it today)
- it is difficult to define layouts and respond to size changes. adding lots of elements to a window and dealing with them is pretty hard
- this is probably hindering the creation of at least a subset of new Mac apps that could be getting developed… Personally I think there is a lot of interest but the barrier to entry is high
- GUI programming has advanced a lot in the last 30 years and even basic GUI libraries do a lot more for the programmer these days
- Programmers writing software for Macs in the 80s and 90s were heroes. It’s amazing what they accomplished with the tooling and resources that they had
To prove myself wrong, I have spent some time playing with getting some of Mac sample apps working with Retro68, such as: https://github.com/CamHenlin/TESample – check out how much code is required just to get a text area working! We can do better!
There are a lot of modern micro UI libraries aimed at embedded devices or to be embedded in other pieces of software. Some of these include:
There are some others that I’m probably missing that would be mentionable as well, but all of these seemed like they would fit the bill.
I set on trying to create a QuickDraw back end for a few of these libraries using QuickDraw and targetting System 6 Macs. Here are a few of those repos:
My intents for these were:
- Get a POC working as quickly as possible to prove the idea is solid, get the source code online for others to look at.
- Fully functioning, easy to use and define, GUI
- only support 1 font up front - loading in other fonts from nuklear (or others) would require more complex image rendering that QuickDraw can’t provide
- no image support of any kind - again, QuickDraw has limited facilities for handling images, I think PICTv1 only. this could happen in the future maybe, but someone would need to create a function to render at least BMPs using quickdraw (probably pretty easy tbh)
- b&w support only - again, might be easy to use color QuickDraw here, but I am personally more interested in coding for b&w Macs
After much expirementation and time I came to the conclusion that Nuklear would likely be the best fit in terms of these types of libraries due to the possibility for leveraging several built in QuickDraw commands to draw the UI. I think having a simple immediate mode GUI library is really nice and is going to be an excellent choice for building out small apps for Classic Macs rather than needing to dive in on the toolbox.
It took a lot of work to get things to the point of being usable despite Nuklear being the “most usable” out of box. These optimizations (from base Nuklear) include:
- All nuklear floating point math has been modified to be integer-based math. This was likely our single biggest performance increase as the 68000 processor does not have a floating point unit.
- Some UTF8 support has been removed (Macintosh doesn’t support it anyways!)
- The QuickDraw graphics layer has been optimized to draw as little as necessary. We’re doing two things here: Between nuklear draw runs, we only draw commands that are changed from one run to the next. This results in us avoiding full window redraws when we are typing for example. The other thing we’re doing is only copying over the bits of the screen that are changed during our double buffering operations.
After optimization, the UI performance is close to excellent. I was able to come to approximately 10x performance improvement from base Nuklear with these changes which was necessary to work well on an 8MHz Macintosh. Performance gains were quantified and verified using this strategy for profiling Retro68 applications. Using the default system font and standard drawing routines I think also gives things a very “Mac-like” feel.
I have the https://github.com/CamHenlin/nuklear-quickdraw up with a small example application ready to build against – the repo README file outlines the necessary steps to get started on your own changes and my other post (here) should help get you up and running with a development workflow. You can start developing your own Nuklear-based Macintosh application using this repo as a base today.
press esc + ↑ to zoom in, esc + ↓ to zoom out
Everything that applies to some of the Nuklear documentation that you find online should work here:
- https://www.thecodingfox.com/nuklear-usage-guide-lwjgl – this is a really good one
Are you building a project using Nuklear on classic Macintosh? Let me know! I’ll include it here.
Did you enjoy my post?
I'm really excited about the work that I'm doing here. If you enjoyed my post and my work, please consider tipping me with a coffee. I appreciate you taking the time to read my post!