unified the objc game state in a single place, which allowed some optimization to ObjcExport class (and more)
authorkoda
Mon, 31 Oct 2011 03:08:16 +0100
changeset 6247 6dfad55fd71c
parent 6246 6b2d19ed521a
child 6248 103bc8fd4f1b
unified the objc game state in a single place, which allowed some optimization to ObjcExport class (and more)
hedgewars/uGame.pas
hedgewars/uIO.pas
hedgewars/uMobile.pas
project_files/HedgewarsMobile/Classes/EngineProtocolNetwork.m
project_files/HedgewarsMobile/Classes/GameInterfaceBridge.h
project_files/HedgewarsMobile/Classes/GameInterfaceBridge.m
project_files/HedgewarsMobile/Classes/HWUtils.h
project_files/HedgewarsMobile/Classes/HWUtils.m
project_files/HedgewarsMobile/Classes/HedgewarsAppDelegate.h
project_files/HedgewarsMobile/Classes/HedgewarsAppDelegate.m
project_files/HedgewarsMobile/Classes/ObjcExports.h
project_files/HedgewarsMobile/Classes/ObjcExports.m
project_files/HedgewarsMobile/Classes/OverlayViewController.h
project_files/HedgewarsMobile/Classes/OverlayViewController.m
project_files/HedgewarsMobile/Classes/SchemeWeaponConfigViewController.m
project_files/HedgewarsMobile/Classes/TeamConfigViewController.m
--- a/hedgewars/uGame.pas	Mon Oct 31 01:44:32 2011 +0100
+++ b/hedgewars/uGame.pas	Mon Oct 31 03:08:16 2011 +0100
@@ -77,7 +77,7 @@
                         AddVisualGear(0, 0, vgtTeamHealthSorter);
                         AddVisualGear(0, 0, vgtSmoothWindBar);
                         {$IFDEF IPHONEOS}InitIPC;{$ENDIF}
-                        uMobile.SaveFinished();
+                        uMobile.SaveLoadingEnded();
                         end;
                end
           else ProcessGears
--- a/hedgewars/uIO.pas	Mon Oct 31 01:44:32 2011 +0100
+++ b/hedgewars/uIO.pas	Mon Oct 31 03:08:16 2011 +0100
@@ -40,7 +40,7 @@
 procedure doPut(putX, putY: LongInt; fromAI: boolean);
 
 implementation
-uses uConsole, uConsts, uVariables, uCommands, uUtils, uDebug, uMobile;
+uses uConsole, uConsts, uVariables, uCommands, uUtils, uDebug;
 
 type PCmd = ^TCmd;
      TCmd = packed record
@@ -175,8 +175,6 @@
     s: shortstring absolute buf;
 begin
 
-uMobile.SaveBegan();
-
 // set RDNLY on file open
 filemode:= 0;
 {$I-}
--- a/hedgewars/uMobile.pas	Mon Oct 31 01:44:32 2011 +0100
+++ b/hedgewars/uMobile.pas	Mon Oct 31 03:08:16 2011 +0100
@@ -24,11 +24,9 @@
 {$IFDEF IPHONEOS}
 (*  iOS calls written in ObjcExports.m  *)
 procedure clearView; cdecl; external;
-procedure startSpinningProgress; cdecl; external;
-procedure stopSpinningProgress; cdecl; external;
-procedure saveBeganSynching; cdecl; external;
+procedure startLoadingIndicator; cdecl; external;
+procedure stopLoadingIndicator; cdecl; external;
 procedure saveFinishedSynching; cdecl; external;
-procedure setGameRunning(arg: boolean); cdecl; external;
 procedure updateVisualsNewTurn; cdecl; external;
 function  isApplePhone: Boolean; cdecl; external;
 procedure AudioServicesPlaySystemSound(num: LongInt); cdecl; external;
@@ -40,8 +38,7 @@
 procedure GameLoaded; inline;
 procedure AmmoUpdate; // do not inline
 procedure NewTurnBeginning; inline;
-procedure SaveBegan; inline;
-procedure SaveFinished; inline;
+procedure SaveLoadingEnded; inline;
 
 implementation
 uses uVariables;
@@ -71,14 +68,14 @@
 procedure GameLoading; inline;
 begin
 {$IFDEF IPHONEOS}
