rewrite gamesetup to use less memory, rename effects to sound plus some nice actions, settings work in game again
authorkoda
Sat, 23 Jan 2010 21:57:24 +0000
changeset 2702 48fc46a922fd
parent 2701 3a8560c00f78
child 2703 fbde0d971ba6
rewrite gamesetup to use less memory, rename effects to sound plus some nice actions, settings work in game again
cocoaTouch/GameSetup.h
cocoaTouch/GameSetup.m
cocoaTouch/SDLOverrides/SDL_uikitappdelegate.h
cocoaTouch/SDLOverrides/SDL_uikitappdelegate.m
cocoaTouch/SettingsViewController.h
cocoaTouch/SettingsViewController.m
cocoaTouch/otherSrc/PascalImports.h
hedgewars/hwengine.pas
--- a/cocoaTouch/GameSetup.h	Sat Jan 23 13:15:27 2010 +0000
+++ b/cocoaTouch/GameSetup.h	Sat Jan 23 21:57:24 2010 +0000
@@ -10,24 +10,17 @@
 #import "SDL_net.h"
 
 @interface GameSetup : NSObject {
-	NSString *localeString;
 	NSDictionary *systemSettings;
 	
-	BOOL engineProtocolStarted;
 	NSInteger ipcPort;
 	TCPsocket sd, csd; // Socket descriptor, Client socket descriptor
-
 }
 
-
-@property (nonatomic, retain) NSString *localeString;
-@property (retain) NSDictionary *systemSettings;
+@property (nonatomic, retain) NSDictionary *systemSettings;
 
 -(void) engineProtocol;
 -(void) startThread: (NSString *)selector;
--(void) loadSettingsFromFile:(NSString *)fileName forKey:(NSString *)objName;
--(int)  sendToEngine: (NSString *)string;
--(void) unloadSettings;
-
+-(int) sendToEngine: (NSString *)string;
+-(const char **)getSettings;
 @end
 
--- a/cocoaTouch/GameSetup.m	Sat Jan 23 13:15:27 2010 +0000
+++ b/cocoaTouch/GameSetup.m	Sat Jan 23 21:57:24 2010 +0000
@@ -15,20 +15,19 @@
 
 @implementation GameSetup
 
-@synthesize localeString, systemSettings;
+@synthesize systemSettings;
 
 -(id) init {
 	self = [super init];
-	self.localeString = [[[NSLocale currentLocale] localeIdentifier] stringByAppendingString:@".txt"];
-	self.systemSettings = nil;
-	engineProtocolStarted = NO;
-	ipcPort = 51432;
+	srandom(time(NULL));
+	ipcPort = (random() % 64541) + 1024 ;//(arc4random() % ((unsigned)64541)) + 1024;
+		
+	NSString *filePath = [[SDLUIKitDelegate sharedAppDelegate] dataFilePath:@"settings.plist"];
+	self.systemSettings = [[NSDictionary alloc] initWithContentsOfFile:filePath]; //should check it exists
 	return self;
 }
 
 -(void) dealloc {
-	if (systemSettings) [self.systemSettings release];
-	[self.localeString autorelease];
 	[super dealloc];
 }
 
