project_files/HedgewarsMobile/Classes/HedgewarsAppDelegate.m
changeset 5002 a9c44a8ffec8
parent 4976 088d40d8aba2
child 5017 d29cf06d7d11
equal deleted inserted replaced
5001:312f4dd41753 5002:a9c44a8ffec8
       
     1 /*
       
     2  SDL - Simple DirectMedia Layer
       
     3  Copyright (C) 1997-2011 Sam Lantinga
       
     4 
       
     5  This library is free software; you can redistribute it and/or
       
     6  modify it under the terms of the GNU Lesser General Public
       
     7  License as published by the Free Software Foundation; either
       
     8  version 2.1 of the License, or (at your option) any later version.
       
     9 
       
    10  This library is distributed in the hope that it will be useful,
       
    11  but WITHOUT ANY WARRANTY; without even the implied warranty of
       
    12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
       
    13  Lesser General Public License for more details.
       
    14 
       
    15  You should have received a copy of the GNU Lesser General Public
       
    16  License along with this library; if not, write to the Free Software
       
    17  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
       
    18 
       
    19  Sam Lantinga, mods for Hedgewars by Vittorio Giovara
       
    20  slouken@libsdl.org, vittorio.giovara@gmail.com
       
    21 */
       
    22 
       
    23 #import "HedgewarsAppDelegate.h"
       
    24 #import "PascalImports.h"
       
    25 #import "ObjcExports.h"
       
    26 #import "CommodityFunctions.h"
       
    27 #import "GameSetup.h"
       
    28 #import "MainMenuViewController.h"
       
    29 #import "OverlayViewController.h"
       
    30 #import "Appirater.h"
       
    31 #include <unistd.h>
       
    32 
       
    33 #ifdef main
       
    34 #undef main
       
    35 #endif
       
    36 
       
    37 #define BLACKVIEW_TAG 17935
       
    38 #define SECONDBLACKVIEW_TAG 48620
       
    39 #define VALGRIND "/opt/fink/bin/valgrind"
       
    40 
       
    41 int main (int argc, char *argv[]) {
       
    42 #ifdef VALGRIND_REXEC
       
    43     // Using the valgrind build config, rexec ourself in valgrind
       
    44     // from http://landonf.bikemonkey.org/code/iphone/iPhone_Simulator_Valgrind.20081224.html
       
    45     if (argc < 2 || (argc >= 2 && strcmp(argv[1], "-valgrind") != 0))
       
    46         execl(VALGRIND, VALGRIND, "--leak-check=full", "--dsymutil=yes", argv[0], "-valgrind", NULL);
       
    47 #endif
       
    48     NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
       
    49     int retVal = UIApplicationMain(argc, argv, nil, @"HedgewarsAppDelegate");
       
    50     [pool release];
       
    51     return retVal;
       
    52 }
       
    53 
       
    54 int SDL_main(int argc, char **argv) {
       
    55     // dummy function to prevent linkage fail
       
    56     return 0;
       
    57 }
       
    58 
       
    59 @implementation HedgewarsAppDelegate
       
    60 @synthesize mainViewController, overlayController, uiwindow, secondWindow, isInGame;
       
    61 
       
    62 // convenience method
       
    63 +(HedgewarsAppDelegate *)sharedAppDelegate {
       
    64     return (HedgewarsAppDelegate *)[[UIApplication sharedApplication] delegate];
       
    65 }
       
    66 
       
    67 -(id) init {
       
    68     if (self = [super init]){
       
    69         mainViewController = nil;
       
    70         uiwindow = nil;
       
    71         secondWindow = nil;
       
    72         isInGame = NO;
       
    73     }
       
    74     return self;
       
    75 }
       
    76 
       
    77 -(void) dealloc {
       
    78     [mainViewController release];
       
    79     [overlayController release];
       
    80     [uiwindow release];
       
    81     [secondWindow release];
       
    82     [super dealloc];
       
    83 }
       
    84 
       
    85 // main routine for calling the actual game engine
       
    86 -(NSArray *)startSDLgame:(NSDictionary *)gameDictionary {
       
    87     UIWindow *gameWindow;
       
    88     if (IS_DUALHEAD())
       
    89         gameWindow = self.secondWindow;
       
    90     else
       
    91         gameWindow = self.uiwindow;
       
    92 
       
    93     UIView *blackView = [[UIView alloc] initWithFrame:gameWindow.frame];
       
    94     blackView.backgroundColor = [UIColor blackColor];
       
    95     blackView.opaque = YES;
       
    96     blackView.tag = BLACKVIEW_TAG;
       
    97     [gameWindow addSubview:blackView];
       
    98     if (IS_DUALHEAD()) {
       
    99         blackView.alpha = 0;
       
   100         [UIView beginAnimations:@"fading to game first" context:NULL];
       
   101         [UIView setAnimationDuration:1];
       
   102         blackView.alpha = 1;
       
   103         [UIView commitAnimations];
       
   104 
       
   105         UIView *secondBlackView = [[UIView alloc] initWithFrame:self.uiwindow.frame];
       
   106         secondBlackView.backgroundColor = [UIColor blackColor];
       
   107         secondBlackView.opaque = YES;
       
   108         secondBlackView.tag = SECONDBLACKVIEW_TAG;
       
   109         secondBlackView.alpha = 0;
       
   110         [self.uiwindow addSubview:secondBlackView];
       
   111         [UIView beginAnimations:@"fading to game second" context:NULL];
       
   112         [UIView setAnimationDuration:1];
       
   113         secondBlackView.alpha = 1;
       
   114         [UIView commitAnimations];
       
   115         [secondBlackView release];
       
   116     }
       
   117     [blackView release];
       
   118 
       
   119 
       
   120     // pull out useful configuration info from various files
       
   121     GameSetup *setup = [[GameSetup alloc] initWithDictionary:gameDictionary];
       
   122     NSNumber *isNetGameNum = [gameDictionary objectForKey:@"netgame"];
       
   123 
       
   124     [NSThread detachNewThreadSelector:@selector(engineProtocol)
       
   125                              toTarget:setup
       
   126                            withObject:nil];
       
   127 
       
   128     NSNumber *menuStyle = [NSNumber numberWithBool:setup.menuStyle];
       
   129     NSNumber *orientation = [[gameDictionary objectForKey:@"game_dictionary"] objectForKey:@"orientation"];
       
   130     NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:
       
   131                           isNetGameNum,@"net",
       
   132                           menuStyle,@"menu",
       
   133                           orientation,@"orientation",
       
   134                           nil];
       
   135     [self performSelector:@selector(displayOverlayLater:) withObject:dict afterDelay:1];
       
   136 
       
   137     // need to set again [gameDictionary objectForKey:@"savefile"] because if it's empty it means it's a normal game
       
   138     const char **gameArgs = [setup getGameSettings:[gameDictionary objectForKey:@"savefile"]];
       
   139     self.isInGame = YES;
       
   140     // this is the pascal fuction that starts the game
       
   141     Game(gameArgs);
       
   142     self.isInGame = NO;
       
   143     free(gameArgs);
       
   144 
       
   145     NSArray *stats = setup.statsArray;
       
   146     [setup release];
       
   147 
       
   148 
       
   149     [self.uiwindow makeKeyAndVisible];
       
   150     [self.uiwindow bringSubviewToFront:self.mainViewController.view];
       
   151 
       
   152     UIView *refBlackView = [gameWindow viewWithTag:BLACKVIEW_TAG];
       
   153     UIView *refSecondBlackView = [self.uiwindow viewWithTag:SECONDBLACKVIEW_TAG];
       
   154     [UIView beginAnimations:@"fading in from ingame" context:NULL];
       
   155     [UIView setAnimationDuration:1];
       
   156     refBlackView.alpha = 0;
       
   157     refSecondBlackView.alpha = 0;
       
   158     [UIView commitAnimations];
       
   159     [refBlackView performSelector:@selector(removeFromSuperview) withObject:nil afterDelay:1];
       
   160     [refSecondBlackView performSelector:@selector(removeFromSuperview) withObject:nil afterDelay:2];
       
   161 
       
   162     return stats;
       
   163 }
       
   164 
       
   165 // overlay with controls, become visible later, with a transparency effect since the sdlwindow is not yet created
       
   166 -(void) displayOverlayLater:(id) object {
       
   167     NSDictionary *dict = (NSDictionary *)object;
       
   168     self.overlayController = [[OverlayViewController alloc] initWithNibName:@"OverlayViewController" bundle:nil];
       
   169     self.overlayController.isNetGame = [[dict objectForKey:@"net"] boolValue];
       
   170     self.overlayController.useClassicMenu = [[dict objectForKey:@"menu"] boolValue];
       
   171     self.overlayController.initialOrientation = [[dict objectForKey:@"orientation"] intValue];
       
   172 
       
   173     UIWindow *gameWindow;
       
   174     if (IS_DUALHEAD())
       
   175         gameWindow = self.uiwindow;
       
   176     else
       
   177         gameWindow = [[UIApplication sharedApplication] keyWindow];
       
   178     [gameWindow addSubview:self.overlayController.view];
       
   179 }
       
   180 
       
   181 // override the direct execution of SDL_main to allow us to implement our own frontend
       
   182 -(void) postFinishLaunch {
       
   183     [[UIApplication sharedApplication] setStatusBarHidden:YES];
       
   184     [Appirater appLaunched];
       
   185 
       
   186     self.uiwindow = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
       
   187 
       
   188     if (IS_IPAD())
       
   189         self.mainViewController = [[MainMenuViewController alloc] initWithNibName:@"MainMenuViewController-iPad" bundle:nil];
       
   190     else
       
   191         self.mainViewController = [[MainMenuViewController alloc] initWithNibName:@"MainMenuViewController-iPhone" bundle:nil];
       
   192 
       
   193     [self.uiwindow addSubview:self.mainViewController.view];
       
   194     [self.mainViewController release];
       
   195     self.uiwindow.backgroundColor = [UIColor blackColor];
       
   196     [self.uiwindow makeKeyAndVisible];
       
   197 
       
   198     // check for dual monitor support
       
   199     if (IS_DUALHEAD()) {
       
   200         DLog(@"dual head mode ftw");
       
   201         self.secondWindow = [[UIWindow alloc] initWithFrame:[[[UIScreen screens] objectAtIndex:1] bounds]];
       
   202         self.secondWindow.backgroundColor = [UIColor blackColor];
       
   203         self.secondWindow.screen = [[UIScreen screens] objectAtIndex:1];
       
   204         UIImage *titleImage = [UIImage imageWithContentsOfFile:@"title.png"];
       
   205         UIImageView *titleView = [[UIImageView alloc] initWithImage:titleImage];
       
   206         titleView.center = self.secondWindow.center;
       
   207         [self.secondWindow addSubview:titleView];
       
   208         [titleView release];
       
   209         [self.secondWindow makeKeyAndVisible];
       
   210     }
       
   211 }
       
   212 
       
   213 -(void) applicationWillTerminate:(UIApplication *)application {
       
   214     if (self.isInGame)
       
   215         HW_terminate(YES);
       
   216 
       
   217     [super applicationWillTerminate:application];
       
   218 }
       
   219 
       
   220 -(void) applicationDidReceiveMemoryWarning:(UIApplication *)application {
       
   221     // don't clean mainMenuViewController here!!!
       
   222     MSG_MEMCLEAN();
       
   223     print_free_memory();
       
   224 }
       
   225 
       
   226 -(void) applicationWillResignActive:(UIApplication *)application {
       
   227     [super applicationWillResignActive: application];
       
   228 
       
   229     UIDevice* device = [UIDevice currentDevice];
       
   230     if ([device respondsToSelector:@selector(isMultitaskingSupported)] &&
       
   231          device.multitaskingSupported &&
       
   232          self.isInGame) {
       
   233         // let's try to be permissive with multitasking here...
       
   234         NSDictionary *settings = [[NSDictionary alloc] initWithContentsOfFile:SETTINGS_FILE()];
       
   235         if ([[settings objectForKey:@"multitasking"] boolValue])
       
   236             HW_suspend();
       
   237         else {
       
   238             // so the game returns to the configuration view
       
   239             if (isGameRunning())
       
   240                 HW_terminate(NO);
       
   241             else {
       
   242                 // while screen is loading you can't call HW_terminate() so we close the app
       
   243                 [self applicationWillTerminate:application];
       
   244             }
       
   245         }
       
   246         [settings release];
       
   247     }
       
   248 }
       
   249 
       
   250 -(void) applicationDidBecomeActive:(UIApplication *)application {
       
   251     [super applicationDidBecomeActive:application];
       
   252 
       
   253     UIDevice* device = [UIDevice currentDevice];
       
   254     if ([device respondsToSelector:@selector(isMultitaskingSupported)] &&
       
   255          device.multitaskingSupported &&
       
   256          self.isInGame) {
       
   257         HW_resume();
       
   258     }
       
   259 }
       
   260 
       
   261 @end