-    startSpinningProgress();
+    startLoadingIndicator();
 {$ENDIF}
 end;
 
 procedure GameLoaded; inline;
 begin
 {$IFDEF IPHONEOS}
-    stopSpinningProgress();
+    stopLoadingIndicator();
 {$ENDIF}
 end;
 
@@ -101,14 +98,7 @@
     AmmoUpdate();
 end;
 
-procedure SaveBegan; inline;
-begin
-{$IFDEF IPHONEOS}
-    saveBeganSynching();
-{$ENDIF}
-end;
-
-procedure SaveFinished; inline;
+procedure SaveLoadingEnded; inline;
 begin
 {$IFDEF IPHONEOS}
     saveFinishedSynching();
--- a/project_files/HedgewarsMobile/Classes/EngineProtocolNetwork.m	Mon Oct 31 01:44:32 2011 +0100
+++ b/project_files/HedgewarsMobile/Classes/EngineProtocolNetwork.m	Mon Oct 31 03:08:16 2011 +0100
@@ -393,7 +393,7 @@
                 }
                 break;
             case 'q':
-                // game ended, can remove the savefile and the trailing overlay (when dualhead)
+                // game ended, can remove the savefile and present the statistics of the match
                 [self gameHasEndedWithStats:statsArray];
                 break;
             case 'Q':
--- a/project_files/HedgewarsMobile/Classes/GameInterfaceBridge.h	Mon Oct 31 01:44:32 2011 +0100
+++ b/project_files/HedgewarsMobile/Classes/GameInterfaceBridge.h	Mon Oct 31 03:08:16 2011 +0100
@@ -22,9 +22,6 @@
 #import <Foundation/Foundation.h>
 #import "EngineProtocolNetwork.h"
 
-typedef enum {gtNone, gtLocal, gtSave, gtMission, gtNet} TGameType;
-typedef enum {gsNone, gsInGame, gsEnded, gsInterrupted} TGameStatus;
-
 @class OverlayViewController;
 
 @interface GameInterfaceBridge : NSObject <EngineProtocolDelegate> {
@@ -35,7 +32,6 @@
     EngineProtocolNetwork *engineProtocol;
 
     NSInteger ipcPort;  // Port on which engine will listen
-    TGameType gameType;
 }
 
 @property (assign) UIViewController *parentController;
@@ -45,7 +41,6 @@
 @property (nonatomic,retain) EngineProtocolNetwork *engineProtocol;
 
 @property (assign) NSInteger ipcPort;
-@property (assign) TGameType gameType;
 
 
 -(id)   initWithController:(id) viewController;
--- a/project_files/HedgewarsMobile/Classes/GameInterfaceBridge.m	Mon Oct 31 01:44:32 2011 +0100
+++ b/project_files/HedgewarsMobile/Classes/GameInterfaceBridge.m	Mon Oct 31 03:08:16 2011 +0100
@@ -27,17 +27,15 @@
 #import "ObjcExports.h"
 
 @implementation GameInterfaceBridge
-@synthesize parentController, savePath, overlayController, engineProtocol, ipcPort, gameType;
+@synthesize parentController, savePath, overlayController, engineProtocol, ipcPort;
 
 -(id) initWithController:(id) viewController {
     if (self = [super init]) {
         self.ipcPort = [HWUtils randomPort];
-        self.gameType = gtNone;
         self.savePath = nil;
 
         self.parentController = (UIViewController *)viewController;
         self.engineProtocol = [[EngineProtocolNetwork alloc] initOnPort:self.ipcPort];
-        self.engineProtocol.delegate = self;
 
         self.overlayController = [[OverlayViewController alloc] initWithNibName:@"OverlayViewController" bundle:nil];
     }
@@ -113,7 +111,7 @@
     gameArgs[ 7] = [[[settings objectForKey:@"music"] stringValue] UTF8String];                 //isMusicEnabled
     gameArgs[ 8] = [[[settings objectForKey:@"alternate"] stringValue] UTF8String];             //cAltDamage
     gameArgs[ 9] = [rotation UTF8String];                                                       //rotateQt
-    gameArgs[10] = (self.gameType == gtSave) ? [self.savePath UTF8String] : NULL;               //recordFileName
+    gameArgs[10] = ([HWUtils gameType] == gtSave) ? [self.savePath UTF8String] : NULL;          //recordFileName
 
     [verticalSize release];
     [horizontalSize release];
@@ -121,12 +119,10 @@
     [localeString release];
     [ipcString release];
 
-    [ObjcExports initialize];
+    [HWUtils setGameStatus:gsLoading];
 
-    // this is the pascal fuction that starts the game, wrapped around isInGame
-    [HedgewarsAppDelegate sharedAppDelegate].isInGame = YES;
+    // this is the pascal fuction that starts the game
     Game(gameArgs);
-    [HedgewarsAppDelegate sharedAppDelegate].isInGame = NO;
 }
 
 // prepares the controllers for hosting a game
