add the appirater class for getting more positive reviews
enabled full multitasking for iphone (but only with ios >= 4.2)
fixed a glitch that would leave stuff onscreen while ammo menu open
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/project_files/HedgewarsMobile/Classes/Appirater.h Sat Dec 11 01:55:16 2010 +0100
@@ -0,0 +1,105 @@
+/*
+ This file is part of Appirater.
+
+ Copyright (c) 2010, Arash Payan
+ All rights reserved.
+
+ Permission is hereby granted, free of charge, to any person
+ obtaining a copy of this software and associated documentation
+ files (the "Software"), to deal in the Software without
+ restriction, including without limitation the rights to use,
+ copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the
+ Software is furnished to do so, subject to the following
+ conditions:
+
+ The above copyright notice and this permission notice shall be
+ included in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * Appirater.h
+ * appirater
+ *
+ * Created by Arash Payan on 9/5/09.
+ * http://arashpayan.com
+ * Copyright 2010 Arash Payan. All rights reserved.
+ */
+
+#import <Foundation/Foundation.h>
+
+extern NSString *const kAppiraterLaunchDate;
+extern NSString *const kAppiraterLaunchCount;
+extern NSString *const kAppiraterCurrentVersion;
+extern NSString *const kAppiraterRatedCurrentVersion;
+extern NSString *const kAppiraterDeclinedToRate;
+
+/*
+ Place your Apple generated software id here.
+ */
+#define APPIRATER_APP_ID 391234866
+
+/*
+ Your app's name.
+ */
+#define APPIRATER_APP_NAME [[[NSBundle mainBundle] infoDictionary] objectForKey:(NSString*)kCFBundleNameKey]
+
+/*
+ This is the message your users will see once they've passed the day+launches
+ threshold.
+ */
+#define APPIRATER_MESSAGE [NSString stringWithFormat:@"If you enjoy using %@, would you mind taking a moment to rate it? It won't take more than a minute. Thanks for your support!", APPIRATER_APP_NAME]
+
+/*
+ This is the title of the message alert that users will see.
+ */
+#define APPIRATER_MESSAGE_TITLE [NSString stringWithFormat:@"Rate %@", APPIRATER_APP_NAME]
+
+/*
+ The text of the button that rejects reviewing the app.
+ */
+#define APPIRATER_CANCEL_BUTTON NSLocalizedString(@"No thanks",@"")
+
+/*
+ Text of button that will send user to app review page.
+ */
+#define APPIRATER_RATE_BUTTON [NSString stringWithFormat:@"Rate %@", APPIRATER_APP_NAME]
+
+/*
+ Text for button to remind the user to review later.
+ */
+#define APPIRATER_RATE_LATER NSLocalizedString(@"Remind me later",@"")
+
+/*
+ Users will need to have the same version of your app installed for this many
+ days before they will be prompted to rate it.
+ */
+#define DAYS_UNTIL_PROMPT 5 // double
+
+/*
+ Users will need to launch the same version of the app this many times before
+ they will be prompted to rate it.
+ */
+#define LAUNCHES_UNTIL_PROMPT 10 // integer
+
+/*
+ 'YES' will show the Appirater alert everytime. Useful for testing how your message
+ looks and making sure the link to your app's review page works.
+ */
+#define APPIRATER_DEBUG NO // bool
+
+@interface Appirater : NSObject <UIAlertViewDelegate> {
+
+}
+
++(void) appLaunched;
+
+@end
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/project_files/HedgewarsMobile/Classes/Appirater.m Sat Dec 11 01:55:16 2010 +0100
@@ -0,0 +1,207 @@
+/*
+ This file is part of Appirater.
+
+ Copyright (c) 2010, Arash Payan
+ All rights reserved.
+
+ Permission is hereby granted, free of charge, to any person
+ obtaining a copy of this software and associated documentation
+ files (the "Software"), to deal in the Software without
+ restriction, including without limitation the rights to use,
+ copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the
+ Software is furnished to do so, subject to the following
+ conditions:
+
+ The above copyright notice and this permission notice shall be
+ included in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * Appirater.m
+ * appirater
+ *
+ * Created by Arash Payan on 9/5/09.
+ * http://arashpayan.com
+ * Copyright 2010 Arash Payan. All rights reserved.
+ */
+
+#import "Appirater.h"
+#import <SystemConfiguration/SCNetworkReachability.h>
+#import <netinet/in.h>
+
+NSString *const kAppiraterLaunchDate = @"kAppiraterLaunchDate";
+NSString *const kAppiraterLaunchCount = @"kAppiraterLaunchCount";
+NSString *const kAppiraterCurrentVersion = @"kAppiraterCurrentVersion";
+NSString *const kAppiraterRatedCurrentVersion = @"kAppiraterRatedCurrentVersion";
+NSString *const kAppiraterDeclinedToRate = @"kAppiraterDeclinedToRate";
+
+NSString *templateReviewURL = @"itms-apps://itunes.apple.com/WebObjects/MZStore.woa/wa/viewContentsUserReviews?id=APP_ID&onlyLatestVersion=true&pageNumber=0&sortOrdering=1&type=Purple+Software";
+
+@interface Appirater (hidden)
+
+-(BOOL) connectedToNetwork;
+
+@end
+
+@implementation Appirater (hidden)
+
+-(BOOL) connectedToNetwork {
+ // Create zero addy
+ struct sockaddr_in zeroAddress;
+ bzero(&zeroAddress, sizeof(zeroAddress));
+ zeroAddress.sin_len = sizeof(zeroAddress);
+ zeroAddress.sin_family = AF_INET;
+
+ // Recover reachability flags
+ SCNetworkReachabilityRef defaultRouteReachability = SCNetworkReachabilityCreateWithAddress(NULL, (struct sockaddr *)&zeroAddress);
+ SCNetworkReachabilityFlags flags;
+
+ BOOL didRetrieveFlags = SCNetworkReachabilityGetFlags(defaultRouteReachability, &flags);
+ CFRelease(defaultRouteReachability);
+
+ if (!didRetrieveFlags) {
+ NSLog(@"Error. Could not recover network reachability flags");
+ return NO;
+ }
+
+ BOOL isReachable = flags & kSCNetworkFlagsReachable;
+ BOOL needsConnection = flags & kSCNetworkFlagsConnectionRequired;
+ BOOL nonWiFi = flags & kSCNetworkReachabilityFlagsTransientConnection;
+
+ NSURL *testURL = [NSURL URLWithString:@"http://www.apple.com/"];
+ NSURLRequest *testRequest = [NSURLRequest requestWithURL:testURL cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:20.0];
+ NSURLConnection *testConnection = [[NSURLConnection alloc] initWithRequest:testRequest delegate:self];
+
+ return ((isReachable && !needsConnection) || nonWiFi) ? (testConnection ? YES : NO) : NO;
+}
+
+@end
+
+
+@implementation Appirater
+
++(void) appLaunched {
+ Appirater *appirater = [[Appirater alloc] init];
+ [NSThread detachNewThreadSelector:@selector(appLaunchedHandler) toTarget:appirater withObject:nil];
+}
+
+-(void) appLaunchedHandler {
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+
+ if (APPIRATER_DEBUG) {
+ [self performSelectorOnMainThread:@selector(showPrompt) withObject:nil waitUntilDone:NO];
+ return;
+ }
+
+ BOOL willShowPrompt = NO;
+
+ // get the app's version
+ NSString *version = [[[NSBundle mainBundle] infoDictionary] objectForKey:(NSString*)kCFBundleVersionKey];
+
+ // get the version number that we've been tracking
+ NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
+ NSString *trackingVersion = [userDefaults stringForKey:kAppiraterCurrentVersion];
+ if (trackingVersion == nil) {
+ trackingVersion = version;
+ [userDefaults setObject:version forKey:kAppiraterCurrentVersion];
+ }
+
+ if (APPIRATER_DEBUG)
+ DLog(@"APPIRATER Tracking version: %@", trackingVersion);
+
+ if ([trackingVersion isEqualToString:version]) {
+ // get the launch date
+ NSTimeInterval timeInterval = [userDefaults doubleForKey:kAppiraterLaunchDate];
+ if (timeInterval == 0) {
+ timeInterval = [[NSDate date] timeIntervalSince1970];
+ [userDefaults setDouble:timeInterval forKey:kAppiraterLaunchDate];
+ }
+
+ NSTimeInterval secondsSinceLaunch = [[NSDate date] timeIntervalSinceDate:[NSDate dateWithTimeIntervalSince1970:timeInterval]];
+ double secondsUntilPrompt = 60 * 60 * 24 * DAYS_UNTIL_PROMPT;
+
+ // get the launch count
+ int launchCount = [userDefaults integerForKey:kAppiraterLaunchCount];
+ launchCount++;
+ [userDefaults setInteger:launchCount forKey:kAppiraterLaunchCount];
+ if (APPIRATER_DEBUG)
+ NSLog(@"APPIRATER Launch count: %d", launchCount);
+
+ // have they previously declined to rate this version of the app?
+ BOOL declinedToRate = [userDefaults boolForKey:kAppiraterDeclinedToRate];
+
+ // have they already rated the app?
+ BOOL ratedApp = [userDefaults boolForKey:kAppiraterRatedCurrentVersion];
+
+ if (secondsSinceLaunch > secondsUntilPrompt &&
+ launchCount > LAUNCHES_UNTIL_PROMPT &&
+ !declinedToRate &&
+ !ratedApp) {
+ if ([self connectedToNetwork]) { // check if they can reach the app store
+ willShowPrompt = YES;
+ [self performSelectorOnMainThread:@selector(showPrompt) withObject:nil waitUntilDone:NO];
+ }
+ }
+ } else {
+ // it's a new version of the app, so restart tracking
+ [userDefaults setObject:version forKey:kAppiraterCurrentVersion];
+ [userDefaults setDouble:[[NSDate date] timeIntervalSince1970] forKey:kAppiraterLaunchDate];
+ [userDefaults setInteger:1 forKey:kAppiraterLaunchCount];
+ [userDefaults setBool:NO forKey:kAppiraterRatedCurrentVersion];
+ [userDefaults setBool:NO forKey:kAppiraterDeclinedToRate];
+ }
+
+ [userDefaults synchronize];
+ if (!willShowPrompt)
+ [self autorelease];
+
+ [pool release];
+}
+
+-(void) showPrompt {
+ UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:APPIRATER_MESSAGE_TITLE
+ message:APPIRATER_MESSAGE
+ delegate:self
+ cancelButtonTitle:APPIRATER_CANCEL_BUTTON
+ otherButtonTitles:APPIRATER_RATE_BUTTON, APPIRATER_RATE_LATER, nil];
+ [alertView show];
+ [alertView release];
+}
+
+-(void) alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger) buttonIndex {
+ NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
+
+ switch (buttonIndex) {
+ case 0:
+ // they don't want to rate it
+ [userDefaults setBool:YES forKey:kAppiraterDeclinedToRate];
+ break;
+ case 1:
+ // they want to rate it
+ [[UIApplication sharedApplication] openURL:
+ [NSURL URLWithString:[templateReviewURL stringByReplacingOccurrencesOfString:@"APP_ID" withString:[NSString stringWithFormat:@"%d", APPIRATER_APP_ID]]]];
+
+ [userDefaults setBool:YES forKey:kAppiraterRatedCurrentVersion];
+ break;
+ case 2:
+ // remind them later
+ break;
+ default:
+ break;
+ }
+
+ [userDefaults synchronize];
+
+ [self release];
+}
+
+@end
--- a/project_files/HedgewarsMobile/Classes/GameConfigViewController.m Sat Dec 11 01:00:00 2010 +0100
+++ b/project_files/HedgewarsMobile/Classes/GameConfigViewController.m Sat Dec 11 01:55:16 2010 +0100
@@ -226,9 +226,6 @@
[NSNumber numberWithInt:self.interfaceOrientation],@"orientation",
nil];
- // finally launch game and remove this controller
- DLog(@"sending config %@", gameDictionary);
-
NSDictionary *allDataNecessary = [NSDictionary dictionaryWithObjectsAndKeys:gameDictionary,@"game_dictionary", @"",@"savefile",
[NSNumber numberWithBool:NO],@"netgame", nil];
if (IS_IPAD())
--- a/project_files/HedgewarsMobile/Classes/ObjcExports.h Sat Dec 11 01:00:00 2010 +0100
+++ b/project_files/HedgewarsMobile/Classes/ObjcExports.h Sat Dec 11 01:55:16 2010 +0100
@@ -31,5 +31,6 @@
BOOL isGameRunning();
void setGameRunning(BOOL value);
NSInteger cachedGrenadeTime();
+void clearView();
void setGrenadeTime(NSInteger value);
void setAmmoMenuInstance(AmmoMenuViewController *instance);
--- a/project_files/HedgewarsMobile/Classes/ObjcExports.m Sat Dec 11 01:00:00 2010 +0100
+++ b/project_files/HedgewarsMobile/Classes/ObjcExports.m Sat Dec 11 01:55:16 2010 +0100
@@ -96,6 +96,7 @@
}
void clearView() {
+ // don't use any engine calls here as this function is called every time the ammomenu is opened
UIWindow *theWindow = (IS_DUALHEAD()) ? [SDLUIKitDelegate sharedAppDelegate].uiwindow : [[UIApplication sharedApplication] keyWindow];
UIButton *theButton = (UIButton *)[theWindow viewWithTag:CONFIRMATION_TAG];
UISegmentedControl *theSegment = (UISegmentedControl *)[theWindow viewWithTag:GRENADE_TAG];
@@ -166,6 +167,7 @@
gAudioSessionInited = YES;
}
UInt32 propertySize = sizeof(CFStringRef);
+ BOOL muteResult = NO;
// this checks if there is volume
Float32 volume;
@@ -179,9 +181,10 @@
n = AudioSessionGetProperty(kAudioSessionProperty_AudioRoute, &propertySize, &state);
if (n != 0)
DLog( @"AudioSessionGetProperty 'audioRoute': %d", n );
- NSString *result = (NSString *)state;
- BOOL muteResult = ([result length] == 0);
- releaseAndNil(result);
-
+ else {
+ NSString *result = (NSString *)state;
+ muteResult = ([result length] == 0);
+ releaseAndNil(result);
+ }
return volumeResult || muteResult;
}
--- a/project_files/HedgewarsMobile/Classes/OverlayViewController.m Sat Dec 11 01:00:00 2010 +0100
+++ b/project_files/HedgewarsMobile/Classes/OverlayViewController.m Sat Dec 11 01:55:16 2010 +0100
@@ -395,6 +395,7 @@
break;
case 10:
playSound(@"clickSound");
+ clearView();
HW_pause();
if (self.amvc.isVisible && IS_DUALHEAD() == NO) {
doDim();
@@ -405,6 +406,7 @@
break;
case 11:
playSound(@"clickSound");
+ clearView();
removeConfirmationInput();
if (IS_DUALHEAD() || self.useClassicMenu == NO) {
--- a/project_files/HedgewarsMobile/Classes/SDL_uikitappdelegate.m Sat Dec 11 01:00:00 2010 +0100
+++ b/project_files/HedgewarsMobile/Classes/SDL_uikitappdelegate.m Sat Dec 11 01:55:16 2010 +0100
@@ -24,7 +24,6 @@
#import "SDL_uikitopenglview.h"
#import "SDL_uikitwindow.h"
#import "SDL_events_c.h"
-#import "../SDL_sysvideo.h"
#import "jumphack.h"
#import "SDL_video.h"
#import "SDL_mixer.h"
@@ -34,6 +33,8 @@
#import "GameSetup.h"
#import "MainMenuViewController.h"
#import "OverlayViewController.h"
+#import "Appirater.h"
+#include <unistd.h>
#ifdef main
#undef main
@@ -41,16 +42,15 @@
#define BLACKVIEW_TAG 17935
#define SECONDBLACKVIEW_TAG 48620
-#define VALGRIND "/opt/valgrind/bin/valgrind"
+#define VALGRIND "/opt/fink/bin/valgrind"
int main (int argc, char *argv[]) {
#ifdef VALGRIND_REXEC
// Using the valgrind build config, rexec ourself in valgrind
// from http://landonf.bikemonkey.org/code/iphone/iPhone_Simulator_Valgrind.20081224.html
if (argc < 2 || (argc >= 2 && strcmp(argv[1], "-valgrind") != 0))
- execl(VALGRIND, VALGRIND, "--leak-check=full", argv[0], "-valgrind", NULL);
+ execl(VALGRIND, VALGRIND, "--leak-check=full", "--dsymutil=yes", argv[0], "-valgrind", NULL);
#endif
-
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
int retVal = UIApplicationMain(argc, argv, nil, @"SDLUIKitDelegate");
[pool release];
@@ -173,7 +173,7 @@
}
// override the direct execution of SDL_main to allow us to implement the frontend (or even using a nib)
--(void) applicationDidFinishLaunching:(UIApplication *)application {
+-(BOOL) application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[application setStatusBarHidden:YES];
self.uiwindow = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
@@ -204,6 +204,9 @@
[titleView release];
[self.secondWindow makeKeyAndVisible];
}
+
+ [Appirater appLaunched];
+ return YES;
}
-(void) applicationWillTerminate:(UIApplication *)application {
@@ -227,15 +230,15 @@
if ([device respondsToSelector:@selector(isMultitaskingSupported)] &&
device.multitaskingSupported &&
self.isInGame) {
- // there is a bug on iphone that presents a sdl view with a black screen, so it returns to frontend
- if (IS_IPAD())
+ // multiasking in-game works only for ios >= 4.2, returns a black screen on other verions
+ if (NSClassFromString(@"UIPrintInfo"))
HW_suspend();
else {
- // while screen is loading you can't call HW_terminate() so we close the app
+ // so the game returns to the configuration view
if (isGameRunning())
HW_terminate(NO);
else {
- // force app closure
+ // while screen is loading you can't call HW_terminate() so we close the app
SDL_SendQuit();
HW_terminate(YES);
longjmp(*(jump_env()), 1);
--- a/project_files/HedgewarsMobile/Classes/TeamConfigViewController.m Sat Dec 11 01:00:00 2010 +0100
+++ b/project_files/HedgewarsMobile/Classes/TeamConfigViewController.m Sat Dec 11 01:55:16 2010 +0100
@@ -236,7 +236,7 @@
label.textColor = [UIColor whiteColor];
label.numberOfLines = 1;
if (section == 0)
- label.text = NSLocalizedString(@"Tap to add hogs or change color, hold tap to remove team.",@"");
+ label.text = NSLocalizedString(@"Tap to add hogs or change color, touch and hold to remove team.",@"");
else
label.text = NSLocalizedString(@"The robot badge indicates an AI-controlled team.",@"");
--- a/project_files/HedgewarsMobile/Hedgewars.xcodeproj/project.pbxproj Sat Dec 11 01:00:00 2010 +0100
+++ b/project_files/HedgewarsMobile/Hedgewars.xcodeproj/project.pbxproj Sat Dec 11 01:55:16 2010 +0100
@@ -182,6 +182,7 @@
61A670C012747D9B00B06CE7 /* Default.png in Resources */ = {isa = PBXBuildFile; fileRef = 6183D83D11E2BCE200A88903 /* Default.png */; };
61A670C112747DB900B06CE7 /* MainMenuViewController-iPhone.xib in Resources */ = {isa = PBXBuildFile; fileRef = 6165924C11CA9CB400D6E256 /* MainMenuViewController-iPhone.xib */; };
61A670C212747DBD00B06CE7 /* MapConfigViewController-iPhone.xib in Resources */ = {isa = PBXBuildFile; fileRef = 6165924E11CA9CB400D6E256 /* MapConfigViewController-iPhone.xib */; };
+ 61AC067412B2E32D000B52A2 /* Appirater.m in Sources */ = {isa = PBXBuildFile; fileRef = 61AC067312B2E32D000B52A2 /* Appirater.m */; };
61B3D71C11EA6F2700EC7420 /* uKeys.pas in Sources */ = {isa = PBXBuildFile; fileRef = 617987FE114AA34C00BA94A9 /* uKeys.pas */; };
61C079E411F35A300072BF46 /* EditableCellView.m in Sources */ = {isa = PBXBuildFile; fileRef = 61C079E311F35A300072BF46 /* EditableCellView.m */; };
61D205A1127CDD1100ABD83E /* ObjcExports.m in Sources */ = {isa = PBXBuildFile; fileRef = 61D205A0127CDD1100ABD83E /* ObjcExports.m */; };
@@ -958,6 +959,8 @@
61A4A39212A5CCC2004D81E6 /* uUtils.pas */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.pascal; name = uUtils.pas; path = ../../hedgewars/uUtils.pas; sourceTree = SOURCE_ROOT; };
61A4A39312A5CCC2004D81E6 /* uVariables.pas */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.pascal; name = uVariables.pas; path = ../../hedgewars/uVariables.pas; sourceTree = SOURCE_ROOT; };
61A4A3A112A5CD56004D81E6 /* uCaptions.pas */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.pascal; name = uCaptions.pas; path = ../../hedgewars/uCaptions.pas; sourceTree = SOURCE_ROOT; };
+ 61AC067212B2E32D000B52A2 /* Appirater.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Appirater.h; path = Classes/Appirater.h; sourceTree = "<group>"; };
+ 61AC067312B2E32D000B52A2 /* Appirater.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = Appirater.m; path = Classes/Appirater.m; sourceTree = "<group>"; };
61C079E211F35A300072BF46 /* EditableCellView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = EditableCellView.h; path = Classes/EditableCellView.h; sourceTree = "<group>"; };
61C079E311F35A300072BF46 /* EditableCellView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = EditableCellView.m; path = Classes/EditableCellView.m; sourceTree = "<group>"; };
61D2059F127CDD1100ABD83E /* ObjcExports.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ObjcExports.h; path = Classes/ObjcExports.h; sourceTree = "<group>"; };
@@ -1076,6 +1079,8 @@
children = (
6165929C11CA9E2F00D6E256 /* SDL_uikitappdelegate.h */,
6165929D11CA9E2F00D6E256 /* SDL_uikitappdelegate.m */,
+ 61AC067212B2E32D000B52A2 /* Appirater.h */,
+ 61AC067312B2E32D000B52A2 /* Appirater.m */,
61DE91561258B76800B80214 /* Custom UIs */,
32CA4F630368D1EE00C91783 /* Hedgewars_Prefix.pch */,
6165922911CA9BD500D6E256 /* PascalImports.h */,
@@ -2412,6 +2417,7 @@
61A4A3A212A5CD56004D81E6 /* uCaptions.pas in Sources */,
61E5D68D12AB006F00566F29 /* uLandPainted.pas in Sources */,
61F544C712AF1748007FD913 /* HoldTableViewCell.m in Sources */,
+ 61AC067412B2E32D000B52A2 /* Appirater.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};