@@ -36,12 +35,7 @@
 #pragma mark Thread/Network relevant code
 -(void) startThread: (NSString *) selector {
 	SEL usage = NSSelectorFromString(selector);
-	
-	// do not start the server thread because the port is already bound
-	if (NO == engineProtocolStarted) {
-		engineProtocolStarted = YES;
-		[NSThread detachNewThreadSelector:usage toTarget:self withObject:nil];
-	}
+	[NSThread detachNewThreadSelector:usage toTarget:self withObject:nil];
 }
 
 -(int) sendToEngine: (NSString *)string {
@@ -52,33 +46,32 @@
 }
 
 -(void) engineProtocol {
+	NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
 	IPaddress ip;
 	int idx, eProto;
-	BOOL serverQuit, clientQuit;
+	BOOL clientQuit, serverQuit;
 	char buffer[BUFFER_SIZE], string[BUFFER_SIZE];
 	Uint8 msgSize;
 	Uint16 gameTicks;
-	NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
 	
 	if (SDLNet_Init() < 0) {
-		fprintf(stderr, "SDLNet_Init: %s\n", SDLNet_GetError());
+		NSLog(@"SDLNet_Init: %s", SDLNet_GetError());
 		exit(EXIT_FAILURE);
 	}
 	
 	/* Resolving the host using NULL make network interface to listen */
 	if (SDLNet_ResolveHost(&ip, NULL, ipcPort) < 0) {
-		fprintf(stderr, "SDLNet_ResolveHost: %s\n", SDLNet_GetError());
+		NSLog(@"SDLNet_ResolveHost: %s\n", SDLNet_GetError());
 		exit(EXIT_FAILURE);
 	}
 	
 	/* Open a connection with the IP provided (listen on the host's port) */
 	if (!(sd = SDLNet_TCP_Open(&ip))) {
-		fprintf(stderr, "SDLNet_TCP_Open: %s\n", SDLNet_GetError());
+		NSLog(@"SDLNet_TCP_Open: %s\n", SDLNet_GetError());
 		exit(EXIT_FAILURE);
 	}
 	
-	NSLog(@"engineProtocol - Waiting for a client");
-	
+	NSLog(@"engineProtocol - Waiting for a client on port %d", ipcPort);
 	serverQuit = NO;
 	while (!serverQuit) {
 		
@@ -100,13 +93,13 @@
 				NSLog(@"engineProtocol - sending game config");
 				
 				// send config data data
-				/*seed is arbitrary string
-				[16:12] unC0Rr:
+				/*
+				seed is arbitrary string
 				addteam <color> <team name>
-				[16:13] unC0Rr:
 				addhh <level> <health> <hedgehog name>
-				[16:13] unC0Rr:
-				<level> is 0 for human, 1-5 for bots (5 is the most stupid)*/				// local game
+				  <level> is 0 for human, 1-5 for bots (5 is the most stupid)
+				 */
+				// local game
 				[self sendToEngine:@"TL"];
 				
 				// seed info
@@ -234,15 +227,15 @@
 					// missing case for exiting right away
 				}
 			}
-			NSLog(@"Client Exited");
+			NSLog(@"Engine exited, closing server");
 			// wait a little to let the client close cleanly
-			sleep(2);
+			[NSThread sleepForTimeInterval:2];
 			// Close the client socket
 			SDLNet_TCP_Close(csd);
+			serverQuit = YES;
 		}
-
 	}
-
+	
 	SDLNet_TCP_Close(sd);
 	SDLNet_Quit();
 
@@ -251,24 +244,23 @@
 }
 
 #pragma mark -
