better network support + initial work for returning to frontend
authorkoda
Tue, 12 Jan 2010 07:32:15 +0000
changeset 2692 ce9992075118
parent 2691 c0da3a98c01c
child 2693 3207e0eacd43
better network support + initial work for returning to frontend
cocoaTouch/SDLOverrides/SDL_uikitappdelegate.m
cocoaTouch/SDLOverrides/SDL_uikitopengles.h
cocoaTouch/SDLOverrides/SDL_uikitopengles.m
cocoaTouch/gameSetup.m
hedgewars/PascalExports.pas
hedgewars/hwengine.pas
hedgewars/uLand.pas
--- a/cocoaTouch/SDLOverrides/SDL_uikitappdelegate.m	Sun Jan 10 00:52:20 2010 +0000
+++ b/cocoaTouch/SDLOverrides/SDL_uikitappdelegate.m	Tue Jan 12 07:32:15 2010 +0000
@@ -33,6 +33,7 @@
 #endif
 
 extern int SDL_main(int argc, char *argv[]);
+BOOL isServerRunning = NO;
 
 int main (int argc, char **argv) {
 	int i;
@@ -62,20 +63,42 @@
 	return (SDLUIKitDelegate *)[[UIApplication sharedApplication] delegate];
 }
 
+void preSDL_main(){
+	NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+
+	SDL_main(forward_argc, forward_argv);
+
+	[pool release];
+}
 
 - (void) startSDLgame {
 	pthread_t threadID;
 
-	pthread_create (&threadID, NULL, (void *) (*engineProtocolThread), NULL);
-	pthread_detach (threadID);
+	if (NO == isServerRunning) {
+		// don't start another server because the port is already bound
+		pthread_create (&threadID, NULL, (void *) (*engineProtocolThread), NULL);
+		pthread_detach (threadID);
+		isServerRunning = YES;
+	}
 
 	setupArgsForLocalPlay();
 	
+	// remove the current view to free resources
+	[UIView beginAnimations:nil context:NULL];
+	[UIView setAnimationDuration:1.5];
+	controller.view.alpha = 0;
+	[UIView commitAnimations];
+	[controller.view performSelector:@selector(removeFromSuperview) withObject:nil afterDelay:1.5];
+	//[controller.view removeFromSuperview];
+	
 	/* run the user's application, passing argc and argv */
 	NSLog(@"Game is launching...");
-	SDL_main(forward_argc, forward_argv);
+	/*pthread_create (&threadID, NULL, (void *) (*preSDL_main), NULL);
+	pthread_detach (threadID);*/
+	int res = SDL_main(forward_argc, forward_argv);
+
 	// can't reach here yet
-	NSLog(@"Game exited");
+	NSLog(@"Game exited with status %d", res);
 
 	//[self performSelector:@selector(makeNewView) withObject:nil afterDelay:0.0];
 	/* exit, passing the return status from the user's application */
@@ -91,12 +114,8 @@
 //#import "SoundEffect.h"	
 //	SoundEffect *erasingSound = [[SoundEffect alloc] initWithContentsOfFile:[mainBundle pathForResource:@"Erase" ofType:@"caf"]];
 //	SoundEffect *selectSound = [[SoundEffect alloc] initWithContentsOfFile:[mainBundle pathForResource:@"Select" ofType:@"caf"]];
-	
 	[window addSubview:controller.view];
 	[window makeKeyAndVisible];
-	
-	// REMOVE ME when you're done with reverse engineering the protocol
-	[self performSelector:@selector(startSDLgame)];
 }
 
 -(void) applicationWillTerminate:(UIApplication *)application {
@@ -107,11 +126,9 @@
 	}
 	free(forward_argv);	
 	SDL_SendQuit();
-	 /* hack to prevent automatic termination.  See SDL_uikitevents.m for details */
+	/* hack to prevent automatic termination.  See SDL_uikitevents.m for details */
 	// have to remove this otherwise game goes on when pushing the home button
 	//longjmp(*(jump_env()), 1);
-	
-	NSLog(@"Closing App...");
 }
 
 -(void) applicationWillResignActive:(UIApplication*)application
@@ -133,6 +150,20 @@
 }
 */
 