@@ -185,7 +181,7 @@
 
 // set up variables for a local game
 -(void) startLocalGame:(NSDictionary *)withOptions {
-    self.gameType = gtLocal;
+    [HWUtils setGameType:gtLocal];
 
     NSDateFormatter *outputFormatter = [[NSDateFormatter alloc] init];
     [outputFormatter setDateFormat:@"yyyy-MM-dd '@' HH.mm"];
@@ -204,16 +200,16 @@
 
 // set up variables for a save game
 -(void) startSaveGame:(NSString *)atPath {
-    self.gameType = gtSave;
     self.savePath = atPath;
+    [HWUtils setGameType:gtSave];
 
     [self.engineProtocol spawnThread:self.savePath];
     [self prepareEngineLaunch];
 }
 
 -(void) startMissionGame:(NSString *)withScript {
-    self.gameType = gtMission;
     self.savePath = nil;
+    [HWUtils setGameType:gtMission];
 
     NSString *missionPath = [[NSString alloc] initWithFormat:@"escript Missions/Training/%@.lua",withScript];
     NSDictionary *config = [NSDictionary dictionaryWithObject:missionPath forKey:@"mission_command"];
@@ -238,7 +234,7 @@
     }
 
     // can remove the savefile if the replay has ended
-    if (self.gameType == gtSave)
+    if ([HWUtils gameType] == gtSave)
         [[NSFileManager defaultManager] removeItemAtPath:self.savePath error:nil];
     [self release];
 }
--- a/project_files/HedgewarsMobile/Classes/HWUtils.h	Mon Oct 31 01:44:32 2011 +0100
+++ b/project_files/HedgewarsMobile/Classes/HWUtils.h	Mon Oct 31 03:08:16 2011 +0100
@@ -21,10 +21,20 @@
 
 #import <Foundation/Foundation.h>
 
+typedef enum {gtNone, gtLocal, gtSave, gtMission, gtNet} TGameType;
+typedef enum {gsNone, gsLoading, gsInGame, gsEnded} TGameStatus;
+
 @interface HWUtils : NSObject {
 
 }
 
++(TGameType) gameType;
++(void) setGameType:(TGameType) type;
++(TGameStatus) gameStatus;
++(void) setGameStatus:(TGameStatus) status;
++(BOOL) isGameLaunched;
++(BOOL) isGameRunning;
+
 +(NSString *)modelType;
 +(NSArray *)teamColors;
 +(NSInteger) randomPort;
--- a/project_files/HedgewarsMobile/Classes/HWUtils.m	Mon Oct 31 01:44:32 2011 +0100
+++ b/project_files/HedgewarsMobile/Classes/HWUtils.m	Mon Oct 31 03:08:16 2011 +0100
@@ -29,8 +29,39 @@
 static NSString *cachedModel = nil;
 static NSArray *cachedColors = nil;
 
+static TGameType gameType = gtNone;
+static TGameStatus gameStatus = gsNone;
+
 @implementation HWUtils
 
