Maelstrom: Switched the game to do frame processing on the Cocoa event loop so Game Center works properly.

https://github.com/libsdl-org/Maelstrom/commit/56c95e26e880261da18c44941262d40115e4e6b2

From 56c95e26e880261da18c44941262d40115e4e6b2 Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Fri, 22 Jun 2012 19:26:58 -0400
Subject: [PATCH] Switched the game to do frame processing on the Cocoa event
 loop so Game Center works properly.

---
 Xcode-iOS/Maelstrom_GameKit.mm |  2 +
 game/main.cpp                  | 86 +++++++++++++++++++---------------
 screenlib/SDL_FrameBuf.h       |  3 ++
 3 files changed, 54 insertions(+), 37 deletions(-)

diff --git a/Xcode-iOS/Maelstrom_GameKit.mm b/Xcode-iOS/Maelstrom_GameKit.mm
index b1d86e85..5c189848 100644
--- a/Xcode-iOS/Maelstrom_GameKit.mm
+++ b/Xcode-iOS/Maelstrom_GameKit.mm
@@ -27,6 +27,8 @@ void InitGameCenter(void)
             } else {
                 // Disable Game Center features
 		s_hasGameCenter = NO;
+		
+		NSLog(@"Unable to log into Game Center: %@", [err localizedDescription]);
             }
         }];
     }
diff --git a/game/main.cpp b/game/main.cpp
index 000212d1..b954e21f 100644
--- a/game/main.cpp
+++ b/game/main.cpp
@@ -272,6 +272,42 @@ InitFilesystem(const char *argv0)
 	return false;
 }
 
+/* ----------------------------------------------------------------- */
+extern "C" void ShowFrame(void*);
+extern "C"
+void ShowFrame(void*)
+{
+	SDL_Event event;
+
+	// If we got a reply event, start it up!
+	if (gReplayFile) {
+		RunReplayGame(gReplayFile);
+		SDL_free(gReplayFile);
+		gReplayFile = NULL;
+	}
+
+	ui->Draw();
+
+	/* -- In case we were faded out */
+	screen->FadeIn();
+
+	/* -- Get events */
+	while ( screen->PollEvent(&event) ) {
+		if ( ui->HandleEvent(event) )
+			continue;
+
+		/* -- Handle file drop requests */
+		if ( event.type == SDL_DROPFILE ) {
+			gReplayFile = event.drop.file;
+		}
+
+		/* -- Handle window close requests */
+		if ( event.type == SDL_QUIT ) {
+			RunQuitGame(0);
+		}
+	}
+}
+
 /* ----------------------------------------------------------------- */
 /* -- Blitter main program */
 int MaelstromMain(int argc, char *argv[])
@@ -280,17 +316,10 @@ int MaelstromMain(int argc, char *argv[])
 	Uint32 window_flags = 0;
 	Uint32 render_flags = SDL_RENDERER_PRESENTVSYNC;
 
-	/* Normal variables */
-	SDL_Event event;
-
 	if ( !InitFilesystem(argv[0]) ) {
 		exit(1);
 	}
 
-#if __IPHONEOS__
-	InitGameCenter();
-#endif
-
 	/* Seed the random number generator */
 	SeedRandom(0L);
 
@@ -323,42 +352,25 @@ int MaelstromMain(int argc, char *argv[])
 	while ( sound->Playing() )
 		Delay(SOUND_DELAY);
 #endif
-	ui->ShowPanel(PANEL_MAIN);
 
-	while ( gRunning ) {
-		// If we got a reply event, start it up!
-		if (gReplayFile) {
-			RunReplayGame(gReplayFile);
-			SDL_free(gReplayFile);
-			gReplayFile = NULL;
-		}
-
-		ui->Draw();
-
-		/* -- In case we were faded out */
-		screen->FadeIn();
-
-		/* -- Get events */
-		while ( screen->PollEvent(&event) ) {
-			if ( ui->HandleEvent(event) )
-				continue;
+	ui->ShowPanel(PANEL_MAIN);
 
-			/* -- Handle file drop requests */
-			if ( event.type == SDL_DROPFILE ) {
-				gReplayFile = event.drop.file;
-			}
+#if __IPHONEOS__
+	// Initialize the Game Center for scoring and matchmaking
+	InitGameCenter();
 
-			/* -- Handle window close requests */
-			if ( event.type == SDL_QUIT ) {
-				RunQuitGame(0);
-			}
-		}
+	// Set up the game to run in the window animation callback on iOS
+	// so that Game Center and so forth works correctly.
+	SDL_iPhoneSetAnimationCallback(screen->GetWindow(), 1, ShowFrame, 0);
+#else
+	while ( gRunning ) {
+		ShowFrame(0);
 		DelayFrame();
 	}
-
-	ui->HidePanel(PANEL_MAIN);
 	CleanUp();
-	exit(0);
+#endif
+	return 0;
+
 }	/* -- main */
 
 
diff --git a/screenlib/SDL_FrameBuf.h b/screenlib/SDL_FrameBuf.h
index 6fc827b5..16c92aa0 100644
--- a/screenlib/SDL_FrameBuf.h
+++ b/screenlib/SDL_FrameBuf.h
@@ -112,6 +112,9 @@ class FrameBuf : public ErrorBase {
 	}
 
 	/* Information routines */
+	SDL_Window *GetWindow() const {
+		return window;
+	}
 	int Width() const {
 		return rect.w;
 	}