# HG changeset patch # User koda # Date 1314063977 -7200 # Node ID 99083392cd4f5d5bde5772f4aa23da28ec233f48 # Parent 1647244b3ffe6adc88b0d7412952ffd501c5581a FREE AT LAST!!! SDL came around a (mostly) sane way for implementing rotation events, so we can scrap all the workaround code that has been added to workaround it!! Also this allows us to use proper (internal) multitasking handling and can simplify optional settings and other yet unexplored features. Yay! diff -r 1647244b3ffe -r 99083392cd4f hedgewars/PascalExports.pas --- a/hedgewars/PascalExports.pas Mon Aug 22 23:56:25 2011 +0200 +++ b/hedgewars/PascalExports.pas Tue Aug 23 03:46:17 2011 +0200 @@ -36,7 +36,6 @@ implementation {$IFDEF HWLIBRARY} var cZoomVal: GLfloat; - previousGameState: TGameState; // retrieve protocol information procedure HW_versionInfo(netProto: PLongInt; versionStr: PPChar); cdecl; export; @@ -185,17 +184,6 @@ exit( isPaused ); end; -procedure HW_suspend; cdecl; export; -begin - previousGameState:= GameState; - GameState:= gsSuspend; -end; - -procedure HW_resume; cdecl; export; -begin - GameState:= previousGameState; -end; - // equivalent to esc+y; when closeFrontend = true the game exits after memory cleanup procedure HW_terminate(closeFrontend: boolean); cdecl; export; begin diff -r 1647244b3ffe -r 99083392cd4f hedgewars/hwengine.pas --- a/hedgewars/hwengine.pas Mon Aug 22 23:56:25 2011 +0200 +++ b/hedgewars/hwengine.pas Tue Aug 23 03:46:17 2011 +0200 @@ -100,7 +100,6 @@ gsExit: begin isTerminated:= true; end; - gsSuspend: exit; end; {$IFDEF SDL13} diff -r 1647244b3ffe -r 99083392cd4f hedgewars/uStore.pas --- a/hedgewars/uStore.pas Mon Aug 22 23:56:25 2011 +0200 +++ b/hedgewars/uStore.pas Tue Aug 23 03:46:17 2011 +0200 @@ -1002,7 +1002,8 @@ x:= x or (SDL_GetNumVideoDisplays() - 1); y:= y or (SDL_GetNumVideoDisplays() - 1); - flags:= flags or SDL_WINDOW_BORDERLESS; // do not use SDL_WINDOW_RESIZABLE on ios (yet) + SDL_SetHint('SDL_IOS_ORIENTATIONS','LandscapeLeft LandscapeRight'); + flags:= flags or SDL_WINDOW_BORDERLESS or SDL_WINDOW_RESIZABLE; {$ENDIF} SDLwindow:= SDL_CreateWindow('Hedgewars', x, y, cScreenWidth, cScreenHeight, flags); diff -r 1647244b3ffe -r 99083392cd4f hedgewars/uTypes.pas --- a/hedgewars/uTypes.pas Mon Aug 22 23:56:25 2011 +0200 +++ b/hedgewars/uTypes.pas Tue Aug 23 03:46:17 2011 +0200 @@ -36,7 +36,7 @@ end; // Possible states of the game - TGameState = (gsLandGen, gsStart, gsGame, gsChat, gsConfirm, gsExit, gsSuspend); + TGameState = (gsLandGen, gsStart, gsGame, gsChat, gsConfirm, gsExit); // Game types that help determining what the engine is actually supposed to do TGameType = (gmtLocal, gmtDemo, gmtNet, gmtSave, gmtLandPreview, gmtSyntax); diff -r 1647244b3ffe -r 99083392cd4f project_files/HedgewarsMobile/Classes/AmmoMenuViewController.m --- a/project_files/HedgewarsMobile/Classes/AmmoMenuViewController.m Mon Aug 22 23:56:25 2011 +0200 +++ b/project_files/HedgewarsMobile/Classes/AmmoMenuViewController.m Tue Aug 23 03:46:17 2011 +0200 @@ -69,14 +69,7 @@ if (placingPoint.x == -1 || placingPoint.y == -1) placingPoint = container.center; - if (IS_DUALHEAD() == YES) { - UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation]; - if (orientation == UIDeviceOrientationLandscapeLeft || orientation == UIDeviceOrientationLandscapeRight) - self.view.center = CGPointMake(placingPoint.y, placingPoint.x); - else - self.view.center = CGPointMake(placingPoint.x, placingPoint.y); - } else - self.view.center = CGPointMake(placingPoint.y, placingPoint.x); + self.view.center = placingPoint; self.isVisible = YES; if (IS_IPAD() == NO) @@ -87,8 +80,7 @@ if (self.isVisible) [self.view removeFromSuperview]; self.isVisible = NO; - placingPoint.x = self.view.center.y; - placingPoint.y = self.view.center.x; + placingPoint = self.view.center; if (IS_IPAD() == NO) HW_pauseToggle(); } diff -r 1647244b3ffe -r 99083392cd4f project_files/HedgewarsMobile/Classes/CommodityFunctions.h --- a/project_files/HedgewarsMobile/Classes/CommodityFunctions.h Mon Aug 22 23:56:25 2011 +0200 +++ b/project_files/HedgewarsMobile/Classes/CommodityFunctions.h Tue Aug 23 03:46:17 2011 +0200 @@ -63,6 +63,7 @@ #define IS_NOT_VERY_POWERFUL(x) ([x hasPrefix:@"iPad1"] || [x hasPrefix:@"iPhone2"] || [x hasPrefix:@"iPod3"] || [x hasPrefix:@"iPod4"]) #define IS_VERY_POWERFUL(x) (IS_NOT_POWERFUL(x) == NO && IS_NOT_VERY_POWERFUL(x) == NO) +#define UIVIEW_HW_SDLVIEW [[[[UIApplication sharedApplication] keyWindow] subviews] objectAtIndex:0] void print_free_memory (void); void playSound (NSString *snd); diff -r 1647244b3ffe -r 99083392cd4f project_files/HedgewarsMobile/Classes/CreationChamber.m --- a/project_files/HedgewarsMobile/Classes/CreationChamber.m Mon Aug 22 23:56:25 2011 +0200 +++ b/project_files/HedgewarsMobile/Classes/CreationChamber.m Tue Aug 23 03:46:17 2011 +0200 @@ -28,7 +28,6 @@ [settings setObject:[NSNumber numberWithBool:YES] forKey:@"music"]; [settings setObject:[NSNumber numberWithBool:YES] forKey:@"sound"]; [settings setObject:[NSNumber numberWithBool:NO] forKey:@"classic_menu"]; - [settings setObject:[NSNumber numberWithBool:YES] forKey:@"multitasking"]; [settings setObject:[NSNumber numberWithBool:YES] forKey:@"sync_ws"]; // limit graphic usage on older devices diff -r 1647244b3ffe -r 99083392cd4f project_files/HedgewarsMobile/Classes/GameInterfaceBridge.m --- a/project_files/HedgewarsMobile/Classes/GameInterfaceBridge.m Mon Aug 22 23:56:25 2011 +0200 +++ b/project_files/HedgewarsMobile/Classes/GameInterfaceBridge.m Tue Aug 23 03:46:17 2011 +0200 @@ -55,16 +55,16 @@ #pragma mark - // overlay with controls, become visible later, with a transparency effect since the sdlwindow is not yet created -(void) displayOverlayLater:(id) object { - [self.overlayController setInitialOrientation:self.parentController.interfaceOrientation]; - - UIWindow *gameWindow = (IS_DUALHEAD() ? [HedgewarsAppDelegate sharedAppDelegate].uiwindow : [[UIApplication sharedApplication] keyWindow]); - [gameWindow addSubview:self.overlayController.view]; + // in order to get rotation events we have to insert the view inside the first view of the second window + // when multihead we have to make sure that overlay is displayed in the touch-enabled window + UIView *injected = (IS_DUALHEAD() ? self.parentController.view : UIVIEW_HW_SDLVIEW); + [injected addSubview:self.overlayController.view]; } // main routine for calling the actual game engine -(void) startGameEngine { const char *gameArgs[11]; - NSInteger width, height, orientation; + NSInteger width, height; NSString *ipcString = [[NSString alloc] initWithFormat:@"%d", self.ipcPort]; NSString *localeString = [[NSString alloc] initWithFormat:@"%@.txt", [[NSLocale currentLocale] objectForKey:NSLocaleLanguageCode]]; NSUserDefaults *settings = [NSUserDefaults standardUserDefaults]; @@ -73,17 +73,15 @@ CGRect screenBounds = [[[UIScreen screens] objectAtIndex:1] bounds]; width = (int) screenBounds.size.width; height = (int) screenBounds.size.height; - orientation = 0; } else { CGRect screenBounds = [[UIScreen mainScreen] bounds]; width = (int) screenBounds.size.height; height = (int) screenBounds.size.width; - orientation = (self.parentController.interfaceOrientation == UIDeviceOrientationLandscapeLeft) ? -90 : 90; } NSString *horizontalSize = [[NSString alloc] initWithFormat:@"%d", width]; NSString *verticalSize = [[NSString alloc] initWithFormat:@"%d", height]; - NSString *rotation = [[NSString alloc] initWithFormat:@"%d", orientation]; + NSString *rotation = [[NSString alloc] initWithString:@"0"]; BOOL enhanced = [[settings objectForKey:@"enhanced"] boolValue]; NSString *modelId = getModelType(); diff -r 1647244b3ffe -r 99083392cd4f project_files/HedgewarsMobile/Classes/GeneralSettingsViewController.m --- a/project_files/HedgewarsMobile/Classes/GeneralSettingsViewController.m Mon Aug 22 23:56:25 2011 +0200 +++ b/project_files/HedgewarsMobile/Classes/GeneralSettingsViewController.m Tue Aug 23 03:46:17 2011 +0200 @@ -90,9 +90,6 @@ case 70: //enhanced graphics [settings setObject:[NSNumber numberWithBool:theSwitch.on] forKey:@"enhanced"]; break; - case 80: //nomultitasking - [settings setObject:[NSNumber numberWithBool:theSwitch.on] forKey:@"multitasking"]; - break; case 60: //classic menu [settings setObject:[NSNumber numberWithBool:theSwitch.on] forKey:@"classic_menu"]; break; @@ -240,12 +237,6 @@ switchContent.tag = 90; break; case 2: - cell.textLabel.text = NSLocalizedString(@"Multitasking", @""); - cell.detailTextLabel.text = NSLocalizedString(@"Disable it in case of issues when returing in game", @""); - switchContent.on = [[settings objectForKey:@"multitasking"] boolValue]; - switchContent.tag = 80; - break; - case 3: cell.textLabel.text = NSLocalizedString(@"Enanched Graphics", @""); cell.detailTextLabel.text = NSLocalizedString(@"Beware that the game will consume more memory", @""); switchContent.on = [[settings objectForKey:@"enhanced"] boolValue]; @@ -254,7 +245,7 @@ if (IS_NOT_POWERFUL(getModelType())) switchContent.enabled = NO; break; - case 4: + case 3: cell.textLabel.text = NSLocalizedString(@"Classic Ammo Menu", @""); cell.detailTextLabel.text = NSLocalizedString(@"Select which style of ammo menu you prefer",@""); switchContent.on = [[settings objectForKey:@"classic_menu"] boolValue]; diff -r 1647244b3ffe -r 99083392cd4f project_files/HedgewarsMobile/Classes/HedgewarsAppDelegate.m --- a/project_files/HedgewarsMobile/Classes/HedgewarsAppDelegate.m Mon Aug 22 23:56:25 2011 +0200 +++ b/project_files/HedgewarsMobile/Classes/HedgewarsAppDelegate.m Tue Aug 23 03:46:17 2011 +0200 @@ -122,54 +122,23 @@ } } --(void) applicationWillTerminate:(UIApplication *)application { - if (self.isInGame) - HW_terminate(YES); - - [super applicationWillTerminate:application]; -} - -(void) applicationDidReceiveMemoryWarning:(UIApplication *)application { + // don't stop music when it is playing + if (self.isInGame) { + [self.backgroundMusic stop]; + releaseAndNil(self.backgroundMusic); + MSG_MEMCLEAN(); + } + print_free_memory(); // don't clean mainMenuViewController here!!! - [self.backgroundMusic stop]; - self.backgroundMusic = nil; - MSG_MEMCLEAN(); - print_free_memory(); } -//TODO: when the SDLUIKitDelegate methods applicationWillResignActive and applicationDidBecomeActive do work -// you'll be able to remove the methods below and just handle the SDL_WINDOWEVENT_MINIMIZED/SDL_WINDOWEVENT_RESTORED -// events in the MainLoop - -(void) applicationWillResignActive:(UIApplication *)application { - //[super applicationWillResignActive:application]; - - UIDevice *device = [UIDevice currentDevice]; - if ([device respondsToSelector:@selector(isMultitaskingSupported)] && - [device isMultitaskingSupported] && self.isInGame) { - // let's try to be permissive with multitasking here... - if ([[[NSUserDefaults standardUserDefaults] objectForKey:@"multitasking"] boolValue]) - HW_suspend(); - else { - // so the game returns to the configuration view - if (isGameRunning()) - HW_terminate(NO); - else { - // while screen is loading you can't call HW_terminate() so we close the app - [self applicationWillTerminate:application]; - } - } - } + // true multitasking with sdl works only on 4.2 and above; we close the game to avoid a black screen at return + if (self.isInGame && ([[[UIDevice currentDevice] systemVersion] floatValue] < 4.2f)) + HW_terminate(NO); + [super applicationWillResignActive:application]; } --(void) applicationDidBecomeActive:(UIApplication *)application { - //[super applicationDidBecomeActive:application]; - - UIDevice *device = [UIDevice currentDevice]; - if ([device respondsToSelector:@selector(isMultitaskingSupported)] && - [device isMultitaskingSupported] && self.isInGame) { - HW_resume(); - } -} @end diff -r 1647244b3ffe -r 99083392cd4f project_files/HedgewarsMobile/Classes/InGameMenuViewController.m --- a/project_files/HedgewarsMobile/Classes/InGameMenuViewController.m Mon Aug 22 23:56:25 2011 +0200 +++ b/project_files/HedgewarsMobile/Classes/InGameMenuViewController.m Tue Aug 23 03:46:17 2011 +0200 @@ -162,21 +162,12 @@ break; case 3: - // expand the view (and table) so that the actionsheet can be selected on the iPhone - if (IS_IPAD() == NO) { - CGRect screen = [[UIScreen mainScreen] bounds]; - [self.tableView deselectRowAtIndexPath:indexPath animated:NO]; - [UIView beginAnimations:@"table width more" context:NULL]; - [UIView setAnimationDuration:0.2]; - self.view.frame = CGRectMake(0, 0, screen.size.height, screen.size.width); - [UIView commitAnimations]; - } actionSheet = [[UIActionSheet alloc] initWithTitle:NSLocalizedString(@"Are you reeeeeally sure?", @"") delegate:self cancelButtonTitle:NSLocalizedString(@"Well, maybe not...", @"") destructiveButtonTitle:NSLocalizedString(@"Of course!", @"") otherButtonTitles:nil]; - [actionSheet showInView:self.view]; + [actionSheet showInView:(IS_IPAD() ? self.view : UIVIEW_HW_SDLVIEW)]; [actionSheet release]; break; @@ -191,20 +182,13 @@ #pragma mark - #pragma mark actionSheet methods -(void) actionSheet:(UIActionSheet *)actionSheet didDismissWithButtonIndex:(NSInteger) buttonIndex { - if (IS_IPAD() == NO) { - CGRect screen = [[UIScreen mainScreen] bounds]; - [UIView beginAnimations:@"table width less" context:NULL]; - [UIView setAnimationDuration:0.2]; - self.view.frame = CGRectMake(screen.size.height-200, 0, 200, VIEW_HEIGHT); - [UIView commitAnimations]; - } - if ([actionSheet cancelButtonIndex] != buttonIndex) { SDL_iPhoneKeyboardHide((SDL_Window *)HW_getSDLWindow()); HW_terminate(NO); } } +//TODO: check this is still needed since we switched to SDL_GL_CreateContext() #pragma mark - #pragma mark save screenshot //by http://www.bit-101.com/blog/?p=1861 diff -r 1647244b3ffe -r 99083392cd4f project_files/HedgewarsMobile/Classes/ObjcExports.m --- a/project_files/HedgewarsMobile/Classes/ObjcExports.m Mon Aug 22 23:56:25 2011 +0200 +++ b/project_files/HedgewarsMobile/Classes/ObjcExports.m Tue Aug 23 03:46:17 2011 +0200 @@ -67,8 +67,7 @@ overlay_instance.lowerIndicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge]; CGPoint center = overlay_instance.view.center; - overlay_instance.lowerIndicator.center = (IS_DUALHEAD() ? CGPointMake(center.y, center.x) - : CGPointMake(center.y, center.x * 5/3)); + overlay_instance.lowerIndicator.center = (IS_DUALHEAD() ? center : CGPointMake(center.x, center.y * 5/3)); [overlay_instance.lowerIndicator startAnimating]; [overlay_instance.view addSubview:overlay_instance.lowerIndicator]; @@ -110,8 +109,7 @@ overlay_instance.savesIndicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge]; - CGPoint center = overlay_instance.view.center; - overlay_instance.savesIndicator.center = CGPointMake(center.y, center.x); + overlay_instance.savesIndicator.center = overlay_instance.view.center; overlay_instance.savesIndicator.hidesWhenStopped = YES; [overlay_instance.savesIndicator startAnimating]; diff -r 1647244b3ffe -r 99083392cd4f project_files/HedgewarsMobile/Classes/OverlayViewController.h --- a/project_files/HedgewarsMobile/Classes/OverlayViewController.h Mon Aug 22 23:56:25 2011 +0200 +++ b/project_files/HedgewarsMobile/Classes/OverlayViewController.h Tue Aug 23 03:46:17 2011 +0200 @@ -45,9 +45,6 @@ CGPoint startingPoint; BOOL isAttacking; - // stuff initialized externally - NSInteger initialOrientation; - // dual head support NSInteger initialScreenCount; @@ -67,7 +64,6 @@ @property (nonatomic,retain) UIButton *confirmButton; @property (nonatomic,retain) UISegmentedControl *grenadeTimeSegment; -@property (assign) NSInteger initialOrientation; @property (assign) NSInteger initialScreenCount; diff -r 1647244b3ffe -r 99083392cd4f project_files/HedgewarsMobile/Classes/OverlayViewController.m --- a/project_files/HedgewarsMobile/Classes/OverlayViewController.m Mon Aug 22 23:56:25 2011 +0200 +++ b/project_files/HedgewarsMobile/Classes/OverlayViewController.m Tue Aug 23 03:46:17 2011 +0200 @@ -35,8 +35,8 @@ @implementation OverlayViewController -@synthesize popoverController, popupMenu, helpPage, amvc, initialScreenCount, initialOrientation, - lowerIndicator, savesIndicator, confirmButton, grenadeTimeSegment; +@synthesize popoverController, popupMenu, helpPage, amvc, initialScreenCount, lowerIndicator, savesIndicator, + confirmButton, grenadeTimeSegment; #pragma mark - #pragma mark rotation @@ -45,48 +45,6 @@ return rotationManager(interfaceOrientation); } -// while in dual head the above rotation functions are not called --(void) handleRotationEvent:(NSNotification *)notification { - if (isGameRunning() == NO) - return; - - UIView *sdlView = nil; - for (UIView *oneView in [[[UIApplication sharedApplication] keyWindow] subviews]) - if ([oneView isMemberOfClass:[SDL_uikitopenglview class]]) { - sdlView = (UIView *)oneView; - break; - } - - UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation]; - NSInteger angle_left = (self.initialOrientation == UIInterfaceOrientationLandscapeLeft) ? 180 : 0; - NSInteger angle_right = (self.initialOrientation == UIInterfaceOrientationLandscapeLeft) ? 0 : 180; - - NSString *model = getModelType(); - if (IS_VERY_POWERFUL(model)) { - [UIView beginAnimations:@"overlay rotation" context:NULL]; - [UIView setAnimationDuration:0.7]; - } - switch (orientation) { - case UIDeviceOrientationLandscapeLeft: - self.view.frame = [[UIScreen mainScreen] bounds]; - self.view.transform = CGAffineTransformMakeRotation(degreesToRadians(90)); - if (IS_DUALHEAD() == NO) - sdlView.transform = CGAffineTransformMakeRotation(degreesToRadians(angle_left)); - break; - case UIDeviceOrientationLandscapeRight: - self.view.frame = [[UIScreen mainScreen] bounds]; - self.view.transform = CGAffineTransformMakeRotation(degreesToRadians(-90)); - if (IS_DUALHEAD() == NO) - sdlView.transform = CGAffineTransformMakeRotation(degreesToRadians(angle_right)); - break; - default: - // a debug log would spam too much - break; - } - if (IS_VERY_POWERFUL(model)) - [UIView commitAnimations]; -} - #pragma mark - #pragma mark View Management -(id) initWithCoder:(NSCoder *)aDecoder { @@ -94,7 +52,6 @@ isAttacking = NO; isPopoverVisible = NO; initialScreenCount = (IS_DUALHEAD() ? 2 : 1); - initialOrientation = 0; lowerIndicator = nil; savesIndicator = nil; } @@ -102,27 +59,10 @@ } -(void) viewDidLoad { - CGRect screenRect = [[UIScreen mainScreen] bounds]; - self.view.frame = CGRectMake(0, 0, screenRect.size.height, screenRect.size.width); - self.view.center = CGPointMake(self.view.frame.size.height/2, self.view.frame.size.width/2); + // fill all the screen available as sdlview disables autoresizing + CGRect rect = [[UIScreen mainScreen] bounds]; + self.view.frame = CGRectMake(0, 0, rect.size.height, rect.size.width); - // set initial orientation of the controller orientation - switch (self.interfaceOrientation) { - case UIDeviceOrientationLandscapeLeft: - self.view.transform = CGAffineTransformMakeRotation(degreesToRadians(90)); - break; - case UIDeviceOrientationLandscapeRight: - self.view.transform = CGAffineTransformMakeRotation(degreesToRadians(-90)); - break; - default: - break; - } - [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications]; - [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(handleRotationEvent:) - name:UIDeviceOrientationDidChangeNotification - object:nil]; - // the timer used to dim the overlay dimTimer = [[NSTimer alloc] initWithFireDate:(IS_DUALHEAD()) ? HIDING_TIME_NEVER : [NSDate dateWithTimeIntervalSinceNow:6] interval:1000 @@ -139,8 +79,7 @@ name:@"show help ingame" object:nil]; - // for iOS >= 3.2 - if ([UIScreen respondsToSelector:@selector(screens)]) { + if (IS_IPAD()) { [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(numberOfScreensIncreased) name:UIScreenDidConnectNotification @@ -161,7 +100,6 @@ } -(void) viewDidUnload { - [[UIDevice currentDevice] endGeneratingDeviceOrientationNotifications]; [[NSNotificationCenter defaultCenter] removeObserver:self]; [NSObject cancelPreviousPerformRequestsWithTarget:self @@ -409,14 +347,6 @@ doNotDim(); } -// present a further check before closing game --(void) actionSheet:(UIActionSheet *)actionSheet didDismissWithButtonIndex:(NSInteger) buttonIndex { - if ([actionSheet cancelButtonIndex] != buttonIndex) - HW_terminate(NO); - else - HW_pause(); -} - // show up a popover containing a popupMenuViewController; we hook it with setPopoverContentSize // on iphone instead just use the tableViewController directly (and implement manually all animations) -(IBAction) showPopover{