+#pragma mark -
+#pragma mark game status and type info
++(TGameType) gameType {
+    return gameType;
+}
+
++(void) setGameType:(TGameType) type {
+    gameType = type;
+}
+
++(TGameStatus) gameStatus {
+    return gameStatus;
+}
+
++(void) setGameStatus:(TGameStatus) status {
+    gameStatus = status;
+}
+
++(BOOL) isGameLaunched {
+    return ((gameStatus == gsLoading) || (gameStatus == gsInGame));
+}
+
++(BOOL) isGameRunning {
+    return (gameStatus == gsInGame);
+}
+
+#pragma mark -
+#pragma mark Helper Functions
 +(NSString *)modelType {
     if (cachedModel == nil) {
         size_t size;
--- a/project_files/HedgewarsMobile/Classes/HedgewarsAppDelegate.h	Mon Oct 31 01:44:32 2011 +0100
+++ b/project_files/HedgewarsMobile/Classes/HedgewarsAppDelegate.h	Mon Oct 31 03:08:16 2011 +0100
@@ -28,13 +28,11 @@
     MainMenuViewController *mainViewController;
     UIWindow *uiwindow;
     UIWindow *secondWindow;
-    BOOL isInGame;
 }
 
 @property (nonatomic,retain) MainMenuViewController *mainViewController;
 @property (nonatomic,retain) UIWindow *uiwindow;
 @property (nonatomic,retain) UIWindow *secondWindow;
-@property (assign) BOOL isInGame;
 
 +(HedgewarsAppDelegate *)sharedAppDelegate;
 
--- a/project_files/HedgewarsMobile/Classes/HedgewarsAppDelegate.m	Mon Oct 31 01:44:32 2011 +0100
+++ b/project_files/HedgewarsMobile/Classes/HedgewarsAppDelegate.m	Mon Oct 31 03:08:16 2011 +0100
@@ -34,7 +34,7 @@
 @end
 
 @implementation HedgewarsAppDelegate
-@synthesize mainViewController, uiwindow, secondWindow, isInGame;
+@synthesize mainViewController, uiwindow, secondWindow;
 
 // convenience method
 +(HedgewarsAppDelegate *)sharedAppDelegate {
@@ -48,7 +48,6 @@
         mainViewController = nil;
         uiwindow = nil;
         secondWindow = nil;
-        isInGame = NO;
     }
     return self;
 }
