123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430 |
- /*
- Copyright (C) 2009-2011 id Software LLC, a ZeniMax Media company.
- Copyright (C) 2009 Id Software, Inc.
-
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License
- as published by the Free Software Foundation; either version 2
- of the License, or (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
- */
- #import "doomAppDelegate.h"
- #import "EAGLView.h"
- #import <AudioToolbox/AudioServices.h>
- #include "../doomiphone.h"
- #import <QuartzCore/CADisplayLink.h>
- #import "SettingsMenuView.h"
- #import "ControlsMenuView.h"
- #include "IBGlue.h"
- #import "MapMenuView.h"
- @interface UIApplication (Private)
- - (void)setSystemVolumeHUDEnabled:(BOOL)enabled forAudioCategory:(NSString *)category;
- - (void)setSystemVolumeHUDEnabled:(BOOL)enabled;
- - (void)runFrame;
- - (void)asyncTic;
- @end
- char iphoneDocDirectory[1024];
- char iphoneAppDirectory[1024];
- @implementation gameAppDelegate
- @synthesize window;
- @synthesize glView;
- @synthesize displayLink;
- extern EAGLContext *context;
- gameAppDelegate * gAppDelegate = NULL;
- NSTimer *animationTimer;
- bool inBackgroundProcess = false;
- touch_t sysTouches[MAX_TOUCHES];
- touch_t gameTouches[MAX_TOUCHES];
- pthread_mutex_t eventMutex; // used to sync between game and event threads
- bool firstRun = true;
- pthread_t gameThreadHandle;
- volatile boolean startupCompleted;
- void *GameThread( void *args ) {
- if ( ![EAGLContext setCurrentContext:context]) {
- printf( "Couldn't setCurrentContext for game thread\n" );
- exit( 1 );
- }
-
- while( inBackgroundProcess ) {
- usleep( 1000 );
- }
-
- printf( "original game thread priority: %f\n", (float)[NSThread threadPriority] );
- [NSThread setThreadPriority: 0.5];
- printf( "new game thread priority: %f\n", (float)[NSThread threadPriority] );
-
- iphoneStartup();
- // make sure one frame has been run before setting
- // startupCompleted, so we don't get one grey frame
- iphoneFrame();
-
- startupCompleted = TRUE; // OK to start touch / accel callbacks
- while( 1 ) {
-
- // we are in the background.. dont do anything.
- if( inBackgroundProcess ) {
- usleep( 1000 );
- }
- iphoneFrame();
- }
- }
- - (void)asyncTic {
- iphoneAsyncTic();
- [ self restartAccelerometerIfNeeded];
- }
- - (void)runFrame {
- iphoneAsyncTic();
- iphoneFrame();
- }
- - (void)applicationDidFinishLaunching:(UIApplication *)application {
- inBackgroundProcess = false;
- application.statusBarHidden = YES;
- application.statusBarOrientation = UIInterfaceOrientationLandscapeLeft;
- gAppDelegate = self;
-
- // get the documents directory, where we will write configs and save games
- NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
- NSString *documentsDirectory = [paths objectAtIndex:0];
- [documentsDirectory getCString: iphoneDocDirectory
- maxLength: sizeof( iphoneDocDirectory ) - 1
- encoding: NSASCIIStringEncoding ];
-
- // get the app directory, where our data files live
- // this gives something like:
- // /var/mobile/Applications/71355F9F-6400-4267-B07D-E7980764F5A8/Applications
- // when what we want is:
- // /var/mobile/Applications/71355F9F-6400-4267-B07D-E7980764F5A8/doom.app
- // so we get that in main() from argv[0]
- #if 0
- paths = NSSearchPathForDirectoriesInDomains(NSApplicationDirectory, NSUserDomainMask, YES);
- NSString *appDirectory = [paths objectAtIndex:0];
- static char iphoneAppDirectoryFromAPI[1024];
- [appDirectory getCString: iphoneAppDirectoryFromAPI
- maxLength: sizeof( iphoneAppDirectoryFromAPI ) - 1
- encoding: NSASCIIStringEncoding ];
- #endif
-
- // disable screen dimming
- [UIApplication sharedApplication].idleTimerDisabled = YES;
-
- // Add the Main Menu as the SubView
- [self MainMenu];
-
- // start the flow of accelerometer events
- UIAccelerometer *accelerometer = [UIAccelerometer sharedAccelerometer];
- accelerometer.delegate = self;
- accelerometer.updateInterval = 1.0f / 30.0f;
- // use this mutex for coordinating touch handling between
- // the run loop thread and the game thread
- if ( pthread_mutex_init( &eventMutex, NULL ) == -1 ) {
- perror( "pthread_mutex_init" );
- }
-
- // use this semaphore for signaling from the async cmd generation thread that
- // the game / draw thread can wake up
- // sem_init is unimplemented on iPhone
- //if ( sem_init( &ticSemaphore, 0, 0 ) == -1 ) {
- // perror( "sem_init" );
- //}
- ticSemaphore = sem_open( "ticSemaphore", O_CREAT, S_IRWXU, 0 );
- if ( ticSemaphore == SEM_FAILED ) {
- perror( "sem_open" );
- }
-
- // we want the main (event/async) thread to be as high a priority as possible
- // so the game/render thread will be interrupted immediately.
- // It looks like the default scheduling on iPhone is already what we want --
- // the main thread is at 1.0, and new threads are at 0.5.
- printf( "original event thread priority: %f\n", (float)[NSThread threadPriority] );
- [NSThread setThreadPriority: 1.0];
- printf( "new event thread priority: %f\n", (float)[NSThread threadPriority] );
-
- // do all the game startup work
- iphoneStartup();
-
- int animationFrameInterval = 2;
- CADisplayLink *aDisplayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(runFrame)];
- [aDisplayLink setFrameInterval:animationFrameInterval];
- [aDisplayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
- self.displayLink = aDisplayLink;
- aDisplayLink.paused = YES;
-
-
- startupCompleted = TRUE; // OK to start touch / accel callbacks
- }
- - (void)applicationWillResignActive:(UIApplication *)application {
- displayLink.paused = YES;
- inBackgroundProcess = YES;
- iphonePauseMusic();
- iphoneShutdown();
- }
- - (void)applicationDidBecomeActive:(UIApplication *)application {
- displayLink.paused = NO;
- inBackgroundProcess = NO;
-
- if( IBMenuVisible && !firstRun ) {
- iphonePlayMusic( "intro" );
- }
-
- firstRun = false;
- }
- - (void)applicationWillTerminate:(UIApplication *)application {
- iphoneStopMusic();
- iphoneShutdown();
- }
- - (void)applicationDidReceiveMemoryWarning:(UIApplication *)application {
- Com_Printf( "applicationDidReceiveMemoryWarning\n" );
- }
- - (void)dealloc {
- [window release];
- [glView release];
- [super dealloc];
- }
- - (void)restartAccelerometerIfNeeded {
- // I have no idea why this seems to happen sometimes...
- if ( SysIphoneMilliseconds() - lastAccelUpdateMsec > 1000 ) {
- static int count;
- if ( ++count < 100 ) {
- printf( "Restarting accelerometer updates.\n" );
- }
- UIAccelerometer *accelerometer = [UIAccelerometer sharedAccelerometer];
- accelerometer.delegate = self;
- accelerometer.updateInterval = 0.01;
- }
- }
- - (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration
- {
- float acc[4];
- acc[0] = acceleration.x;
- acc[1] = acceleration.y;
- acc[2] = acceleration.z;
- acc[3] = acceleration.timestamp;
- iphoneTiltEvent( acc );
- lastAccelUpdateMsec = SysIphoneMilliseconds();
- }
- - (void) PrepareForViewSwap {
-
- [ mainMenuViewController.view removeFromSuperview ];
- [ mapMenuViewController.view removeFromSuperview ];
- [ creditsMenuViewController.view removeFromSuperview ];
- [ legalMenuViewController.view removeFromSuperview ];
- [ settingsMenuViewController.view removeFromSuperview ];
- [ controlsMenuViewController.view removeFromSuperview ];
- [ episodeMenuViewController.view removeFromSuperview ];
- }
- - (void) ResumeGame {
-
- ResumeGame();
-
- // Switch to the Game View.
- [window addSubview:glView];
- [window makeKeyAndVisible];
-
- displayLink.paused = NO;
- IBMenuVisible = NO;
- }
- - (void) MainMenu {
-
- [self PrepareForViewSwap];
-
- // Switch to the Game View.
- [window addSubview: mainMenuViewController.view];
- [window makeKeyAndVisible];
- iphonePauseMusic();
-
- displayLink.paused = YES;
- IBMenuVisible = YES;
- }
- - (void) DemoGame {
-
- StartDemoGame( false );
-
- // Switch to the Game View.
- [window addSubview:glView];
- [window makeKeyAndVisible];
-
- displayLink.paused = NO;
- IBMenuVisible = NO;
- }
- - (void) NewGame {
-
- [self PrepareForViewSwap];
-
- // Switch to the Game View.
- [window addSubview: episodeMenuViewController.view];
- [window makeKeyAndVisible];
-
- displayLink.paused = YES;
- IBMenuVisible = YES;
-
- }
- - (void) playMap: (int) dataset: (int) episode: (int) map: (int) skill {
- mapStart_t startmap;
-
- startmap.map = map;
- startmap.episode = episode;
- startmap.dataset = dataset;
- startmap.skill = skill;
-
- StartSinglePlayerGame( startmap );
-
- [self HideIB];
- }
- - (void) CreditsMenu {
-
- [self PrepareForViewSwap];
-
- // Switch to the Game View.
- [window addSubview: creditsMenuViewController.view];
- [window makeKeyAndVisible];
-
- displayLink.paused = YES;
- IBMenuVisible = YES;
-
- }
- - (void) LegalMenu {
-
- [self PrepareForViewSwap];
-
- // Switch to the Game View.
- [window addSubview: legalMenuViewController.view];
- [window makeKeyAndVisible];
-
- displayLink.paused = YES;
- IBMenuVisible = YES;
-
- }
- - (void) GotoSupport {
-
- SysIPhoneOpenURL("http://www.idsoftware.com/doom-classic/index.html");
-
- }
- - (void) idSoftwareApps {
-
- SysIPhoneOpenURL("http://itunes.com/apps/idsoftware");
- }
- - (void) ControlsMenu {
-
- [self PrepareForViewSwap];
-
- ControlsMenuView * menu = controlsMenuViewController.view;
- [ menu SetOptions];
-
- // Switch to the Game View.
- [window addSubview: controlsMenuViewController.view];
- [window makeKeyAndVisible];
-
- displayLink.paused = YES;
- IBMenuVisible = YES;
-
- }
- - (void) SettingsMenu {
-
- [self PrepareForViewSwap];
-
- SettingsMenuView * menu = settingsMenuViewController.view;
- [ menu resetSwitches];
-
- // Switch to the Game View.
- [window addSubview: settingsMenuViewController.view];
- [window makeKeyAndVisible];
-
- displayLink.paused = YES;
- IBMenuVisible = YES;
-
- }
- - (void) HUDLayout {
-
- menuState = IPM_HUDEDIT;
-
- [self HideIB];
- }
- - (void) HideIB {
-
- [self PrepareForViewSwap];
-
- // Switch to the Game View.
- [window addSubview:glView];
- [window makeKeyAndVisible];
-
- displayLink.paused = NO;
- IBMenuVisible = NO;
- }
- - (void) SelectEpisode: (int) episode {
-
- [self PrepareForViewSwap];
-
- [ (MapMenuView*)mapMenuViewController.view setEpisode: episode ];
-
- // Switch to the Game View.
- [window addSubview: mapMenuViewController.view];
- [window makeKeyAndVisible];
-
- displayLink.paused = YES;
- IBMenuVisible = YES;
-
- }
- @end
|