project_files/HedgewarsMobile/Classes/GameSetup.m
changeset 4754 a0fd8211c00f
parent 4605 a5c2f09daaaa
child 4757 7ca9ebb6895d
equal deleted inserted replaced
4752:d65705a67c4e 4754:a0fd8211c00f
    26 #import "OverlayViewController.h"
    26 #import "OverlayViewController.h"
    27 
    27 
    28 #define BUFFER_SIZE 255     // like in original frontend
    28 #define BUFFER_SIZE 255     // like in original frontend
    29 
    29 
    30 @implementation GameSetup
    30 @implementation GameSetup
    31 @synthesize systemSettings, gameConfig, savePath, menuStyle;
    31 @synthesize systemSettings, gameConfig, statsDictionary, savePath, menuStyle;
    32 
    32 
    33 -(id) initWithDictionary:(NSDictionary *)gameDictionary {
    33 -(id) initWithDictionary:(NSDictionary *)gameDictionary {
    34     if (self = [super init]) {
    34     if (self = [super init]) {
    35         ipcPort = randomPort();
    35         ipcPort = randomPort();
    36 
    36 
    55             NSString *newDateString = [outputFormatter stringFromDate:[NSDate date]];
    55             NSString *newDateString = [outputFormatter stringFromDate:[NSDate date]];
    56             self.savePath = [SAVES_DIRECTORY() stringByAppendingFormat:@"%@.hws", newDateString];
    56             self.savePath = [SAVES_DIRECTORY() stringByAppendingFormat:@"%@.hws", newDateString];
    57             [outputFormatter release];
    57             [outputFormatter release];
    58         } else
    58         } else
    59             self.savePath = path;
    59             self.savePath = path;
       
    60 
       
    61         self.statsDictionary = nil;
    60     }
    62     }
    61     return self;
    63     return self;
    62 }
    64 }
    63 
    65 
    64 -(void) dealloc {
    66 -(void) dealloc {
       
    67     [statsDictionary release];
    65     [gameConfig release];
    68     [gameConfig release];
    66     [systemSettings release];
    69     [systemSettings release];
    67     [savePath release];
    70     [savePath release];
    68     [super dealloc];
    71     [super dealloc];
    69 }
    72 }
   202     return result;
   205     return result;
   203 }
   206 }
   204 
   207 
   205 #pragma mark -
   208 #pragma mark -
   206 #pragma mark Network relevant code
   209 #pragma mark Network relevant code
   207 -(void) dumpRawData:(const uint8_t*)buffer ofSize:(uint8_t) length {
   210 -(void) dumpRawData:(const char *)buffer ofSize:(uint8_t) length {
   208     // is it performant to reopen the stream every time?
   211     // is it performant to reopen the stream every time?
   209     NSOutputStream *os = [[NSOutputStream alloc] initToFileAtPath:self.savePath append:YES];
   212     NSOutputStream *os = [[NSOutputStream alloc] initToFileAtPath:self.savePath append:YES];
   210     [os open];
   213     [os open];
   211     [os write:&length maxLength:1];
   214     [os write:&length maxLength:1];
   212     [os write:buffer maxLength:length];
   215     [os write:(const uint8_t *)buffer maxLength:length];
   213     [os close];
   216     [os close];
   214     [os release];
   217     [os release];
   215 }
   218 }
   216 
   219 
   217 // wrapper that computes the length of the message and then sends the command string, saving the command on a file
   220 // wrapper that computes the length of the message and then sends the command string, saving the command on a file
   218 -(int) sendToEngine:(NSString *)string {
   221 -(int) sendToEngine:(NSString *)string {
   219     uint8_t length = [string length];
   222     uint8_t length = [string length];
   220 
   223 
   221     [self dumpRawData:(const uint8_t *)[string UTF8String] ofSize:length];
   224     [self dumpRawData:[string UTF8String] ofSize:length];
   222     SDLNet_TCP_Send(csd, &length, 1);
   225     SDLNet_TCP_Send(csd, &length, 1);
   223     return SDLNet_TCP_Send(csd, [string UTF8String], length);
   226     return SDLNet_TCP_Send(csd, [string UTF8String], length);
   224 }
   227 }
   225 
   228 
   226 // wrapper that computes the length of the message and then sends the command string, skipping file writing
   229 // wrapper that computes the length of the message and then sends the command string, skipping file writing
   236     NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
   239     NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
   237     TCPsocket sd;
   240     TCPsocket sd;
   238     IPaddress ip;
   241     IPaddress ip;
   239     int eProto;
   242     int eProto;
   240     BOOL clientQuit;
   243     BOOL clientQuit;
   241     uint8_t buffer[BUFFER_SIZE];
   244     char const buffer[BUFFER_SIZE];
   242     uint8_t msgSize;
   245     uint8_t msgSize;
   243 
   246 
   244     clientQuit = NO;
   247     clientQuit = NO;
   245     csd = NULL;
   248     csd = NULL;
   246 
   249 
   266         csd = SDLNet_TCP_Accept(sd);
   269         csd = SDLNet_TCP_Accept(sd);
   267     SDLNet_TCP_Close(sd);
   270     SDLNet_TCP_Close(sd);
   268 
   271 
   269     while (!clientQuit) {
   272     while (!clientQuit) {
   270         msgSize = 0;
   273         msgSize = 0;
   271         memset(buffer, '\0', BUFFER_SIZE);
   274         memset((void *)buffer, '\0', BUFFER_SIZE);
   272         if (SDLNet_TCP_Recv(csd, &msgSize, sizeof(uint8_t)) <= 0)
   275         if (SDLNet_TCP_Recv(csd, &msgSize, sizeof(uint8_t)) <= 0)
   273             break;
   276             break;
   274         if (SDLNet_TCP_Recv(csd, buffer, msgSize) <=0)
   277         if (SDLNet_TCP_Recv(csd, (void *)buffer, msgSize) <= 0)
   275             break;
   278             break;
   276 
   279 
   277         switch (buffer[0]) {
   280         switch (buffer[0]) {
   278             case 'C':
   281             case 'C':
   279                 DLog(@"sending game config...\n%@",self.gameConfig);
   282                 DLog(@"sending game config...\n%@",self.gameConfig);
   281                 if (isNetGame == YES)
   284                 if (isNetGame == YES)
   282                     [self sendToEngineNoSave:@"TN"];
   285                     [self sendToEngineNoSave:@"TN"];
   283                 else
   286                 else
   284                     [self sendToEngineNoSave:@"TL"];
   287                     [self sendToEngineNoSave:@"TL"];
   285                 NSString *saveHeader = @"TS";
   288                 NSString *saveHeader = @"TS";
   286                 [self dumpRawData:(const uint8_t *)[saveHeader UTF8String] ofSize:[saveHeader length]];
   289                 [self dumpRawData:[saveHeader UTF8String] ofSize:[saveHeader length]];
   287 
   290 
   288                 // seed info
   291                 // seed info
   289                 [self sendToEngine:[self.gameConfig objectForKey:@"seed_command"]];
   292                 [self sendToEngine:[self.gameConfig objectForKey:@"seed_command"]];
   290 
   293 
   291                 // dimension of the map
   294                 // dimension of the map
   343                     DLog(@"ERROR - wrong protocol number: %d (expecting %d)", netProto, eProto);
   346                     DLog(@"ERROR - wrong protocol number: %d (expecting %d)", netProto, eProto);
   344                     clientQuit = YES;
   347                     clientQuit = YES;
   345                 }
   348                 }
   346                 break;
   349                 break;
   347             case 'i':
   350             case 'i':
       
   351                 // initialized with maximum
       
   352                 if (self.statsDictionary == nil)
       
   353                     self.statsDictionary = [[NSMutableDictionary alloc] initWithCapacity:10];
   348                 switch (buffer[1]) {
   354                 switch (buffer[1]) {
   349                     case 'r':
   355                     case 'r':
   350                         DLog(@"Winning team: %s", &buffer[2]);
   356                         DLog(@"Winning team: %s", &buffer[2]);
       
   357                         [self.statsDictionary setObject:[NSString stringWithUTF8String:&buffer[2]] forKey:@"winning_team"];
   351                         break;
   358                         break;
   352                     case 'D':
   359                     case 'D':
   353                         DLog(@"Best Shot: %s", &buffer[2]);
   360                         DLog(@"Best Shot: %s", &buffer[2]);
       
   361                         [self.statsDictionary setObject:[NSString stringWithUTF8String:&buffer[2]] forKey:@"best_shot"];
   354                         break;
   362                         break;
   355                     case 'k':
   363                     case 'k':
   356                         DLog(@"Best Hedgehog: %s", &buffer[2]);
   364                         DLog(@"Best Hedgehog: %s", &buffer[2]);
       
   365                         [self.statsDictionary setObject:[NSString stringWithUTF8String:&buffer[2]] forKey:@"best_hog"];
   357                         break;
   366                         break;
   358                     case 'K':
   367                     case 'K':
   359                         DLog(@"Hogs Killed: %s", &buffer[2]);
   368                         DLog(@"Hogs Killed: %s", &buffer[2]);
       
   369                         [self.statsDictionary setObject:[NSString stringWithUTF8String:&buffer[2]] forKey:@"kills"];
   360                         break;
   370                         break;
   361                     case 'H':
   371                     case 'H':
   362                         //something about team health
   372                         //something about team health
   363                         break;
   373                         break;
   364                     case 'T':
   374                     case 'T':
   367                     case 'P':
   377                     case 'P':
   368                         // player postion
   378                         // player postion
   369                         break;
   379                         break;
   370                     case 's':
   380                     case 's':
   371                         DLog(@"Most self damage: %s", &buffer[2]);
   381                         DLog(@"Most self damage: %s", &buffer[2]);
       
   382                         [self.statsDictionary setObject:[NSString stringWithUTF8String:&buffer[2]] forKey:@"self_dmg"];
   372                         break;
   383                         break;
   373                     case 'S':
   384                     case 'S':
   374                         DLog(@"Most friendly fire: %s", &buffer[2]);
   385                         DLog(@"Most friendly fire: %s", &buffer[2]);
       
   386                         [self.statsDictionary setObject:[NSString stringWithUTF8String:&buffer[2]] forKey:@"friendly_fire"];
   375                         break;
   387                         break;
   376                     case 'B':
   388                     case 'B':
   377                         DLog(@"Most turn skipped by: %s", &buffer[2]);
   389                         DLog(@"Most turn skipped by: %s", &buffer[2]);
       
   390                         [self.statsDictionary setObject:[NSString stringWithUTF8String:&buffer[2]] forKey:@"turn_skips"];
   378                         break;
   391                         break;
   379                     default:
   392                     default:
   380                         DLog(@"Unhandled stat message, see statsPage.cpp");
   393                         DLog(@"Unhandled stat message, see statsPage.cpp");
   381                         break;
   394                         break;
   382                 }
   395                 }
   383                 break;
   396                 break;
   384             case 'q':
   397             case 'q':
   385                 // game ended, can remove the savefile
   398                 // game ended, can remove the savefile
   386                 [[NSFileManager defaultManager] removeItemAtPath:self.savePath error:nil];
   399                 [[NSFileManager defaultManager] removeItemAtPath:self.savePath error:nil];
   387                 //[[NSNotificationCenter defaultCenter] postNotificationName:@"removedSave" object:nil];
       
   388                 // and remove + disable the overlay
   400                 // and remove + disable the overlay
   389                 [[NSNotificationCenter defaultCenter] postNotificationName:@"remove overlay" object:nil];
   401                 [[NSNotificationCenter defaultCenter] postNotificationName:@"remove overlay" object:nil];
   390                 break;
   402                 break;
   391             default:
   403             default:
   392                 [self dumpRawData:buffer ofSize:msgSize];
   404                 [self dumpRawData:buffer ofSize:msgSize];
   406 }
   418 }
   407 
   419 
   408 #pragma mark -
   420 #pragma mark -
   409 #pragma mark Setting methods
   421 #pragma mark Setting methods
   410 // returns an array of c-strings that are read by engine at startup
   422 // returns an array of c-strings that are read by engine at startup
   411 -(const char **)getSettings: (NSString *)recordFile {
   423 -(const char **)getGameSettings:(NSString *)recordFile {
   412     NSInteger width, height;
   424     NSInteger width, height;
   413     NSString *ipcString = [[NSString alloc] initWithFormat:@"%d", ipcPort];
   425     NSString *ipcString = [[NSString alloc] initWithFormat:@"%d", ipcPort];
   414     NSString *localeString = [[NSString alloc] initWithFormat:@"%@.txt", [[NSLocale currentLocale] objectForKey:NSLocaleLanguageCode]];
   426     NSString *localeString = [[NSString alloc] initWithFormat:@"%@.txt", [[NSLocale currentLocale] objectForKey:NSLocaleLanguageCode]];
   415     NSString *rotation;
   427     NSString *rotation;
   416     if (IS_DUALHEAD()) {
   428     if (IS_DUALHEAD()) {
   429             rotation = @"90";
   441             rotation = @"90";
   430     }
   442     }
   431         
   443         
   432     NSString *horizontalSize = [[NSString alloc] initWithFormat:@"%d", width];
   444     NSString *horizontalSize = [[NSString alloc] initWithFormat:@"%d", width];
   433     NSString *verticalSize = [[NSString alloc] initWithFormat:@"%d", height];
   445     NSString *verticalSize = [[NSString alloc] initWithFormat:@"%d", height];
   434     const char **gameArgs = (const char**) malloc(sizeof(char *) * 10);
   446     const char **gameArgs = (const char **)malloc(sizeof(char *) * 10);
       
   447     BOOL enhanced = [[self.systemSettings objectForKey:@"enhanced"] boolValue];
       
   448 
       
   449     NSString *modelId = modelType();
   435     NSInteger tmpQuality;
   450     NSInteger tmpQuality;
   436     BOOL enhanced = [[self.systemSettings objectForKey:@"enhanced"] boolValue];
       
   437 
       
   438     NSString *modelId = modelType();
       
   439     if ([modelId hasPrefix:@"iPhone1"] || [modelId hasPrefix:@"iPod1,1"] || [modelId hasPrefix:@"iPod2,1"])     // = iPhone and iPhone 3G or iPod Touch or iPod Touch 2G
   451     if ([modelId hasPrefix:@"iPhone1"] || [modelId hasPrefix:@"iPod1,1"] || [modelId hasPrefix:@"iPod2,1"])     // = iPhone and iPhone 3G or iPod Touch or iPod Touch 2G
   440         tmpQuality = 0x00000001 | 0x00000002 | 0x00000008 | 0x00000040;                 // rqLowRes | rqBlurryLand | rqSimpleRope | rqKillFlakes
   452         tmpQuality = 0x00000001 | 0x00000002 | 0x00000008 | 0x00000040;                 // rqLowRes | rqBlurryLand | rqSimpleRope | rqKillFlakes
   441     else if ([modelId hasPrefix:@"iPhone2"] || [modelId hasPrefix:@"iPod3"])                                    // = iPhone 3GS or iPod Touch 3G
   453     else if ([modelId hasPrefix:@"iPhone2"] || [modelId hasPrefix:@"iPod3"])                                    // = iPhone 3GS or iPod Touch 3G
   442         tmpQuality = 0x00000002 | 0x00000040;                                           // rqBlurryLand | rqKillFlakes
   454         tmpQuality = 0x00000002 | 0x00000040;                                           // rqBlurryLand | rqKillFlakes
   443     else if ([modelId hasPrefix:@"iPad1"] || [modelId hasPrefix:@"iPod4"] || enhanced == NO)                    // = iPad 1G or iPod Touch 4G or not enhanced mode
   455     else if ([modelId hasPrefix:@"iPad1"] || [modelId hasPrefix:@"iPod4"] || enhanced == NO)                    // = iPad 1G or iPod Touch 4G or not enhanced mode