Boxer levels up again, to 1.3! This version sports the volume controls I told you about last time: along with screenshotting and fast-forwarding, and a heaping helping of bugfixes. Full release notes are here, in HTML even this time.
I tried to make this release as boring as possible, but a couple of interesting improvements still snuck into it while I wasn't looking:
One of those why-didn’t-Boxer-always-do-this features: Gameboxes now remember all the drives you’ve added and queue them up next time you play, even drives that aren’t physically part of the gamebox.
Previously, Boxer would only ‘remember’ drives that were part of the gamebox you were playing. This meant that to get an outside drive to be mounted all the time, you either had to muck about with DOSBox mount commands or let Boxer physically import the drive into the gamebox. Which, you know, sucked.
So now: fire up a gamebox, add a new drive, and it’ll just be there every time you play the gamebox. You can rename or move the drive’s source folder or image, and the gamebox will still find it each time. Drag the drive out of the Drives panel and the gamebox will forget about it again. That’s that.
This finally makes it super-easy to share OSX documents with a DOS app, or share a bunch of utilities among several apps. It also frees you from having to do any drive-importing of your own: until and unless you want to share your gamebox with others.
I’m making this sound like a big fucking bright idea but seriously, why didn’t it always do this?
Boxer 1.3 now boasts the ability to paste text from OS X into any DOS program (as well as the DOS prompt, which was supported already in Boxer 1.2.2).
Pasting still has some limitations: only ASCII characters can be pasted at the moment, so accents get lost in translation. And of course, you can’t copy text back from DOS (at least, not yet.)
But it's still awesome, dammit, so I'm going to bore you about how it works:
MS-DOS has no idea what a clipboard is, so to get text into DOS, Boxer essentially has to type it in.
In MS-DOS, the characters you type start out as raw keyboard signals in the keyboard buffer: from here they're read out by the BIOS, combined and translated into BIOS keycodes (according to the current keyboard layout and state of the Shift/Alt/CapsLock keys), and stored in the BIOS key buffer.
Most DOS programs that deal with raw text (text editors, productivity apps, text-mode games) poll this BIOS key buffer regularly to check for new key input. When you paste text from OSX, Boxer takes over the BIOS key buffer: it translates each pasted character into its corresponding BIOS keycode and feeds them into the program as fast as it asks for them. This is reasonably fast and very accurate, so Boxer uses this approach when it can.
Most DOS games don’t do this though: they read keyboard signals directly from the keyboard’s own buffer, and bypass the BIOS and keyboard layout layers altogether, because they hate me. For these games, Boxer has to work out which combination of keys and modifiers would trigger each character you’re pasting, and literally type those keys into the emulated keyboard.
This is more laborious, among other things because Boxer has to carefully manage the state of the Shift key to match the case of the characters you’re pasting. It's also a lot slower: Boxer has to paste text in short, careful bursts to avoid ‘flooding’ the limited keyboard buffer, and to ensure the program has time to read each batch of typing. But it works.
Neither approach is instantaneous: it’ll take a while to paste large amounts of text, but you can cancel a long paste by pressing Esc in the middle.
OK, that’s all! Go back to what you were doing. (Downloading another awesome Boxer update, that is.)
“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.
Because I’m pathologically incapable of doing a simple bugfix update, I also slipped in a new feature: a simulated numeric keypad to help out players with Macbooks or Apple Wireless Keyboards. In a nutshell:
If you don’t want to hold down Fn all the time, you can also toggle the numpad behaviour on and off with Cmd+U or
I’ve also (re)introduced paste-to-DOS, which had been around in pre-1.0 versions but was cut for being too buggy. You can now paste single or multiple lines of text at the DOS prompt, letting you easily enter command sequences and complicated paths.
In a future release I'll expand this feature to let you paste text into any DOS application - I can see that coming in really handy for text editors and parser-driven games.
Finally, after some constructive pushback in the comments for the 1.2.1 release, I’ve also reverted Boxer’s default location for the games folder back to [your home folder]/DOS Games/. I appreciate better now how many users regard the Documents folder as sacrosanct—unfortunately, OS X is pretty short on good places to put the-kind-of-objects-that-game-ROMs-are. (This will probably be revisited again when Boxer goes through app store submission, which will be Real Soon Now I Promise.)
Salutations chaps and chapettes! Boxer 1.2.1 has been kicked into the street, shivering and bloody. You can grab the new release here, and as usual the full release notes are here (RSS). This release is still 10.5- and PowerPC-compatible, as it contains Serious Bugfixes. The next feature release won’t be however.
The big things for this version are a flicker-free renderer, GOG game-import fixes, and the removal of the first-run games folder choice.
Back when I tore out DOSBox’s old renderer and wrote my own, I was inordinately proud of an Apple-specific rendering optimisation I put in: one which mapped the emulator’s framebuffer directly to an OpenGL texture, saving on potentially expensive writes when new frames are ready.
So proud I was of it, that I blinded myself to three things:
It significantly increased frame-tearing, as Boxer was frequently rendering the previous frame to the display while the emulation was writing over it with the next frame;
Many Mac GPU chipsets didn’t handle the trick very well, causing stuttering or weird rendering artifacts in fullscreen mode;
The actual performance improvement was negligible because these are 20-year-old games for god’s sake, not Wipeout HD.
So in 1.2.1 I swallowed my pride and rewrote the frame updates in a more traditional way: to my chagrin, it turned out very similar to how DOSBox does it. With tweaks to sync up rendering with the display’s vertical refresh rate, Boxer now renders completely free of frame-tearing. If you play games with lot of scrolling (like platformers or pinball) you’ll notice the difference straight away.
The moral of this story: sometimes the smart solution isn’t very smart.
This update also fixes a serious (and stupid) bug in 1.2 whereby Boxer would crash at the end of importing a GOG game that had
BIN+CUE disc images, resulting in a broken game import. If you’ve encountered this, try reimporting games now.
However, Boxer still won’t import certain newer GOG releases correctly: Rayman Forever being exhibit A. Fixing these will require fairly major rewrites to Boxer’s import system, which I hope to do for the next update if I don’t slit my wrists first.
I finally pulled my thumb out of my ass and removed the initial first-run window that asks where to keep your DOS games. This now defaults to
Documents/DOS Games – though the folder can still be changed later from the Preferences window, or just moved somewhere else via Finder. This change has no impact on existing game folders, it only affects people who are running Boxer for the first time.
I’ve been planning this for a while, because I felt humiliated having to ask the user for a commitment before they’ve tried out the app, and because this is a key part of the shift to a ‘post-filesystem’ game browser model. That shift won’t prevent you from accessing your games from the filesystem or organizing your games how you wish — the goal is just to eliminate the need for everybody to care about where things are located.
Anyway! I should be getting on with the game browser in the next major update, though there may be another minor release before then.
Since November I’ve been settling into my new career as an iOS games developer at TicBits! Crossing over into games and iOS development alike have been major long-term goals of mine, and I’m able to work with a great bunch of people, so this has been the perfect opportunity (and one that Boxer helped me get, incidentally). My first game will be out shortly, so look forward to borderline-inappropriate cross-promotion in the coming weeks.
Game development as a day job has meant learning to balance my creative juices between that and Boxer, which is why it’s taken 3 months for me to get a straightforward bugfix release out the door. I think I’ve finally got the hang of this though (the key: weekends) so there should be more substantial updates from here on in 2012.
Incidentally, 1.2.1 is the version I’ll finally be submitting to the Mac App Store: I’ll keep you posted on how that process goes.
The tentpole feature for this release is Roland MT-32/CM-32L emulation, possible thanks to the sterling work of the Munt project. Boxer switches on the emulation whenever a game is playing MIDI music intended for the MT-32. Put on some early-90s Sierra or Origin games and you’ll hear some of the best music ever composed for the DOS era.
Something you may not know is that some games sent cheeky messages to the MT-32’s LCD display when they started up. Boxer shows these in a nifty overlay bezel while you’re playing.
And not only is there MT-32 emulation, but Boxer’s pre-existing support for real MT-32s just got a whole lot better too. Boxer now detects if you have a real MT-32 plugged in, and will pipe MT-32 music to it automatically: no configuration-file hackery needed.
MT-32 emulation requires ROMs that are not quite legal, so Boxer doesn’t come with these out-of-the-box. You’ll have to download the ROMs yourself, and drop them onto Boxer’s Audio Preferences to activate the emulation. But you guys are no strangers to Google I’m sure.
Boxer also supports CM-32L/LAPC-I ROMs: these have an extra bank of sound effect samples, providing better sound in games that can make use of them.
Boxer now respects the GOG game’s DOSBox configuration file: it extracts necessary emulation settings and startup commands, and uses them to set up drives and default programs automatically. This means Boxer 1.2 should Just Work with almost every DOS game from GOG. (Previous versions of Boxer would ignore the configuration file, and just guess at the drive layout: which meant a lot of the time Boxer would get things wrong, especially with newer releases.)
There are undoubtedly exceptions however, and I could use some help tracking down GOG games that Boxer still doesn’t import correctly. See this thread for details.
Note that Boxer cannot open GOG’s Windows-only installers yet: you’ll still need Windows to extract the game files themselves. I hope to nail this one in an upcoming release.
Boxer 1.2 now makes CD swapping easy for multi-CD games, removing another longstanding irritation.
When the game asks you for the next CD, just insert it into the DVD drive (if it's a real disc) or drag it into the DOS window (if it’s a disc image), and it’ll replace the previous disc at the same drive letter. No more dicking around removing and re-adding drives — it just Does the Right Thing.
You can then switch back and forth between the new CD and the old one with CmdShift⇠/⇢ — or pick a CD directly from the newly redesigned Drives Inspector.
You can also import extra CDs into the gamebox with the Drives Inspector — this makes them always available to swap between.
This release fixes a mountain of OS X Lion bugs. If you were getting odd drive-ejected notifications, or having drives disappear on you in the Drives Inspector, or you got a funny rash in an intimate area, well that won’t happen anymore.
Boxer now disables OS X’s function key and arrow-key shortcuts while you’re playing: no more switching Spaces by mistake! This may require a tweak to your Universal Access preferences to let Boxer do this: see Boxer’s Keyboard Preferences for details. Your keyboard’s own built-in function key shortcuts will still take effect unless you hold down Fn while you press them. Unfortunately that functionality is part of the keyboard itself, and out of Boxer’s control.
If your game uses Ctrl ⌃click for its own nefarious purposes, you can now change Boxer’s right-click shortcut from the Mouse Inspector to prevent conflicts.
Boxer’s source code repository and issue tracker have moved to GitHub; other supporting repos will be following shortly.
Boxer 1.2 will be the last OS X 10.5-compatible release, for real this time. Apple have made it too painful to continue supporting legacy versions while developing on Lion, and so 1.2 will be the end of the line for 10.5 and PowerPC support. I’ll still make 1.2.x bugfixes, but all feature development will be 10.6-and-up from now on.
That pretty much covers it I think. So get downloading and get playing!
Design by 40watt.