Mac OS X CoreAudio reference setup code

I've created two repositories up on Github with my Mac OS X ports of Handmade Hero. They incorporate Casey's code as of Friday, although I have to finish fixing up a few things and clean up some sections of code. The goal is to be able to take Casey's daily platform independent code, and drop it right into the project so it compiles and runs unchanged.

As Casey is not releasing the game source publicly yet, I won't update the platform-independent code (handmade.cpp and whatever that turns into) much more on Github, but I'll try to make sure the OS X specific code stays updated to support the ongoing development.

I used native OS X libraries for the port:
- CoreAudio for sound
- OpenGL for graphics
- HID for joystick input
- CVDisplayLink for frame timing

So far for input support, I've only tested a dusty old Logitech gamepad controller that I found in my closet, so I'm interested to see if anyone has luck with other controllers.

The main Github repository is a standard-looking Xcode project:
https://github.com/itfrombit/osx_handmade

The second repository is basically the same code, along with some extra plumbing to demonstrate how to create the app completely programmatically without a nib file or using an Xcode project.
https://github.com/itfrombit/osx_handmade_minimal

This second version works, but it's not a good Mac app citizen at the moment. It needs some additional work to assemble it into a standard Mac application bundle, but that's easy to do. The minimal version is mostly a technology demonstration, so you're probably better off following the standard Xcode-based app repository.
Big thanks Jeff! Also nice that you walked that extra mile to show different approaches.
In a way it seems to be better to use the xcode/regular style to get everything to play ball. Easier to to adaptations, app icons , prepare for app store etc. But, I think it would be beneficial to create a command line build example so you don't have to use xcode beyond the initial setup. What's your take on this?
xcodebuild works as it is for now but it would be nice to not have to use xcode at all going forward when adding files etc.

For approach 2, the minimal version, I guess you will write something for creating the .app folder structure like: https://gist.github.com/framkant/1c135f8d6d012ceceda6
and then calling that in the build script ?
/Filip
@wan,

You could recreate the steps that xcodebuild does, but you're probably better off just using xcodebuild directly for command line builds of Xcode projects. If you're curious, you can look at the build logs in Xcode for all of the gory details.

