After several months of big noisy feature work I needed to blow off a little steam: so over the past few weekends I’ve been pottering away on a feature I knew would be of use to approximately 6 people. Can you guess what feature that could be? That’s right!
Boxer 1.4 emulates a 24-pin dot matrix parallel printer, compatible with the IBM PPDS and Epson ESC/P2 printer languages popular in the DOS heyday. This means any DOS app can print text; any DOS app with drivers for IBM ProPrinter or Epson LX/LQ-series printers (including Word, Works, WordPerfect and others) can print graphics too. Authentically shitty graphics, as you can see — just like the old days.
This emulation is built on the third-party printer emulation patch that’s been floating around for DOSBox: rewritten in Objective-C with Cocoa's native PDF support, and sprinkled with some UI magic to help the medicine go down. Boxer uses the standard OS X print panel, so you can print to a PDF file or straight to a real printer. Because Boxer generates actual PDF data, the PDFs you save are fully vectorised and have selectable text.
One of the challenges of printer emulation is that the print workflow in DOS programs is quite different to how we roll these days. Printing in OS X is done in discrete print jobs representing a set of pages or an entire document. But DOS programs squirt text and graphics to the printer line-by-line: they have no notion of a print job, and there’s no formal indication of when they’re actually done printing. This means a human (you) has to decide when the printing is done — and that means you need to be able to see what the printer is doing.
So once the DOS program starts printing, Boxer brings up a live animated print preview showing you what’s coming out of the emulated printer. After the emulated printer has been idle for more than a couple of seconds, Boxer lets you print or discard the pages so far – or you can keep printing more pages to add to the print job. Once you’re ready, hit Print and Boxer will wrap it up as a print job and hand you over to the OS X print panel.
I’ll be honest: the print preview was the reason I implemented this whole feature, because it was a fun design challenge and a way to make printer emulation about me instead. I call this Design By Narcissism.
So when I said back in July that I was taking a break because of real-life commitments, that was a teeny tiny fib. In fact I was beavering away undercover with the fine people at GOG.com to help them launch their DOS games catalogue on Mac.
On October 18th the fruits of our labours were finally revealed, and I can finally gush about what I’ve been working on all this time: Boxer standalone. This is a streamlined and state-of-the-art Boxer built for one purpose: releasing DOS games as individual apps. It's also a peek into Boxer’s future.
When we were figuring out how to deploy GOG.com's DOS games on the Mac, it became abundantly clear that Boxer in its current form wasn't gonna cut it. It sticks you with a folder full of sample games to help you figure out the emulator. Its gameboxes are document files that can’t be played without downloading a separate application. Its emulation is studded with peripheral features to help you install new games and configure them and add new drives to them and all that jazz. The entire app is designed around turning your box of old CDs into a games collection.
But GOG.com are selling games, not raw materials for someone else’s curated emulation experience. Their games already come ready to play, so they don't need any of the features to help you get there. Each game needs nothing but to look and feel like a native Mac game.
So I began macheteing off all the bits of Boxer that weren’t part of that experience. Sample games and game importing were the first to go; the preferences window, inspector panel and drag-drop drive addition all hit the cutting-room floor. The UI was tailored to clean away everything that smelled like emulator infrastructure instead of a native game.
Putting together a game app isn’t as easy as making a gamebox – there’s resources to bundle, app IDs to choose, help links to define, behaviour to tweak, branding to slap on – so I also developed a bundler utility that takes a gamebox and wraps it into an app according to your specifications. It’s not as slick as Boxer’s game importer and it’s not intended for end-users: you’ll need to build it and Boxer standalone from source yourself.
With Boxer’s dead weight liposuctioned away and gamebox-to-app conversion a reality, new challenges came to light. Ones that required exciting and shiny new features.
Boxer’s program panel was designed for one task: choosing the right executable once and never touching it again.
But many of GOG.com’s games don’t have just one true executable: there may be a main game and expansion packs, there may be separate singleplayer and multiplayer options, there may be setup utilities and campaign editors. Boxer’s program panel was woefully inadequate for switching back and forth between different launch options.
Even worse, the program panel insisted on appearing alongside the wretched old DOS prompt, and it wouldn’t even appear at all in fullscreen mode. In a standalone game app, that makes for a terrible user experience.
So I threw it away and started again.
The first time you launch one of these games, you’ll be greeted with a tidy list of predefined launch options. Click an option to launch that program; quit back to DOS, and the app will return to the launch options. (You can also get back to the launch options at any time from the File menu.)
If you quit the app while a program is still running, the app will remember which launch option you’d chosen and start up with that next time. This way, it’s easy to switch back and forth between launch options, without needing to choose one every time you start up.
The launch options panel only appears in GOG games that actually have multiple options. For games with only a single launch option, the game will start up straight away and exiting to DOS will quit the app instead of returning to the launch options.
As you’d expect, inside each game app are all the files for that game. And as you also know, DOS games like to dump their savegames in the same place as all their other program files.
These two facts are on a head-on collision course. OS X apps aren’t expected to be self-modifying: and if you’re not running as an administrator, then apps in the Applications folder are not even allowed to write to themselves. This would prevent you from saving your game and in many cases would prevent the game from running at all.
The solution is one I’ve discussed in the past: write shadowing. Attempts to write to game files are instead written to a ‘shadow’ location inside the current user’s Application Support folder. The app reads changes from there first, before reading the original game files from inside the app. This way noone’s trying to modify the app itself and everyone’s happy.
This has several knock-on benefits:
Dropping OSX 10.5 support let me pull the trigger on a feature I’ve had in my sights for a long time: pixel shaders for rendering styles. Shaders are programmable effects that run on the GPU, and they allow for faster and considerably fancier scaling effects.
The game apps ship with three shader-powered rendering styles: the original untouched output, a 5xBR smoothing shader by Hyllian and crazy46guy, and a simply awesome curved CRT shader by cgwg, Themaister and DOLLS. I cherry-picked these from the thriving BSNES shader community; the coders deserve much love for creating such great-looking shaders.
For older Macs that can’t run pixel shaders at an acceptable speed, Boxer standalone falls back on the old software rendering styles you get in Boxer 1.3.
Naturally, the game apps also natively support those newfangled retina displays.
The game apps are slick as hell, but that comes in exchange for flexibility and features. Hence some caveats:
Each game app has a gamebox inside, so if you prefer you can just run the gamebox in Boxer 1.3.2 instead. However, Boxer 1.3.2 does not utilise the new launch option structure, nor does it support write shadowing: your game state will not be consistent between Boxer and the game app, and any changes you make in Boxer will be saved permanently into the app.
Soon! But there’s still a bunch of work to do before these features are ready to appear in Boxer 1.4:
For now, buy the hell out of GOG.com’s DOS game collection and get the goodies right away. If you don’t mind wet paint and you’re familiar with XCode, you could build Boxer 1.4pre from source and take advantage of all the new features; or even build Boxer standalone and its bundler utility and start churning out your own game apps (some assembly required!)
It's been a huge pleasure to collaborate with the cool guys at GOG.com and big ups to them for choosing Boxer. By doing so, they’ve ensured that their Mac gamers get the best DOS gaming experience across any platform.
“Volume control” is a single bullet point in the feature list for the upcoming Boxer 1.2.3, but I thought it would be interesting (read “validating”) to give a behind-the-scenes tour of what actually goes into a simple feature like this.
First things first is deciding the scope of the feature. I chose early on to make the volume control apply application-wide to every game, rather than tracking it for each individual game, so that its behaviour would be consistent and predictable. The use case I targeted was one I faced daily: muting Boxer to listen to other music or videos in the background.
I chose not to target a more sophisticated use case: tweaking the volume of a specific game, such as one with annoying beeper-speaker effects or really loud MIDI music. I felt this was too complex for a single volume control.
Instead I made plans to add a separate mixer panel later, which would let you tweak the volume of each individual “channel”: PC speaker, digital audio, MIDI and CD audio and so on. The volumes you’ve set for individual channels would be remembered for each game, and scaled by the application’s master volume. But that will have to wait for a future release.
Now I'm ready to start on the physical volume control UI that the user manipulates.
I decided to add a slider to the DOS window's status bar, so it would be obvious and immediately accessible. I made the speaker icons at either end of the slider minimize/maximize the volume when clicked, like they do in iTunes. (And because the volume control is sharing space with the “Click to lock the mouse” help text, I also had to make sure the latter is hidden at small window sizes so they won’t overlap.)
But wait: OS X’s standard slider widget was designed for pale backgrounds, and looks dumb against the darker status bar area. We need a custom slider widget that’s restyled to fit. Good thing I had some custom widget code already for the Inspector panel sliders; unfortunately it needed a lot of rework before it was suitable.
Wait, what if the user is in fullscreen or has the status bar hidden? They won’t be able to access the control. So I added a “Sound” menu containing its own slider, which can be accessed from anywhere. The menu also lets me expose keyboard shortcuts with which the user can nudge the volume up or down.
Because the user can nudge the volume with those shortcuts while no volume slider is visible, we need some way to give them feedback that something has happened. Time for a new notification bezel! (Though we should only show the bezel if the volume slider isn't already visible, otherwise it’s redundant: so check for that too.)
I wanted the bezel to show a speaker that changes according to the current volume, so I snapped screenshots of OS X's menubar volume icon in each of its states and recreated them as vector versions in Photoshop.
So now the UI for our volume control is pretty much ready, but it doesn't actually do anything yet. Time to hit the emulation layer.
First, we need to control the volume of the DOSBox mixer: this component mixes together all of the audio produced by the emulated PC speaker, Sound Blaster etc. This means injecting some more code into DOSBox so that Boxer can dictate the master volume.
But General MIDI output doesn’t pass through the DOSBox mixer: it goes straight to OS X’s CoreAudio MIDI synth. Time to dust off my CoreAudio documentation and figure out how to manipulate the volume on audio units.
If we’re sending MIDI music to a real MIDI device, like an MT-32 plugged into your Mac, this uses a different system again: we need to send actual MIDI commands to the device to change its own master volume. Time to dust off the General MIDI spec. (Of course MT-32s don’t respond to General MIDI volume commands, so we need to send a different message to those instead: time to dust off the MT-32 spec too!)
Because MIDI is a low-bandwidth realtime medium, we need to take care not to spam a real MIDI device with tiny volume changes that would crowd out other MIDI messages. This means coalescing volume updates and sending them at certain intervals, once the device isn’t otherwise busy.
Another wrinkle: many MT-32-compatible DOS games send their own MIDI commands to set the master volume. If we let those go through to the external MIDI device they’ll override our own volume: so we need to detect and intercept those commands, and scale them by our own volume before sending them on their way.
And one final snag: Audio tracks from physical CDs are played back through yet another system, a decrepit and awful SDL API, whose playback volume is beyond the reach of Boxer altogether. I decided this was a bridge too far for this release, since Boxer usually rips CD audio anyway to play back in a manner it can control.
Instead, I swore a dark and solemn oath to rewrite the DOSBox audio architecture for Boxer 1.3: to remove the lingering dependencies on SDL and to unify the disparate outputs under my own roof.
So that’s what goes into a simple application volume control. This is something of an extreme case: some simple features really are trivial to implement, and most don’t have to cover quite so many bases. But they do usually involve a lot of unexpected edge-cases and layers of complexity hidden beneath the surface.
Judging from the discussion upon Boxer’s future post-1.0, passions run pretty high about the Mac App Store. This was originally a comment there, but I’m expanding it into a post of its own, as I want everyone’s thoughts upon it.
App Store skeptics: rest assured that I’m none too taken with the MAS either, and it doesn’t make my life as a developer any easier. The only reason I would stop distributing Boxer separately is if/when it gets simply too hard for me to maintain two separate distributions, and I plan to stick that out as long as possible.
However: the App Store’s not going anywhere, and it will eventually become the only port-of-call for most Mac users looking to find quality software. If Boxer is to be rescued from obscurity, then it needs to be available there sooner or later, however else it continues to be available.
Moreover, most of the restrictions Apple have placed on the behaviour of apps in the App Store make sense and are beneficial to the health of the OS. Private API usage is simply A Bad Idea; centralised application updates are A Good Idea (awkward though this currently is through the MAS); and fostering an overt concern over the physical arrangement of files on one's hard disk is an anachronism that belongs back in the 90s.
To recap, Apple’s app store guidelines mandate that applications keep their supporting folders in
~/Library/Application Support/, and never create folders within the system’s folder space (
Applications etc.) without asking first. Currently Boxer’s default DOS Games folder location is
~/DOS Games/, which would have to change.
I fully recognise the usefulness of choosing the location of this folder—e.g. to be on an external disk or a Dropbox folder—and Boxer will continue to support this. But, it would be saner and safer for Boxer to default to a suitable Apple-friendly location automatically, and let you migrate it afterwards, rather than demanding up-front where and how you want to organise your collection. It’s worth noting that the only real reason Boxer does so now is to draw attention to the sample games it has given you.
One instance came to light post-1.0 of a user choosing their Documents folder itself as the game storage location, and Boxer overriding its icon and appearance as a result. Choosing a system folder is now prevented in Boxer 1.0.1, but this demonstrates how risky and error-prone it can be, to give users the choice of where to put required folders whose contents are controlled by an application.
Boxer's long-term plan is to offer an in-app game browser to work alongside the Finder model. The browser would unify the welcome, import and games-folder UIs; allow you quicker access to recent games; and allow you to display your DOS games by metadata: genre, publisher, year etc.
This is quite clearly Apple’s preferred approach for apps that deal with document-like objects, and would render their physical location irrelevant: which would be a necessity if their actual location is buried deep within a library folder and beyond the reach of Finder. As a further complication, OS X 10.7 Lion hides the
Library folders altogether from Finder, and can optionally sandbox an app’s files so they don’t even live there anymore. This, I have grave reservations about.
The rise of the App Store distribution model, and the push towards an iOS-style sandboxed approach to the filesystem, are going to see a lot of pushback from Mac developers and Mac users alike in the coming year. As someone who grew up with the old paradigms, I’m reluctant to change and can’t tell to what extent the new paradigms will actually improve and simplify the Mac desktop experience.
My concern is to make sure Boxer continues to work the way the Mac works; but without alienating users who prefer the way the Mac used to work. Above all, I don’t want to discard the old when embracing the new—except where the old really did suck.
So, what do you think?
Now that Boxer stores per-user-per-gamebox settings, we can have some much-needed tweaks for mouse behaviour:
A slider for mouse speed, to fix games that get it wrong and don’t let you adjust it in-game. This applies only while the mouse is locked: while unlocked, Boxer sticks to OS X’s mouse speed to keep the OS X and DOS cursors in sync.
A toggle to ignore the mouse until it’s locked. When enabled, the mouse does nothing until you click on the window, at which point it is automatically locked. (This is analogous to DOSBox’s original “autolock” mode.)
This latter setting is vital for games where moving the mouse also moves the game view: Boxer’s regular behaviour can be frustrating as hell, if the game goes spinning or scrolling off into oblivion while you reach for a menu.
I’ve been humming and hawing for some time over how to present the option. It’s clear that it’s necessary, but it may be worth going further and making it the default; or making it Boxer-wide instead of per-gamebox, like rendering settings; or making it per-gamebox instead of per-user, like CPU settings. Time will tell where it should best live.
For the moment though, I feel that Boxer’s regular mouse behaviour does a good job for most games; and I find I only want to change it for one or two that misbehave. So for me, it strikes the best balance to have it as a per-user-per-gamebox option that’s disabled by default.
I’ve been primping and preening it to within an inch of its life. Besides aesthetic improvements, I’ve put in buttons to add, eject and manipulate drives, making the panel’s functionality more obvious and accessible.
The biggest addition though is the ability to import drives into the gamebox straight from the Drives panel. This copies an entire volume or disc image into the gamebox, so it comes along for the ride and gets mounted whenever you play the game.
Of course, this is just like Boxer 0.8x used to do when installing games, and will be a key feature of Boxer 1.0’s upcoming game installer too. It’s not often that you’ll need to use it outside of game installation; but I want to ensure that anything you can do during installation, you can do afterwards too.
This will hopefully be the last alpha build before Boxer 1.0 goes beta. That will be a Boxer feature-complete and mere weeks away from a final release. After one-and-a-half years, the time is nigh.
There’s two core features left to (re)implement before then: game installation, and the DOS Games folder. I’ll be working furiously through August to get these ready, and I’m very excited for what we’ll have to play with at the end of it.
Design by 40watt.