@@ -92,7 +91,7 @@
 -(void) applicationDidReceiveMemoryWarning:(UIApplication *)application {
     [HWUtils releaseCache];
     // don't stop music if it is playing
-    if (self.isInGame) {
+    if ([HWUtils isGameLaunched]) {
         [AudioManagerController releaseCache];
     }
     MSG_MEMCLEAN();
@@ -101,7 +100,7 @@
 
 // true multitasking with sdl works only on 4.2 and above; we close the game to avoid a black screen at return
 -(void) applicationWillResignActive:(UIApplication *)application {
-    if (self.isInGame && [[[UIDevice currentDevice] systemVersion] floatValue] < 4.2f)
+    if ([HWUtils isGameLaunched] && [[[UIDevice currentDevice] systemVersion] floatValue] < 4.2f)
          HW_terminate(NO);
 
     [super applicationWillResignActive:application];
--- a/project_files/HedgewarsMobile/Classes/ObjcExports.h	Mon Oct 31 01:44:32 2011 +0100
+++ b/project_files/HedgewarsMobile/Classes/ObjcExports.h	Mon Oct 31 03:08:16 2011 +0100
@@ -23,16 +23,13 @@
 
 }
 
-+(void) initialize;
++(void) setGrenadeTime:(NSInteger) value;
++(NSInteger) grenadeTime;
 
 @end
 
 
-BOOL isGameRunning(void);
-void setGameRunning(BOOL value);
-NSInteger cachedGrenadeTime(void);
 void clearView(void);
-void setGrenadeTime(NSInteger value);
 BOOL isApplePhone(void);
 
 void startSpinningProgress(void);
--- a/project_files/HedgewarsMobile/Classes/ObjcExports.m	Mon Oct 31 01:44:32 2011 +0100
+++ b/project_files/HedgewarsMobile/Classes/ObjcExports.m	Mon Oct 31 03:08:16 2011 +0100
@@ -24,10 +24,6 @@
 #import "AmmoMenuViewController.h"
 
 
-// actual game started (controls should be enabled)
-static BOOL gameRunning;
-// black screen present
-static BOOL savedGame;
 // cache the grenade time
 static NSInteger grenadeTime;
 // the reference to the newMenu instance
@@ -35,32 +31,16 @@
 
 @implementation ObjcExports
 
-+(void) initialize {
-    overlay_instance = [OverlayViewController mainOverlay];
-    gameRunning = NO;
-    savedGame = NO;
-    grenadeTime = 2;
++(void) setGrenadeTime:(NSInteger) value {
+    grenadeTime = value;
+}
+
++(NSInteger) grenadeTime {
+    return grenadeTime;
 }
 
 @end
 
-#pragma mark -
-#pragma mark functions called by objc code
-BOOL inline isGameRunning() {
-    return gameRunning;
-}
-
-void inline setGameRunning(BOOL value) {
-    gameRunning = value;
-}
-
-NSInteger cachedGrenadeTime() {
-    return grenadeTime;
-}
-
-void inline setGrenadeTime(NSInteger value) {
-    grenadeTime = value;
-}
 
 #pragma mark -
 #pragma mark functions called by pascal code
@@ -68,24 +48,51 @@
     return (IS_IPAD() == NO);
 }
 
-void startSpinningProgress() {
-    gameRunning = NO;
-    overlay_instance.lowerIndicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
+void startLoadingIndicator() {
+    // this is the first ojbc function called by engine, so we have to initialize some variables here
+    overlay_instance = [OverlayViewController mainOverlay];
+    grenadeTime = 2;
 
+    if ([HWUtils gameType] == gtSave) {
+        [[UIApplication sharedApplication] setIdleTimerDisabled:YES];
+
+        overlay_instance.view.backgroundColor = [UIColor blackColor];
+        overlay_instance.view.alpha = 0.75;
+        overlay_instance.view.userInteractionEnabled = NO;
+    }
     CGPoint center = overlay_instance.view.center;
-    overlay_instance.lowerIndicator.center = (IS_DUALHEAD() ? center : CGPointMake(center.x, center.y * 5/3));
+    CGPoint loaderCenter = ((IS_DUALHEAD() || [HWUtils gameType] == gtSave) ? center : CGPointMake(center.x, center.y * 5/3));
 
-    [overlay_instance.lowerIndicator startAnimating];
-    [overlay_instance.view addSubview:overlay_instance.lowerIndicator];
-    [overlay_instance.lowerIndicator release];
+    overlay_instance.loadingIndicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
+    overlay_instance.loadingIndicator.hidesWhenStopped = YES;
+    overlay_instance.loadingIndicator.center = loaderCenter;
+    [overlay_instance.loadingIndicator startAnimating];
+    [overlay_instance.view addSubview:overlay_instance.loadingIndicator];
+    [overlay_instance.loadingIndicator release];
 }
 
-void stopSpinningProgress() {
-    [overlay_instance.lowerIndicator stopAnimating];
-    [overlay_instance.lowerIndicator removeFromSuperview];
+void stopLoadingIndicator() {
     HW_zoomSet(1.7);
-    if (savedGame == NO)
-        gameRunning = YES;
+    if ([HWUtils gameType] != gtSave) {
+        [overlay_instance.loadingIndicator stopAnimating];
+        [overlay_instance.loadingIndicator removeFromSuperview];
+        [HWUtils setGameStatus:gsInGame];
+    }
+}
+
+void saveFinishedSynching() {
+    [UIView beginAnimations:@"fading from save synch" context:NULL];
+    [UIView setAnimationDuration:1];
+    overlay_instance.view.backgroundColor = [UIColor clearColor];
+    overlay_instance.view.alpha = 1;
+    overlay_instance.view.userInteractionEnabled = YES;
+    [UIView commitAnimations];
+
+    [overlay_instance.loadingIndicator stopAnimating];
+    [overlay_instance.loadingIndicator performSelector:@selector(removeFromSuperview) withObject:nil afterDelay:1];
+
+    [[UIApplication sharedApplication] setIdleTimerDisabled:NO];
+    [HWUtils setGameStatus:gsInGame];
 }
 
 void clearView() {
@@ -105,40 +112,6 @@
     grenadeTime = 2;
 }
 
-void saveBeganSynching() {
-    savedGame = YES;
-    stopSpinningProgress();
-    [[UIApplication sharedApplication] setIdleTimerDisabled:YES];
-
-    overlay_instance.view.backgroundColor = [UIColor blackColor];
-    overlay_instance.view.alpha = 0.75;
-    overlay_instance.view.userInteractionEnabled = NO;
-
-    overlay_instance.savesIndicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
-
-    overlay_instance.savesIndicator.center = overlay_instance.view.center;
-    overlay_instance.savesIndicator.hidesWhenStopped = YES;
-
-    [overlay_instance.savesIndicator startAnimating];
-    [overlay_instance.view addSubview:overlay_instance.savesIndicator];
-    [overlay_instance.savesIndicator release];
-}
-
-void saveFinishedSynching() {
-    [UIView beginAnimations:@"fading from save synch" context:NULL];
-    [UIView setAnimationDuration:1];
-    overlay_instance.view.backgroundColor = [UIColor clearColor];
-    overlay_instance.view.alpha = 1;
-    overlay_instance.view.userInteractionEnabled = YES;
-    [UIView commitAnimations];
-
-    [overlay_instance.savesIndicator stopAnimating];
-    [overlay_instance.savesIndicator performSelector:@selector(removeFromSuperview) withObject:nil afterDelay:1];
-
-    [[UIApplication sharedApplication] setIdleTimerDisabled:NO];
-    gameRunning = YES;
-}
-
 void updateVisualsNewTurn(void) {
     [overlay_instance.amvc updateAmmoVisuals];
 }
--- a/project_files/HedgewarsMobile/Classes/OverlayViewController.h	Mon Oct 31 01:44:32 2011 +0100
+++ b/project_files/HedgewarsMobile/Classes/OverlayViewController.h	Mon Oct 31 03:08:16 2011 +0100
@@ -49,8 +49,7 @@
     NSInteger initialScreenCount;
 
     // various other widgets
-    UIActivityIndicatorView *lowerIndicator;
-    UIActivityIndicatorView *savesIndicator;
+    UIActivityIndicatorView *loadingIndicator;
     UIButton *confirmButton;
     UISegmentedControl *grenadeTimeSegment;
 }
@@ -59,8 +58,7 @@
 @property (nonatomic,retain) InGameMenuViewController *popupMenu;
 @property (nonatomic,retain) HelpPageViewController *helpPage;
 @property (nonatomic,retain) AmmoMenuViewController *amvc;
-@property (nonatomic,retain) UIActivityIndicatorView *lowerIndicator;
-@property (nonatomic,retain) UIActivityIndicatorView *savesIndicator;
+@property (nonatomic,retain) UIActivityIndicatorView *loadingIndicator;
 @property (nonatomic,retain) UIButton *confirmButton;
 @property (nonatomic,retain) UISegmentedControl *grenadeTimeSegment;
 
--- a/project_files/HedgewarsMobile/Classes/OverlayViewController.m	Mon Oct 31 01:44:32 2011 +0100
+++ b/project_files/HedgewarsMobile/Classes/OverlayViewController.m	Mon Oct 31 03:08:16 2011 +0100
@@ -36,7 +36,7 @@
 static OverlayViewController *mainOverlay;
 
 @implementation OverlayViewController
-@synthesize popoverController, popupMenu, helpPage, amvc, initialScreenCount, lowerIndicator, savesIndicator,
+@synthesize popoverController, popupMenu, helpPage, amvc, initialScreenCount, loadingIndicator,
             confirmButton, grenadeTimeSegment;
 
 #pragma mark -
@@ -53,8 +53,7 @@
         isAttacking = NO;
         isPopoverVisible = NO;
         initialScreenCount = (IS_DUALHEAD() ? 2 : 1);
-        lowerIndicator = nil;
-        savesIndicator = nil;
+        loadingIndicator = nil;
         mainOverlay = self;
     }
     return self;
@@ -119,8 +118,7 @@
     [self dismissPopover];
     self.popoverController = nil;
     self.amvc = nil;
-    self.lowerIndicator = nil;
-    self.savesIndicator = nil;
+    self.loadingIndicator = nil;
     MSG_DIDUNLOAD();
     [super viewDidUnload];
 }
@@ -132,10 +130,8 @@
         self.helpPage = nil;
     if (self.amvc.view.superview == nil)
         self.amvc = nil;
-    if (self.lowerIndicator.superview == nil)
-        self.lowerIndicator = nil;
-    if (self.savesIndicator.superview == nil)
-        self.savesIndicator = nil;
+    if (self.loadingIndicator.superview == nil)
+        self.loadingIndicator = nil;
     if (self.confirmButton.superview == nil)
         self.confirmButton = nil;
     if (self.grenadeTimeSegment.superview == nil)
@@ -153,8 +149,7 @@
     releaseAndNil(helpPage);
     releaseAndNil(popoverController);
     releaseAndNil(amvc);
-    releaseAndNil(lowerIndicator);
-    releaseAndNil(savesIndicator);
+    releaseAndNil(loadingIndicator);
     releaseAndNil(confirmButton);
     releaseAndNil(grenadeTimeSegment);
     // dimTimer is autoreleased
@@ -191,7 +186,7 @@
 #pragma mark overlay appearance
 // nice transition for dimming, should be called only by the timer himself
 -(void) dimOverlay {
-    if (isGameRunning()) {
+    if ([HWUtils isGameRunning]) {
         [UIView beginAnimations:@"overlay dim" context:NULL];
         [UIView setAnimationDuration:0.6];
         self.view.alpha = 0.2;
@@ -215,7 +210,7 @@
 #pragma mark overlay user interaction
 // dim the overlay when there's no more input for a certain amount of time
 -(IBAction) buttonReleased:(id) sender {
-    if (isGameRunning() == NO)
+    if ([HWUtils isGameRunning] == NO)
         return;
 
     UIButton *theButton = (UIButton *)sender;
@@ -248,7 +243,7 @@
 -(IBAction) buttonPressed:(id) sender {
     [self activateOverlay];
     
-    if (isGameRunning() == NO)
+    if ([HWUtils isGameRunning] == NO)
         return;
     
     if (isPopoverVisible)
@@ -333,9 +328,9 @@
 
 -(void) setGrenadeTime:(id) sender {
     UISegmentedControl *theSegment = (UISegmentedControl *)sender;
-    if (cachedGrenadeTime() != theSegment.selectedSegmentIndex) {
+    if ([ObjcExports grenadeTime] != theSegment.selectedSegmentIndex) {
         HW_setGrenadeTime(theSegment.selectedSegmentIndex + 1);
-        setGrenadeTime(theSegment.selectedSegmentIndex);
+        [ObjcExports setGrenadeTime:theSegment.selectedSegmentIndex];
     }
 }
 
@@ -401,7 +396,7 @@
 #pragma mark -
 #pragma mark Custom touch event handling
 -(BOOL) shouldIgnoreTouch:(NSSet *)allTouches {
-    if (isGameRunning() == NO)
+    if ([HWUtils isGameRunning] == NO)
         return YES;
 
     // ignore activity near the dpad and buttons
@@ -512,7 +507,7 @@
                                 [grenadeSegment release];
                             }
                             self.grenadeTimeSegment.frame = CGRectMake(screen.size.height / 2 - 125, screen.size.width, 250, 50);
-                            self.grenadeTimeSegment.selectedSegmentIndex = cachedGrenadeTime();
+                            self.grenadeTimeSegment.selectedSegmentIndex = [ObjcExports grenadeTime];
                             self.grenadeTimeSegment.alpha = 1;
                             [self.view addSubview:self.grenadeTimeSegment];
 
--- a/project_files/HedgewarsMobile/Classes/SchemeWeaponConfigViewController.m	Mon Oct 31 01:44:32 2011 +0100
+++ b/project_files/HedgewarsMobile/Classes/SchemeWeaponConfigViewController.m	Mon Oct 31 03:08:16 2011 +0100
@@ -329,7 +329,7 @@
 #pragma mark -
 #pragma mark Memory management
 -(void) didReceiveMemoryWarning {
-    if ([[HedgewarsAppDelegate sharedAppDelegate] isInGame]) {
+    if ([HWUtils isGameLaunched]) {
         self.tableView = nil;
         self.lastIndexPath_sc = nil;
         self.lastIndexPath_we = nil;
--- a/project_files/HedgewarsMobile/Classes/TeamConfigViewController.m	Mon Oct 31 01:44:32 2011 +0100
+++ b/project_files/HedgewarsMobile/Classes/TeamConfigViewController.m	Mon Oct 31 03:08:16 2011 +0100
@@ -271,7 +271,7 @@
 #pragma mark -
 #pragma mark Memory management
 -(void) didReceiveMemoryWarning {
-    if ([[HedgewarsAppDelegate sharedAppDelegate] isInGame]) {
+    if ([HWUtils isGameLaunched]) {
         self.listOfSelectedTeams = nil;
         self.listOfAllTeams = nil;
         self.tableView = nil;