This was a pretty good week of coding. After implementing some core platform specific code and moving the Windows OpenGL code to Mac OSX, the game rendered on the screen without any issue.
Well, I shouldn’t say without any issue. It runs at less than 1 frame per second and water isn’t rendering correctly. There’s still no sound and no input, no Steam integration and it lacks the ability to resize the window and shut down. But I’m getting there. It’s good progress.
Working on Mac and doing this port has been a good experience. This week I hope to head back and spend time on the current Beta version a bit to work out some issues, then get back to the Mac version.
In the mean time here’s some thoughts on working on Mac. I’ve been using Windows exclusively (except for console programming) for a long time, and OSX is a new system to me, so don’t be offended if I’m getting things wrong. 🙂
Using a Mac
I don’t know anything about OSX. When I started I could open the web browser, and that’s about it. I stumbled with the user interface for a bit, couldn’t figure out how an ‘All Files’ category was useful when browsing finder windows, but then realized I could open a term window and that I was really using a unix-like system with a user interface that wasn’t X Windows. Good deal, I can do that.
So after that, file organization and using the machine was easy, and I was comfortably editing files using vi. Apparently my vi command muscle memory hasn’t totally faded.
Development Environment: Xcode
Xcode isn’t too bad. It was fairly intuitive to bring the Banished source into it, setup the required compiler settings and get to work. I mostly turned off it’s auto formatting since it does things that don’t go with my code style, and the intellesense is a bit overdone, but overall it’s an IDE that gets the job done.
When I look at Objective-C and the general Cocoa libraries, I feel like I’m looking at a foreign language I haven’t used in 20 years. I bought a book on it to help out. I mostly get it, but I just feel like I’m missing a fundamental knowledge base. Luckily there’s not that much of it I have to write or use before it jumps straight into the C++ code that’s common to all platforms.
I just need to spend more time with it. And read the book.
I had the best intentions of writing my game engine using portable C++. I didn’t do anything crazy with the language, and any platform specific chuncks were tucked away in their own files to be replaced per platform.
While that was a good start, I don’t think it’s possible to actually write cross platform code until you’re compiling the code with multiple compilers. Even before I could get to writing the OSX specifics, I had many errors and warnings that clang presented that the Microsoft compiler just overlooked.
Most of these had to do with templates that expected the code inside them not to be compiled until they were instantiated. The Microsoft compiler has that behavior, while clang does not. There’s command line flags for a compatibility mode, but I’d rather just fix the issues so that other compilers won’t treat the errors the same way.
Once the common code was compiling cleanly, I started writing things specific to OSX. Memory management, file I/O, timers, date handling, threading, etc. What is nice, is being a unixy environment, a ton of the platform specific code will also work on Linux and Steam Box. When I get to working on Linux more fully it should go quickly.
I did have a few issues that required changes to both the Windows and Mac code bases to make sharing more code possible, but it was an easy refactor.
I’m glad I spent the time to write a common shader language, switch to UTF8, and make other changes to the engine to make porting easier. I could have just ported as the code was, but it would have been a lot more labor intensive and bug prone.
Currently the toolset for Banished only works on Windows – so it’s really just the engine and game code that are being written for OSX. This is a little annoying, as all the data has to be compiled on the PC, and then the Mac just reads it. I should convert everything to work on all platforms, so that I don’t have to flipflop machines, but this would take a lot of additional effort.
The OpenGL code I wrote for Windows came over smoothly, without any compile errors. Although I did have to write the platform specific startup code to create pixel formats and OpenGL contexts. I’m not using SDL or any other library to hide those platform differences.
I unfortunately have two different sets of the same GL code now. The Windows code is nearly identical, but since Windows supports multiple renderers (DX9/DX11/GL/etc) there’s some abstractions and separation of data that doesn’t exist on Mac.
Copy-pasted-slightly-edited code like this annoys me a bit but at the moment I don’t have a good way to abstract away the differences. It’s not terrible, but a little frustrating to have to update two sets of the same code when bug fixes are made. At least the Linux build should share the code 100%.
If nothing else, it was satisfying to actually see the title screen come up on the first try after bringing over the OpenGL code. If I was writing for a console (or other graphics API) it’d probably take an entire week just getting the first triangle on the screen.
The fact that it’s running at 1 FPS is a little disheartening – I know the GPU is fast enough. I’ve got a Windows machine with an Intel Iris Pro 5000 that runs Banished just fine, which is the same graphics hardware in my MacBook Pro. I’ve got my suspicions as to whats going on but I have a bunch of testing ahead of me to make sure I fix the issue properly.
I’ve got a bit more coding and learning about Mac to do before the port is done. I don’t expect the remaining tasks to be too arduous – playing sounds, reading input, and compiling the Steam library should be easy. ish. Maybe.