For the minimal version, the gist you pointed to is exactly along the lines of what you do to put it into proper form for a Mac app bundle. A few years ago, I worked on an interpreted Lisp language that ran on top of the Objective-C runtime (http://programming.nu), and we built a command line tool that did this very thing to assemble standalone apps.
Hi Jeff, what is the license for this code? I would like to modify and integrate parts of it in my own project, mostly initialisation of the audio and HID stuff. Using an AudioUnit certainly seems more efficient than the AudioQueue interface.

Is this fullscreen method the most efficient? E.g. it disables app switching, whereas many large games ported by Feral leave that working. There are quite a few fullscreen mechanisms now in OS X, bit confusing.

Also, I tested the app with my wired Xbox 360 controller and it was a bit odd, mostly because the left stick makes minor motions inside its dead zone that would overrule other inputs. Best result was when I used the right trigger to lower and raise the pitch, the sticks were all over the place. I'll play with it some more today. Thanks.
I usually use something like an MIT or BSD license on open source projects, but in the spirit of this project, you can consider my code in the repositories to be public domain. So use it how you like. Bug reports and suggestions (and pull requests) are appreciated, but if you want to take the code and run off in your own direction, that's cool too.

For fullscreen app switching, I'm probably just eating the command-tab keystroke before it propagates through the responder chain. I'll fix that so it works like you'd expect.

The HID input processing is very much a hack at the moment. I custom scaled the inputs so I could quickly just get the sine wave tone to change in an acceptable range for testing, but I'll be doing some major cleanup on that code. Also, for the right analog stick, I'm only catching the rz input at the moment. I'll add the rest of them in, but in the meantime, you can check out page 26 of the USB HID Usage Tables spec for more details on the other missing usage values:
http://www.usb.org/developers/hidpage/Hut1_12v2.pdf

Until I do proper HID range detection, you might also need to play with the xyRange and xyScalingShiftFactor variables to get your controller sensitivity correct. I just ordered an Xbox 360 controller so I can get it working better. I suppose that's the controller most people would be using.

I'm going to be doing some general cleanup and refactoring to the whole shell. There are lots of global variables laying around and lots of code that needs bulletproofed. I'll be fixing a few things in the near term and then cleaning up the rest once Casey is more-or-less done with the platform layer.
Jeff, I'm way behind you with my own code but it seems you have the same bug I do. Whenever the window is resized below-if I remember correctly-precisely 3px in height the update method of NSView recurses infinitely and crashes. I found this bug fix in Chromium that seems to address the same problem (https://codereview.chromium.org/8261004).

There are also glitches during resizing due to update weirdness. Still don't know what the best solution is but it can visually be removed by redrawing in update as well as the display link callback. But I imagine that will introduce problems when I get round to interfacing with the actually game code.

In my code I have overridden update with this
1
2
3
4
5
6
7
8
9
- (void) update
{
    if (updated)
        return; // bail out quick if we've already updated.
    updated = YES;
    [super update];
    // set viewport and redraw frame
    updated = NO;
}
Thanks for the head's up on the resizing issues.

For the first issue, the easiest thing to do is to prevent the window size from ever getting that small. I just added

1
    [window setMinSize:NSMakeSize(100, 100)];

to keep the window size (100, 100) or bigger. If you are using a nib, you can alternatively set the min size of the window in the sizing constraints section. I'll probably make this min size even larger at some point because I doubt the game will work well at (100, 100).

I fixed the resizing glitch by forcing a redraw right after I resize the OpenGL viewport. My drawView method locks the openGL context, so it can be called from either the main thread or the CVDisplayLink callback thread. I added a resizing flag to the drawView method, so you can check that if you don't want to do any game logic during resize events. That's probably what I'll do.
Hey Jeff, thanks for the OS X port! I'll definitely be using that to follow along with Casey going forward. One suggested change:

1
#define rdtsc __builtin_readcyclecounter

as a slightly cleaner option on Clang than the using the (admittedly fine) inline assembly. It's described in the Clang builtin docs.
Great to see so many people contributing!
I tried my hand at a "hybrid approach" where I set up the .xib in xcode and then do the rest from the command line.

Ultra minimal example here: https://github.com/framkant/osx_handmade_hybrid

At the moment, it just shows the packaging/creating of a bundle etc

I'm not sure which way is better, but on a personal level I want to stay as far away from xcode as possible.
/Filip
@visitect,

Thanks for the head's up on __builtin_readcyclecounter() - I didn't know about that. That's way cleaner.

Jeff
Filip,

That's a good example of building and packaging a Mac app. Nice work!

I don't go out of my way to avoid Xcode, but I do most of my editing and building outside of it. Xcode's debugger is a far cry from Visual Studio's debugger, but it's still better than using lldb from the command line.
@zenmumbler,

Are you using a 3rd party device driver for your Xbox 360 wired controller on your Mac? I just bought one and plugged it into my Mac to test it out, but it doesn't look like it's even being recognized.

Thanks,
Jeff
@itfrombit, yes, you need a driver from tattiebogle. Odd name, but it works. See the GitHub repo releases for a version compatible with 10.10.

https://github.com/d235j/360Controller

Curious about your findings! Use the supplied control panel to test force feedback etc.
Jeff, when I connect my ps4 controller using USB your app crashes. If I connect using bluetooth it seems to work but loses connection after one second.

Just wondering, have anyone of you tried to use GameController framework which is available on 10.9 and 10.10 ?

On a note, using ps4 controller with GLFW3 works fine. It also uses IOKit directly but with a different approach.

And btw maybe it is time to rename this thread to "Mac OS X platform layer?" or start a new thread ....
@zenmumbler,

I was wary of installing the tattiebogle experimental unsigned kernel extension, but what the hell. That's why I keep a reformattable Mac laying around.

So there were two main problems:
- The scaling factors were way off compared to the Logitech controller I was testing with.
- Some dead zone detection needs implemented.

In the meantime, if you want to try your 360 controller with a little better behavior until I do auto-scaling, change these variables for now:
xyRange = 32768
xyScalingShiftFactor = 12

That won't fix the dead zone detection, but that should at least get you a little less wacky behavior for the time being. I'll sort this out tonight.