-#pragma mark Settings setup methods
--(void) loadSettingsFromFile:(NSString *)fileName forKey:(NSString *)objName {
-	NSString *filePath = [[SDLUIKitDelegate sharedAppDelegate] dataFilePath:fileName];
+#pragma mark Setting methods
+-(const char **)getSettings {
+	const char **gameArgs = (const char**) malloc(sizeof(char*) * 7);
+	NSString *ipcString = [[NSString alloc] initWithFormat:@"%d", ipcPort];
+	NSString *localeString = [[NSString alloc] initWithFormat:@"%@.txt", [[NSLocale currentLocale] localeIdentifier]];
 	
-	if ([[NSFileManager defaultManager] fileExistsAtPath:filePath]) {	
-		NSDictionary *dict = [[NSDictionary alloc] initWithContentsOfFile:filePath];
-		systemSettings = dict;
-		//[self setValue:dict forKey:objName];
-		[dict release];
-	} else {
-		//TODO create it
-		[NSException raise:@"File NOT found" format:@"The file %@ was not found at %@", fileName, filePath];
-	}
-
-}
-
--(void) unloadSettings {
-	systemSettings = nil;
+	gameArgs[0] = [[systemSettings objectForKey:@"username"] UTF8String];	//UserNick
+	gameArgs[1] = [ipcString UTF8String];					//ipcPort
+	gameArgs[2] = [[systemSettings objectForKey:@"sounds"] UTF8String];	//isSoundEnabled
+	gameArgs[3] = [[systemSettings objectForKey:@"music"] UTF8String];	//isMusicEnabled
+	gameArgs[4] = [localeString UTF8String];				//cLocaleFName
+	gameArgs[5] = [[systemSettings objectForKey:@"volume"] UTF8String];	//cInitVolume
+	gameArgs[6] = [[systemSettings objectForKey:@"alternate"] UTF8String];	//cAltDamage
+	
+	[localeString release];
+	[ipcString release];
+	return gameArgs;
 }
 
 
--- a/cocoaTouch/SDLOverrides/SDL_uikitappdelegate.h	Sat Jan 23 13:15:27 2010 +0000
+++ b/cocoaTouch/SDLOverrides/SDL_uikitappdelegate.h	Sat Jan 23 21:57:24 2010 +0000
@@ -23,20 +23,16 @@
 #import <UIKit/UIKit.h>
 #import "SDL_video.h"
 
-@class GameSetup;
-
 @interface SDLUIKitDelegate:NSObject<UIApplicationDelegate> {
     UIWindow *window;
 	SDL_WindowID windowID;
 	UITabBarController *controller;
-	GameSetup *setup;
 }
 
 // the outlets are set in MainWindow.xib
 @property (readwrite, retain) IBOutlet UIWindow *window;
 @property (readwrite, assign) SDL_WindowID windowID;
 @property (nonatomic, retain) IBOutlet UITabBarController *controller;
-@property (nonatomic, retain) GameSetup *setup;
 
 +(SDLUIKitDelegate *)sharedAppDelegate;
 -(NSString *)dataFilePath:(NSString *)fileName;
--- a/cocoaTouch/SDLOverrides/SDL_uikitappdelegate.m	Sat Jan 23 13:15:27 2010 +0000
+++ b/cocoaTouch/SDLOverrides/SDL_uikitappdelegate.m	Sat Jan 23 21:57:24 2010 +0000
@@ -38,7 +38,7 @@
 #undef main
 #endif
 
-int main(int argc, char *argv[]) {
+int main (int argc, char *argv[]) {
     NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
     int retVal = UIApplicationMain(argc, argv, nil, @"SDLUIKitDelegate");
     [pool release];
@@ -47,7 +47,7 @@
 
 @implementation SDLUIKitDelegate
 
-@synthesize window, windowID, controller, setup;
+@synthesize window, windowID, controller;
 
 /* convenience method */
 +(SDLUIKitDelegate *)sharedAppDelegate {
@@ -56,15 +56,16 @@
 }
 
 -(void) dealloc {
-	[setup release];
 	[controller release];
 	[window release];
 	[super dealloc];
 }
 
 -(IBAction) startSDLgame {
+	NSAutoreleasePool *internal_pool = [[NSAutoreleasePool alloc] init];
+
+	GameSetup *setup = [[GameSetup alloc] init];
 	[setup startThread:@"engineProtocol"];
-	[setup loadSettingsFromFile:@"settings.plist" forKey:@"systemSettings"];
 
 	// remove the current view to free resources
 	[UIView beginAnimations:@"removing main controller" context:NULL];
@@ -74,18 +75,17 @@
 	[controller.view performSelector:@selector(removeFromSuperview) withObject:nil afterDelay:1];
 
 	NSLog(@"Game is launching...");
-
-	NSAutoreleasePool *internal_pool = [[NSAutoreleasePool alloc] init];
-
+	const char **gameArgs = [setup getSettings];
+	
 	// direct execution or thread? check the one that gives most fps
 	// library or call SDL_main? pascal quits at the end of the main
-	Game();
-
-	[internal_pool drain];
+	Game(gameArgs);
+	
+	free(gameArgs);
 	NSLog(@"Game is exting...");
 
 	[[window viewWithTag:54867] removeFromSuperview];
-	[setup unloadSettings];
+	[setup release];
 
 	[window addSubview:controller.view];
 	[window makeKeyAndVisible];
@@ -94,13 +94,37 @@
 	[UIView setAnimationDuration:1];
 	controller.view.alpha = 1;
 	[UIView commitAnimations];
+	
+	[internal_pool release];
+}
+
+-(BOOL) checkFirstRun {
+	BOOL isFirstRun = NO;
+	
+	NSString *filePath = [self dataFilePath:@"settings.plist"];
+	if (!([[NSFileManager defaultManager] fileExistsAtPath:filePath])) {
+		isFirstRun = YES;
+		// file not present, let's create it
+		NSMutableDictionary *saveDict = [[NSMutableDictionary alloc] init];
+	
+		[saveDict setObject:@"" forKey:@"username"];
+		[saveDict setObject:@"" forKey:@"password"];
+		[saveDict setObject:@"1" forKey:@"music"];
+		[saveDict setObject:@"1" forKey:@"sounds"];
+		[saveDict setObject:@"0" forKey:@"alternate"];
+		[saveDict setObject:@"100" forKey:@"volume"];
+	
+		[saveDict writeToFile:filePath atomically:YES];
+		[saveDict release];
+	}
+	return isFirstRun;
 }
 
 // override the direct execution of SDL_main to allow us to implement the frontend (even using a nib)
 -(void) applicationDidFinishLaunching:(UIApplication *)application {
 	[application setStatusBarHidden:YES animated:NO];
 
-	setup = [[GameSetup alloc] init];
+	[self checkFirstRun];
 	/* Set working directory to resource path */
 	[[NSFileManager defaultManager] changeCurrentDirectoryPath: [[NSBundle mainBundle] resourcePath]];
 
--- a/cocoaTouch/SettingsViewController.h	Sat Jan 23 13:15:27 2010 +0000
+++ b/cocoaTouch/SettingsViewController.h	Sat Jan 23 21:57:24 2010 +0000
@@ -13,7 +13,7 @@
 	UITextField *username;
 	UITextField *password;
 	UISwitch *musicSwitch;
-	UISwitch *effectsSwitch;
+	UISwitch *soundsSwitch;
 	UISwitch *altDamageSwitch;
 	UISlider *volumeSlider;
 	UILabel *volumeLabel;
@@ -23,7 +23,7 @@
 @property (nonatomic, retain) IBOutlet UITextField *username;
 @property (nonatomic, retain) IBOutlet UITextField *password;
 @property (nonatomic, retain) UISwitch *musicSwitch;
-@property (nonatomic, retain) UISwitch *effectsSwitch;
+@property (nonatomic, retain) UISwitch *soundsSwitch;
 @property (nonatomic, retain) UISwitch *altDamageSwitch;
 @property (nonatomic, retain) IBOutlet UISlider *volumeSlider;
 @property (nonatomic, retain) IBOutlet UILabel *volumeLabel;
--- a/cocoaTouch/SettingsViewController.m	Sat Jan 23 13:15:27 2010 +0000
+++ b/cocoaTouch/SettingsViewController.m	Sat Jan 23 21:57:24 2010 +0000
@@ -11,13 +11,16 @@
 
 @implementation SettingsViewController
 
-@synthesize username, password, musicSwitch, effectsSwitch, altDamageSwitch, volumeSlider, volumeLabel, table, volumeCell;
+@synthesize username, password, musicSwitch, soundsSwitch, altDamageSwitch, volumeSlider, volumeLabel, table, volumeCell;
 
 
 -(void) loadView {
 	self.musicSwitch = [[UISwitch alloc] init];
-	self.effectsSwitch = [[UISwitch alloc] init];
+	self.soundsSwitch = [[UISwitch alloc] init];
 	self.altDamageSwitch = [[UISwitch alloc] init];
+	[self.soundsSwitch addTarget:self action:@selector(sameValueSwitch) forControlEvents:UIControlEventValueChanged];
+	[self.musicSwitch addTarget:self action:@selector(checkValueSwitch) forControlEvents:UIControlEventValueChanged];
+
 	[super loadView];
 }
 
@@ -33,10 +36,10 @@
 		} else {
 			musicSwitch.on = NO;
 		}
-		if (1 == [[data objectForKey:@"effects"] intValue]) {
-			effectsSwitch.on = YES;
+		if (1 == [[data objectForKey:@"sounds"] intValue]) {
+			soundsSwitch.on = YES;
 		} else {
-			effectsSwitch.on = NO;
+			soundsSwitch.on = NO;
 		}
 		if (1 == [[data objectForKey:@"alternate"] intValue]) {
 			altDamageSwitch.on = YES;
@@ -66,7 +69,7 @@
 	self.username = nil;
 	self.password = nil;
 	self.musicSwitch = nil;
-	self.effectsSwitch = nil;
+	self.soundsSwitch = nil;
 	self.altDamageSwitch = nil;
 	self.volumeLabel = nil;
 	self.volumeSlider = nil;
@@ -79,13 +82,13 @@
 -(void) viewWillDisappear:(BOOL)animated {
 	NSMutableDictionary *saveDict = [[NSMutableDictionary alloc] init];
 	NSString *tmpMus = (musicSwitch.on) ? @"1" : @"0";
-	NSString *tmpEff = (effectsSwitch.on) ? @"1" : @"0";
+	NSString *tmpEff = (soundsSwitch.on) ? @"1" : @"0";
 	NSString *tmpAlt = (altDamageSwitch.on) ? @"1" : @"0";
 	
 	[saveDict setObject:username.text forKey:@"username"];
 	[saveDict setObject:password.text forKey:@"password"];
 	[saveDict setObject:tmpMus forKey:@"music"];
-	[saveDict setObject:tmpEff forKey:@"effects"];
+	[saveDict setObject:tmpEff forKey:@"sounds"];
 	[saveDict setObject:tmpAlt forKey:@"alternate"];
 	[saveDict setObject:volumeLabel.text forKey:@"volume"];
 	
@@ -93,7 +96,19 @@
 	[saveDict release];
 	[super viewWillDisappear:animated];
 }
- 
+
+-(void) dealloc {
+	[username release];
+	[password release];
+	[musicSwitch release];
+	[soundsSwitch release];
+	[altDamageSwitch release];
+	[volumeLabel release];
+	[volumeSlider release];
+	[table release];
+	[volumeCell release];
+	[super dealloc];
+}
 /*
 // Override to allow orientations other than the default portrait orientation.
 - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
@@ -113,6 +128,7 @@
 	[sender resignFirstResponder];
 }
 
+// update the value of the label when slider is updated
 -(IBAction) sliderChanged: (id) sender {
 	UISlider *slider = (UISlider *)sender;
 	int progress = slider.value;
@@ -121,17 +137,18 @@
 	[newLabel release];
 }
 
--(void) dealloc {
-	[username release];
-	[password release];
-	[musicSwitch release];
-	[effectsSwitch release];
-	[altDamageSwitch release];
-	[volumeLabel release];
-	[volumeSlider release];
-	[table release];
-	[volumeCell release];
-	[super dealloc];
+// set music off when sound is turned off
+-(void) sameValueSwitch {
+	if (YES == self.musicSwitch.on) {
+		[musicSwitch setOn:NO animated:YES];
+	}
+}
+
+// don't enable music when sound is off
+-(void) checkValueSwitch {
+	if (NO == self.soundsSwitch.on) {
+		[musicSwitch setOn:!musicSwitch.on animated:YES];
+	}
 }
 
 #pragma mark -
@@ -193,13 +210,13 @@
 		case kAudioFields:
 			switch ([indexPath row]) {
 				case 0:
+					cell.accessoryView = soundsSwitch;
+					cell.textLabel.text = NSLocalizedString(@"Sound", @"");
+					break;
+				case 1:
 					cell.accessoryView = musicSwitch;
 					cell.textLabel.text = NSLocalizedString(@"Music", @"");
 					break;
-				case 1:
-					cell.accessoryView = effectsSwitch;
-					cell.textLabel.text = NSLocalizedString(@"Sound Effects", @"");
-					break;
 				case 2:
 					cell = volumeCell;
 					break;
--- a/cocoaTouch/otherSrc/PascalImports.h	Sat Jan 23 13:15:27 2010 +0000
+++ b/cocoaTouch/otherSrc/PascalImports.h	Sat Jan 23 21:57:24 2010 +0000
@@ -18,7 +18,7 @@
 	 * that you want to use
 	 */
 
-	void Game(void);
+	void Game(const char *args[]);
 
 
 	int HW_protoVer(void);
--- a/hedgewars/hwengine.pas	Sat Jan 23 13:15:27 2010 +0000
+++ b/hedgewars/hwengine.pas	Sat Jan 23 21:57:24 2010 +0000
@@ -67,11 +67,12 @@
 //       proto.inc
 
 {$IFDEF IPHONEOS}
+type arrayofpchar = array[0..6] of PChar;
 procedure DoTimer(Lag: LongInt);
 procedure OnDestroy;
 procedure MainLoop;
 procedure ShowMainWindow;
-procedure Game; cdecl; export;
+procedure Game(gameArgs: arrayofpchar); cdecl; export;
 procedure initEverything;
 procedure freeEverything;
 
@@ -133,7 +134,7 @@
 
 	SDL_GL_SwapBuffers();
 {$IFNDEF IPHONEOS}
-		// not going to make captures on the iPhone
+	// not going to make captures on the iPhone
 	if flagMakeCapture then
 	begin
 		flagMakeCapture:= false;
@@ -166,7 +167,7 @@
 procedure MainLoop; 
 var PrevTime,
     CurrTime: Longword;
-    event: TSDL_Event;
+    {$IFNDEF IPHONEOS}event: TSDL_Event;{$ENDIF}
 begin
 
 	PrevTime:= SDL_GetTicks;
@@ -216,7 +217,11 @@
 end;
 
 ///////////////
-procedure Game;{$IFDEF IPHONEOS}cdecl; export;{$ENDIF}
+{$IFDEF IPHONEOS}
+procedure Game(gameArgs: arrayofpchar); cdecl; export;
+{$ELSE}
+procedure Game;cdecl; export;
+{$ENDIF}
 var	p: TPathType;
 	s: shortstring;
 begin
@@ -228,21 +233,22 @@
 	val('480', cScreenHeight);
 	cInitWidth:= cScreenWidth;
 	cInitHeight:= cScreenHeight;
-	cBitsStr:= '16';
+	cBitsStr:= '32';
 	val(cBitsStr, cBits);
-	val('51432', ipcPort);
 	cFullScreen:= true;
-	isSoundEnabled:= false;
 	cVSyncInUse:= true;
-	cLocaleFName:= 'en.txt';
-	val('100', cInitVolume);
 	val('8', cTimerInterval);
 	PathPrefix:= 'Data';
+	cReducedQuality:= false;
 	cShowFPS:= true;
-	cAltDamage:= false;
-	UserNick:= 'Koda'; //DecodeBase64(ParamStr(15));
-	isMusicEnabled:= false;
-	cReducedQuality:= false;
+
+	UserNick:= gameArgs[0];
+	val(gameArgs[1], ipcPort);
+	isSoundEnabled:= gameArgs[2] = '1';
+	isMusicEnabled:= gameArgs[3] = '1';
+	cLocaleFName:= gameArgs[4];
+	val(gameArgs[5], cInitVolume);
+	cAltDamage:= gameArgs[6] = '1';
 {$ENDIF}
 
 	for p:= Succ(Low(TPathType)) to High(TPathType) do