# HG changeset patch # User koda # Date 1263084740 0 # Node ID c0da3a98c01c6e42150a7c9afb86881be5acbc43 # Parent 8e83c7e3172080623c81ad761687cadc299436d7 initial support for engine protocol diff -r 8e83c7e31720 -r c0da3a98c01c cocoaTouch/SDLOverrides/SDL_uikitappdelegate.h --- a/cocoaTouch/SDLOverrides/SDL_uikitappdelegate.h Sat Jan 09 01:34:23 2010 +0000 +++ b/cocoaTouch/SDLOverrides/SDL_uikitappdelegate.h Sun Jan 10 00:52:20 2010 +0000 @@ -37,4 +37,6 @@ +(SDLUIKitDelegate *)sharedAppDelegate; -(void) startSDLgame; +int forward_argc; +char **forward_argv; @end diff -r 8e83c7e31720 -r c0da3a98c01c cocoaTouch/SDLOverrides/SDL_uikitappdelegate.m --- a/cocoaTouch/SDLOverrides/SDL_uikitappdelegate.m Sat Jan 09 01:34:23 2010 +0000 +++ b/cocoaTouch/SDLOverrides/SDL_uikitappdelegate.m Sun Jan 10 00:52:20 2010 +0000 @@ -20,19 +20,19 @@ slouken@libsdl.org, vittorio.giovara@gmail.com */ +#import #import "SDL_uikitappdelegate.h" #import "SDL_uikitopenglview.h" #import "SDL_events_c.h" #import "jumphack.h" #import "SDL_video.h" +#import "gameSetup.h" #ifdef main #undef main #endif extern int SDL_main(int argc, char *argv[]); -static int forward_argc; -static char **forward_argv; int main (int argc, char **argv) { int i; @@ -62,10 +62,17 @@ return (SDLUIKitDelegate *)[[UIApplication sharedApplication] delegate]; } + - (void) startSDLgame { + pthread_t threadID; + pthread_create (&threadID, NULL, (void *) (*engineProtocolThread), NULL); + pthread_detach (threadID); + + setupArgsForLocalPlay(); + /* run the user's application, passing argc and argv */ - NSLog(@"Game is launching"); + NSLog(@"Game is launching..."); SDL_main(forward_argc, forward_argv); // can't reach here yet NSLog(@"Game exited"); @@ -87,6 +94,9 @@ [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 { diff -r 8e83c7e31720 -r c0da3a98c01c cocoaTouch/gameSetup.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/cocoaTouch/gameSetup.h Sun Jan 10 00:52:20 2010 +0000 @@ -0,0 +1,19 @@ +// +// gameSetup.h +// hwengine +// +// Created by Vittorio on 10/01/10. +// Copyright 2010 __MyCompanyName__. All rights reserved. +// + +#import + + +@interface gameSetup : NSObject { + +} + +@end + +void engineProtocolThread (); +void setupArgsForLocalPlay(); diff -r 8e83c7e31720 -r c0da3a98c01c cocoaTouch/gameSetup.m --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/cocoaTouch/gameSetup.m Sun Jan 10 00:52:20 2010 +0000 @@ -0,0 +1,162 @@ +// +// gameSetup.m +// hwengine +// +// Created by Vittorio on 10/01/10. +// Copyright 2010 __MyCompanyName__. All rights reserved. +// + +#import +#import "SDL_uikitappdelegate.h" +#import "gameSetup.h" +#import "SDL_net.h" +#import "PascalImports.h" + +#define IPC_PORT 51342 +#define IPC_PORT_STR "51342" +#define BUFFER_SIZE 256 + + +@implementation gameSetup + +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; + + if (SDLNet_Init() < 0) { + fprintf(stderr, "SDLNet_Init: %s\n", SDLNet_GetError()); + exit(EXIT_FAILURE); + } + + /* Resolving the host using NULL make network interface to listen */ + if (SDLNet_ResolveHost(&ip, NULL, IPC_PORT) < 0) { + fprintf(stderr, "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()); + exit(EXIT_FAILURE); + } + + NSLog(@"engineProtocolThread - Waiting for a client"); + + serverQuit = NO; + while (!serverQuit) { + + /* This check the sd if there is a pending connection. + * If there is one, accept that, and open a new socket for communicating */ + if ((csd = SDLNet_TCP_Accept(sd))) { + + NSLog(@"engineProtocolThread - Client found"); + + //first byte of the command alwayas contain the size of the command + SDLNet_TCP_Recv(csd, &msgSize, sizeof(Uint8)); + + SDLNet_TCP_Recv(csd, buffer, msgSize); + gameTicks = SDLNet_Read16(&buffer[msgSize - 2]); + NSLog(@"engineProtocolThread - %d: received [%s]", gameTicks, buffer); + + if ('C' == buffer[0]) { + NSLog(@"engineProtocolThread - Client found and connected"); + clientQuit = NO; + } else { + NSLog(@"engineProtocolThread - wrong Connected message, closing"); + clientQuit = YES; + } + + while (!clientQuit){ + /* Now we can communicate with the client using csd socket + * sd will remain opened waiting other connections */ + idx = 0; + 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); + gameTicks = SDLNet_Read16(&buffer[msgSize - 2]); + 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); + break; + case 'E': + NSLog(@"ERROR - last console line: [%s]", buffer); + clientQuit = YES; + break; + default: + sscanf(buffer, "%*s %d", &eProto); + if (HW_protoVer() == eProto) { + NSLog(@"Setting protocol version %s", buffer); + } else { + NSLog(@"ERROR - wrong protocol number: [%s] - expecting %d", buffer, eProto); + clientQuit = YES; + } + + break; + } + + /* + // Terminate this connection + if(strcmp(buffer, "exit") == 0) { + quit2 = 1; + printf("Terminate connection\n"); + } + // Quit the thread + if(strcmp(buffer, "quit") == 0) { + quit2 = 1; + quit = 1; + printf("Quit program\n"); + } + */ + } + } + + /* Close the client socket */ + SDLNet_TCP_Close(csd); + } + + SDLNet_TCP_Close(sd); + SDLNet_Quit(); + + pthread_exit(NULL); +} + +void setupArgsForLocalPlay() { + forward_argc = 18; + forward_argv = (char **)realloc(forward_argv, forward_argc * sizeof(char *)); + //forward_argv[i] = malloc( (strlen(argv[i])+1) * sizeof(char)); + forward_argv[ 1] = forward_argv[0]; // (UNUSED) + forward_argv[ 2] = "320"; // cScreenWidth (NO EFFECT) + forward_argv[ 3] = "480"; // cScreenHeight (NO EFFECT) + forward_argv[ 4] = "32"; // cBitsStr + forward_argv[ 5] = IPC_PORT_STR; // ipcPort; <- (MAIN TODO) + forward_argv[ 6] = "1"; // cFullScreen (NO EFFECT) + forward_argv[ 7] = "0"; // isSoundEnabled (TOSET) + forward_argv[ 8] = "1"; // cVSyncInUse (UNUSED) + forward_argv[ 9] = "en.txt"; // cLocaleFName (TOSET) + forward_argv[10] = "100"; // cInitVolume (TOSET) + forward_argv[11] = "8"; // cTimerInterval + forward_argv[12] = "Data"; // PathPrefix + forward_argv[13] = "1"; // cShowFPS (TOSET?) + forward_argv[14] = "0"; // cAltDamage (TOSET) + forward_argv[15] = "Koda"; // UserNick (DecodeBase64(ParamStr(15)) FTW) <- TODO + forward_argv[16] = "0"; // isMusicEnabled (TOSET) + forward_argv[17] = "0"; // cReducedQuality + + return; +} + +@end diff -r 8e83c7e31720 -r c0da3a98c01c cocoaTouch/otherSrc/PascalImports.h --- a/cocoaTouch/otherSrc/PascalImports.h Sat Jan 09 01:34:23 2010 +0000 +++ b/cocoaTouch/otherSrc/PascalImports.h Sun Jan 10 00:52:20 2010 +0000 @@ -18,6 +18,8 @@ * that you want to use */ + int HW_protoVer(void); + void HW_click(void); void HW_zoomIn(void); void HW_zoomOut(void); diff -r 8e83c7e31720 -r c0da3a98c01c hedgewars/PascalExports.pas --- a/hedgewars/PascalExports.pas Sat Jan 09 01:34:23 2010 +0000 +++ b/hedgewars/PascalExports.pas Sun Jan 10 00:52:20 2010 +0000 @@ -15,11 +15,16 @@ interface uses uKeys, uConsole; +{$INCLUDE "proto.inc"} + {$IFDEF IPHONEOS} // called by pascal code, they deal with the objc code function IPH_getDocumentsPath: PChar; cdecl; external; procedure IPH_showControls; cdecl; external; +// retrieve protocol information +function HW_protoVer: LongInt; cdecl; export; + // called by the touch functions (SDL_uikitview.m) // they emulate user interaction from mouse or keyboard procedure HW_click; cdecl; export; @@ -40,6 +45,11 @@ implementation {$IFDEF IPHONEOS} +function HW_protoVer: LongInt; cdecl; export; +begin + HW_protoVer:= cNetProtoVersion; +end; + procedure HW_click; cdecl; export; begin WriteLnToConsole('HW - left click'); diff -r 8e83c7e31720 -r c0da3a98c01c hedgewars/hwengine.pas --- a/hedgewars/hwengine.pas Sat Jan 09 01:34:23 2010 +0000 +++ b/hedgewars/hwengine.pas Sun Jan 10 00:52:20 2010 +0000 @@ -236,6 +236,7 @@ ///////////////////// procedure DisplayUsage; +var i: LongInt; begin WriteLn('Wrong argument format: correct configurations is'); WriteLn(); @@ -249,6 +250,9 @@ WriteLn(' --set-everything [screen height] [screen width] [color dept] [volume] [enable music] [enable sounds] [language file] [full screen] [show FPS] [alternate damage] [timer value] [reduced quality]'); WriteLn(); WriteLn('Read documentation online at http://www.hedgewars.org/node/1465 for more information'); + Write('parsed command: '); + for i:=0 to ParamCount do Write(ParamStr(i) + ' '); + WriteLn(); halt(1); end; diff -r 8e83c7e31720 -r c0da3a98c01c hedgewars/uIO.pas --- a/hedgewars/uIO.pas Sat Jan 09 01:34:23 2010 +0000 +++ b/hedgewars/uIO.pas Sun Jan 10 00:52:20 2010 +0000 @@ -158,7 +158,7 @@ begin buf[0]:= i; ss:= ss + s; - while (Length(ss) > 1)and(Length(ss) > byte(ss[1])) do + while (Length(ss) > 1) and (Length(ss) > byte(ss[1])) do begin ParseIPCCommand(copy(ss, 2, byte(ss[1]))); Delete(ss, 1, Succ(byte(ss[1]))) @@ -205,7 +205,7 @@ SendEmptyPacketTicks:= 0; if s[0]>#251 then s[0]:= #251; SDLNet_Write16(GameTicks, @s[Succ(byte(s[0]))]); - {$IFDEF DEBUGFILE}AddFileLog('IPC send: '+s[1]);{$ENDIF} + {$IFDEF DEBUGFILE}AddFileLog('IPC send: '+ s[1]);{$ENDIF} inc(s[0], 2); SDLNet_TCP_Send(IPCSock, @s, Succ(byte(s[0]))) end diff -r 8e83c7e31720 -r c0da3a98c01c hedgewars/uMisc.pas --- a/hedgewars/uMisc.pas Sat Jan 09 01:34:23 2010 +0000 +++ b/hedgewars/uMisc.pas Sun Jan 10 00:52:20 2010 +0000 @@ -595,6 +595,7 @@ ParamStr(1) {$ENDIF} + '/debug' + inttostr(i) + '.txt'); +// f:= stderr; rewrite(f); if IOResult = 5 then begin