iDevGames Forums

Full Version: Next step after Timers
You're currently viewing a stripped down version of our content. View the full version with proper formatting.


If you are interested on a little more control and precision than timer based game loops check out the Quake 3 source code for some hints on how to use a standard (while/for) game loop using Cocoa.

It takes some digging but the general idea is to start a normal Cocoa application according to the standard Apple documentation for Cocoa. Next implement the applicationDidFinishLaunching to call into your games "main" method. Make sure you set the applications delegate to point to the class that implements the applicationDidFinishLaunching method. This is shown in the Q3Controller.m file.

In the "quakeMain" method at the very bottom a while(1) loop is entered that calls Com_Frame over and over again. Also in this loop every 15 times through the loop (I think) it releases and reallocates an NSAutorelease pool. This keeps memory from filling up from the Cocoa objects being allocated and released during the running of the loop and also cuts down on the deallocs being called all at once by not doing it every time through the loop.

The Com_Frame subroutine (in normal C code) is where the rest of the action is stowed. This subroutine handles the variable frame animation and picks up events and processes them. While doing this it uses the routines in macosx_input.m. The most useful function here is Sys_SendKeyEvents. This is where the standard event processing is bypassed and nextEventMatchingMask method on the NSApplication class is used to pull events from the system and dispatch them. How Quake3 handles keyboard and mouse events is stored in here also.

After getting the events this way, next they create their own event structure and push this onto their own event queue which is platform independent. Then Com_Frame picks up and processes these system independent events. The reason they do this is because it looks like they have a way to store these system independent events in a file so that they can be played back for testing the game or possibly for demos. It looks like possibly even network events are put into this event queue.

This method of game loop is not really much harder to do than timers in my opinion but this technique is probably only useful when you are writing FPS games like Quake 3 and you need all the CPU cycles you can get and more guaranteed precision in your game loop timing. But for most smaller projects timers are the way to go.

I have been trying to implement this technique using Carbon instead of Cocoa over the past week but have been unsuccessful (mostly because I've been learning Carbon as I go). I have a theory on how to go about it but the amount of code required just to get the game loop up is getting out of hand.

Basically you would start your Carbon Run loop and implement a CFRunLoopObserver in place of the applicationDidFinishLaunching notification. Then you would use the ReceiveNextEvent call in place of nextEventMatchingMask. Problems I don't have a solution for are 1.) I'm not sure the best place to put the run loop observer to most closely mimic a Cocoa notification; 2.) I'm not even sure a run loop observer is similar enough to a notification to be used in this way. But even at the point I'm at the amount of code seems excessive and Id Software choosing Cocoa gives it some credibility in the speed department. Obviously it's adequate for a commercial FPS.
Just call your applicationFinishedLaunching function yourself, before your first call to RNE. Don't make things more complicated than they already are Rasp

There's nothing wrong with the timer-based approach to a game loop, either. Quake 3 does things the other way because it does full-screen without a window, which is going against the grain of Cocoa.

The choice of Carbon vs. Cocoa will generally be completely irrelevant for games -- you're not going to spend enough time in either API for it to make a difference. Pick whichever you think is easier -- but remember, many more people know about Cocoa than Carbon, so if you're going to need to ask for help, take that into account Wink
Reference URL's