+void IPH_returnFrontend (void) {
+	NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+	
+	[[[SDLUIKitDelegate sharedAppDelegate].window viewWithTag:54867] removeFromSuperview];
+	[[SDLUIKitDelegate sharedAppDelegate].window addSubview:[SDLUIKitDelegate sharedAppDelegate].controller.view];
+//	[[SDLUIKitDelegate sharedAppDelegate].window makeKeyAndVisible];
+	NSLog(@"Game exited...");
+//	pthread_exit(NULL);
+	[pool release];
+	exit(0);
+//	while(1);	//prevent exiting	
+}
+
+
 -(void) dealloc {
 	[controller release];
 	[window release];
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cocoaTouch/SDLOverrides/SDL_uikitopengles.h	Tue Jan 12 07:32:15 2010 +0000
@@ -0,0 +1,38 @@
+/*
+    SDL - Simple DirectMedia Layer
+    Copyright (C) 1997-2009 Sam Lantinga
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+    Sam Lantinga
+    slouken@libsdl.org
+*/
+
+#include "SDL_config.h"
+
+#ifndef _SDL_uikitopengles
+#define _SDL_uikitopengles
+
+#include "SDL_uikitvideo.h"
+
+extern int UIKit_GL_MakeCurrent(_THIS, SDL_Window * window,
+                                SDL_GLContext context);
+extern void UIKit_GL_SwapWindow(_THIS, SDL_Window * window);
+extern SDL_GLContext UIKit_GL_CreateContext(_THIS, SDL_Window * window);
+extern void UIKit_GL_DeleteContext(_THIS, SDL_GLContext context);
+extern void *UIKit_GL_GetProcAddress(_THIS, const char *proc);
+extern int UIKit_GL_LoadLibrary(_THIS, const char *path);
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cocoaTouch/SDLOverrides/SDL_uikitopengles.m	Tue Jan 12 07:32:15 2010 +0000
@@ -0,0 +1,139 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 1997-2009 Sam Lantinga
+ 
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+ 
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ Lesser General Public License for more details.
+ 
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ 
+ Sam Lantinga
+ slouken@libsdl.org
+ */
+
+#include "SDL_uikitopengles.h"
+#include "SDL_uikitopenglview.h"
+#include "SDL_uikitappdelegate.h"
+#include "SDL_uikitwindow.h"
+#include "jumphack.h"
+#include "SDL_sysvideo.h"
+#include "SDL_loadso.h"
+#include <dlfcn.h>
+
+static int UIKit_GL_Initialize(_THIS);
+
+void *
+UIKit_GL_GetProcAddress(_THIS, const char *proc)
+{	
+	/* Look through all SO's for the proc symbol.  Here's why:
+	   -Looking for the path to the OpenGL Library seems not to work in the iPhone Simulator.
+	   -We don't know that the path won't change in the future.
+	*/
+    return SDL_LoadFunction(RTLD_DEFAULT, proc);
+}
+
+/*
+	note that SDL_GL_Delete context makes it current without passing the window
+*/
+int UIKit_GL_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context)
+{
+	
+	if (context) {
+		SDL_WindowData *data = (SDL_WindowData *)window->driverdata;
+		[data->view setCurrentContext];
+	}
+	else {
+		[EAGLContext setCurrentContext: nil];
+	}
+		
+    return 0;
+}
+
+int
+UIKit_GL_LoadLibrary(_THIS, const char *path)
+{
+	/* 
+		shouldn't be passing a path into this function 
+		why?  Because we've already loaded the library
+		and because the SDK forbids loading an external SO
+	*/
+    if (path != NULL) {
+		SDL_SetError("iPhone GL Load Library just here for compatibility");
+		return -1;
+    }
+    return 0;
+}
+
+
+void UIKit_GL_SwapWindow(_THIS, SDL_Window * window)
+{
+
+	SDL_WindowData *data = (SDL_WindowData *)window->driverdata;
+	
+	if (nil == data->view) {
+		return;
+	}
+	[data->view swapBuffers];
+	/* since now we've got something to draw
+	   make the window visible */
+	[data->uiwindow makeKeyAndVisible];
+
+	/* we need to let the event cycle run, or the OS won't update the OpenGL view! */
+	SDL_PumpEvents();
+	
+}
+
+SDL_GLContext UIKit_GL_CreateContext(_THIS, SDL_Window * window)
+{
+	
+	SDL_uikitopenglview *view;
+
+	SDL_WindowData *data = (SDL_WindowData *)window->driverdata;
+	
+	/* construct our view, passing in SDL's OpenGL configuration data */
+	view = [[SDL_uikitopenglview alloc] initWithFrame: [[UIScreen mainScreen] applicationFrame] \
+									retainBacking: _this->gl_config.retained_backing \
+									rBits: _this->gl_config.red_size \
+									gBits: _this->gl_config.green_size \
+									bBits: _this->gl_config.blue_size \
+									aBits: _this->gl_config.alpha_size \
+									depthBits: _this->gl_config.depth_size];
+	
+	// add a tag to be able to remove from superview once finished
+	view.tag = 54867;
+	data->view = view;
+	
+	/* add the view to our window */
+	[data->uiwindow addSubview: view ];
+	
+	/* Don't worry, the window retained the view */
+	[view release];
+	
+	if ( UIKit_GL_MakeCurrent(_this, window, view) < 0 ) {
+        UIKit_GL_DeleteContext(_this, view);
+        return NULL;
+    }
+		
+	return view;
+}
+
+void UIKit_GL_DeleteContext(_THIS, SDL_GLContext context)
+{
+	/* the delegate has retained the view, this will release him */
+	SDL_uikitopenglview *view = (SDL_uikitopenglview *)context;
+	/* this will also delete it */
+	[view removeFromSuperview];
+	
+	return;
+}
+
+
--- a/cocoaTouch/gameSetup.m	Sun Jan 10 00:52:20 2010 +0000
+++ b/cocoaTouch/gameSetup.m	Tue Jan 12 07:32:15 2010 +0000
@@ -17,16 +17,26 @@
 #define BUFFER_SIZE 256
 
 
+//
+TCPsocket sd, csd; /* Socket descriptor, Client socket descriptor */
+
 @implementation gameSetup
 
+int sendToEngine(NSString *string) {
+	Uint8 length = [string length];
+	
+	SDLNet_TCP_Send(csd, &length , 1);
+	return SDLNet_TCP_Send(csd, [string UTF8String], length);
+}
+
 void engineProtocolThread () {
-	TCPsocket sd, csd; /* Socket descriptor, Client socket descriptor */
 	IPaddress ip;
 	int idx, eProto;
 	BOOL serverQuit, clientQuit;
 	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());
@@ -65,9 +75,88 @@
 			
 			if ('C' == buffer[0]) {
 				NSLog(@"engineProtocolThread - Client found and connected");
+				
+				// send config data data
+				
+				// local game
+				sendToEngine(@"TL");
+				
+				// seed info
+				sendToEngine(@"eseed {232c1b42-7d39-4ee6-adf8-4240e1f1efb8}");
+				
+				// various flags
+				sendToEngine(@"e$gmflags 256"); 
+
+				// various flags
+				sendToEngine(@"e$damagepct 100");
+				
+				// various flags
+				sendToEngine(@"e$turntime 45000");
+				
+				// various flags
+				sendToEngine(@"e$minestime 3000");
+				
+				// various flags
+				sendToEngine(@"e$landadds 4");
+				
+				// various flags
+				sendToEngine(@"e$sd_turns 15");
+												
+				// various flags
+				sendToEngine(@"e$casefreq 5");
+				
+				// various flags
+				sendToEngine(@"e$template_filter 1");
+								
+				// theme info
+				sendToEngine(@"etheme Freeway");
+				
+				// team 1 info
+				sendToEngine(@"eaddteam 4421353 System Cats");
+				
+				// team 1 grave info
+				sendToEngine(@"egrave star");
+				
+				// team 1 fort info
+				sendToEngine(@"efort  Earth");
+								
+				// team 1 voicepack info
+				sendToEngine(@"evoicepack Classic");
+				
+				// team 1 binds (skipped)				
+				// team 1 members info
+				//for (int i=0; i<4; i++) {
+					sendToEngine(@"eaddhh 0 100 Snow Leopard");
+					sendToEngine(@"ehat NoHat");
+				//}
+				// team 1 ammostore
+				sendToEngine(@"eammstore 93919294221991210322351110012010000002110404000441400444645644444774776112211144");
+
+				// team 2 info
+				sendToEngine(@"eaddteam 4100897 Poke-MAN");
+				
+				// team 2 grave info
+				sendToEngine(@"egrave Badger");
+				
+				// team 2 fort info
+				sendToEngine(@"efort UFO");
+				
+				// team 2 voicepack info
+				sendToEngine(@"evoicepack Classic");
+				
+				// team 2 binds (skipped)
+				// team 2 members info
+			//	for (int i=0; i<4; i++) {
+					sendToEngine(@"eaddhh 0 100 Raichu");
+					sendToEngine(@"ehat Bunny");
+			//	}
+				
+				// team 2 ammostore
+				sendToEngine(@"eammstore 93919294221991210322351110012010000002110404000441400444645644444774776112211144");
+				
 				clientQuit = NO;
 			} else {
-				NSLog(@"engineProtocolThread - wrong Connected message, closing");
+				NSLog(@"engineProtocolThread - wrong message, closing connection");
 				clientQuit = YES;
 			}
 			
@@ -78,25 +167,24 @@
 				msgSize = 0;
 				memset(buffer, 0, BUFFER_SIZE);
 				memset(string, 0, BUFFER_SIZE);
-				SDLNet_TCP_Recv(csd, &msgSize, sizeof(Uint8));
-			
-				SDLNet_TCP_Recv(csd, buffer, msgSize);
+				if (SDLNet_TCP_Recv(csd, &msgSize, sizeof(Uint8)) <= 0)
+					clientQuit = YES;
+				if (SDLNet_TCP_Recv(csd, buffer, msgSize) <=0)
+					clientQuit = YES;
+				
 				gameTicks = SDLNet_Read16(&buffer[msgSize - 2]);
-				NSLog(@"engineProtocolThread - %d: received [%s]", gameTicks, buffer);
+				//NSLog(@"engineProtocolThread - %d: received [%s]", gameTicks, buffer);
 				
 				switch (buffer[0]) {
 					case '?':
 						NSLog(@"Ping? Pong!");
-						string[idx++] = 0x01;
-						string[idx++] = '!';
-						
-						SDLNet_TCP_Send(csd, string, idx);
+						sendToEngine(@"!");
 						break;
 					case 'E':
 						NSLog(@"ERROR - last console line: [%s]", buffer);
 						clientQuit = YES;
 						break;
-					default:
+					case 'e':
 						sscanf(buffer, "%*s %d", &eProto);
 						if (HW_protoVer() == eProto) {
 							NSLog(@"Setting protocol version %s", buffer);
@@ -104,8 +192,21 @@
 							NSLog(@"ERROR - wrong protocol number: [%s] - expecting %d", buffer, eProto);
 							clientQuit = YES;
 						}
-						
+						break;
+					default:
+						// empty packet or just statistics
 						break;
+					case 'i':
+						switch (buffer[1]) {
+							case 'r':
+								NSLog(@"Winning team: %s", &buffer[2]);
+								break;
+							case 'k':
+								NSLog(@"Best Hedgehog: %s", &buffer[2]);
+								break;
+						}
+						break;
+					// missing case for exiting
 				} 
 				
 				/*
@@ -131,10 +232,13 @@
 	SDLNet_TCP_Close(sd);
 	SDLNet_Quit();
 
+	[pool release];
 	pthread_exit(NULL);
 }
 
 void setupArgsForLocalPlay() {
+	memset(forward_argv, 0, forward_argc);
+	
 	forward_argc = 18;
 	forward_argv = (char **)realloc(forward_argv, forward_argc * sizeof(char *));
 	//forward_argv[i] = malloc( (strlen(argv[i])+1) * sizeof(char));
--- a/hedgewars/PascalExports.pas	Sun Jan 10 00:52:20 2010 +0000
+++ b/hedgewars/PascalExports.pas	Tue Jan 12 07:32:15 2010 +0000
@@ -21,6 +21,7 @@
 // called by pascal code, they deal with the objc code
 function  IPH_getDocumentsPath: PChar; cdecl; external;
 procedure IPH_showControls; cdecl; external;
+procedure IPH_returnFrontend; cdecl; external; 
 
 // retrieve protocol information
 function  HW_protoVer: LongInt; cdecl; export;
@@ -47,6 +48,7 @@
 {$IFDEF IPHONEOS}
 function HW_protoVer: LongInt; cdecl; export;
 begin
+	WriteLnToConsole('HW - protocol version');
 	HW_protoVer:= cNetProtoVersion;
 end;
 
--- a/hedgewars/hwengine.pas	Sun Jan 10 00:52:20 2010 +0000
+++ b/hedgewars/hwengine.pas	Tue Jan 12 07:32:15 2010 +0000
@@ -146,18 +146,20 @@
 ////////////////////
 procedure OnDestroy;
 begin
-{$IFDEF DEBUGFILE}AddFileLog('Freeing resources...');{$ENDIF}
+	WriteLnToConsole('Freeing resources...');
 	if isSoundEnabled then ReleaseSound();
 	StoreRelease();
 	FreeLand();
+	ControllerClose();
 	SendKB();
 	CloseIPC();
 	TTF_Quit();
-//{$IFNDEF IPHONEOS}
-	// TODO: don't halt and don't clean, return to the previous view
 	SDL_Quit();
+{$IFDEF IPHONEOS}
+	IPH_returnFrontend();
+{$ELSE}
 	halt();
-//{$ENDIF}
+{$ENDIF}
 end;
 
 ///////////////////
@@ -478,7 +480,7 @@
 TryDo(InitStepsFlags = cifAllInited, 'Some parameters not set (flags = ' + inttostr(InitStepsFlags) + ')', true);
 
 MainLoop;
-ControllerClose
+ControllerClose();
 end;
 
 /////////////////////////
@@ -496,7 +498,7 @@
 h:= MaxHedgehogs;
 SendIPCRaw(@h, sizeof(h));
 WriteLnToConsole('Preview sent, disconnect');
-CloseIPC
+CloseIPC();
 end;
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -504,12 +506,13 @@
 ////////////////////////////////////////////////////////////////////////////////
 
 begin
-WriteLnToConsole('Hedgewars ' + cVersionString + ' engine (network protocol: ' + inttostr(cNetProtoVersion) + ')');
-GetParams;
+	WriteLnToConsole('Hedgewars ' + cVersionString + ' engine (network protocol: ' + inttostr(cNetProtoVersion) + ')');
+	GetParams;
 
-Randomize;
+	Randomize;
 
-if GameType = gmtLandPreview then GenLandPreview
-                             else Game
+	if GameType = gmtLandPreview then GenLandPreview
+								 else Game;
+//	ExitCode := 100;
 end.
 
--- a/hedgewars/uLand.pas	Sun Jan 10 00:52:20 2010 +0000
+++ b/hedgewars/uLand.pas	Tue Jan 12 07:32:15 2010 +0000
@@ -28,7 +28,7 @@
 {$ENDIF}
 	uConsts;
 type TLandArray = packed array[0 .. LAND_HEIGHT - 1, 0 .. LAND_WIDTH - 1] of LongWord;
-TCollisionArray = packed array[0 .. LAND_HEIGHT - 1, 0 .. LAND_WIDTH - 1] of Word;
+	TCollisionArray = packed array[0 .. LAND_HEIGHT - 1, 0 .. LAND_WIDTH - 1] of Word;
 	TPreview  = packed array[0..127, 0..31] of byte;
 	TDirtyTag = packed array[0 .. LAND_HEIGHT div 32 - 1, 0 .. LAND_WIDTH div 32 - 1] of byte;
 
@@ -43,7 +43,7 @@
 procedure GenMap;
 function  GenPreview: TPreview;
 procedure CheckLandDigest(s: shortstring);
-function LandBackPixel(x, y: LongInt): LongWord;
+function  LandBackPixel(x, y: LongInt): LongWord;
 
 implementation
 uses uConsole, uStore, uMisc, uRandom, uTeams, uLandObjects, uSHA, uIO, uAmmos, uLandTexture;