# HG changeset patch # User koda # Date 1275589916 0 # Node ID 07256e1ad55916ce463b904a7d31522363e20e26 # Parent 4619b1ae99b568ad4574b959444ecd6fdec3c6ad map preview generation reworked like nemo suggested (he was right, it's quickier in this way) add some rounding image capabilities for more professional look diff -r 4619b1ae99b5 -r 07256e1ad559 cocoaTouch/MapConfigViewController.h --- a/cocoaTouch/MapConfigViewController.h Thu Jun 03 14:03:48 2010 +0000 +++ b/cocoaTouch/MapConfigViewController.h Thu Jun 03 18:31:56 2010 +0000 @@ -11,7 +11,6 @@ @interface MapConfigViewController : UIViewController { TCPsocket sd, csd; - unsigned char map[128*32]; NSInteger oldValue; //slider NSInteger oldPage; //segmented control BOOL busy; @@ -63,7 +62,9 @@ -(IBAction) segmentedControlChanged:(id) sender; -(void) turnOnWidgets; -(void) turnOffWidgets; +-(void) setLabelText:(NSString *)str; +-(void) setButtonImage:(UIImage *)img; --(void) engineProtocol:(NSInteger) port; +-(uint8_t *)engineProtocol:(NSInteger) port; @end diff -r 4619b1ae99b5 -r 07256e1ad559 cocoaTouch/MapConfigViewController.m --- a/cocoaTouch/MapConfigViewController.m Thu Jun 03 14:03:48 2010 +0000 +++ b/cocoaTouch/MapConfigViewController.m Thu Jun 03 18:31:56 2010 +0000 @@ -33,9 +33,10 @@ return SDLNet_TCP_Send(csd, [string UTF8String], length); } --(void) engineProtocol:(NSInteger) port { +-(uint8_t *)engineProtocol:(NSInteger) port { IPaddress ip; BOOL serverQuit = NO; + uint8_t map[128*32]; if (SDLNet_Init() < 0) { NSLog(@"SDLNet_Init: %s", SDLNet_GetError()); @@ -54,6 +55,11 @@ serverQuit = YES; } + // launch the preview here so that we're sure the tcp channel is open + pthread_t thread_id; + pthread_create(&thread_id, NULL, (void *)GenLandPreview, (void *)port); + pthread_detach(thread_id); + DLog(@"Waiting for a client on port %d", port); while (!serverQuit) { /* This check the sd if there is a pending connection. @@ -79,54 +85,46 @@ SDLNet_TCP_Close(sd); SDLNet_Quit(); + return map; } -(void) drawingThread { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - // select the port for IPC and launch the preview generation + // select the port for IPC and launch the preview generation through engineProtocol: int port = randomPort(); - pthread_t thread_id; - pthread_create(&thread_id, NULL, (void *)GenLandPreview, (void *)port); - pthread_detach(thread_id); - [self engineProtocol:port]; + uint8_t *map = [self engineProtocol:port]; + uint8_t mapExp[128*32*8]; // draw the buffer (1 pixel per component, 0= transparent 1= color) - int xc = 0; - int yc = -1; - UIGraphicsBeginImageContext(CGSizeMake(256,128)); - CGContextRef context = UIGraphicsGetCurrentContext(); - UIGraphicsPushContext(context); + int k = 0; for (int i = 0; i < 32*128; i++) { unsigned char byte = map[i]; for (int j = 0; j < 8; j++) { // select the color based on the leftmost bit if ((byte & 0x80) != 0) - CGContextSetRGBFillColor(context, 0.5, 0.5, 0.7, 1.0); + mapExp[k] = 100; else - CGContextSetRGBFillColor(context, 0.0, 0.0, 0.0, 0.0); - // draw pixel - CGContextFillRect(context,CGRectMake(xc,yc,1,1)); - // move coordinates - xc = (xc + 1) % 256; - if (xc == 0) yc++; + mapExp[k] = 255; // shift to next bit byte <<= 1; + k++; } } - UIGraphicsPopContext(); - UIImage *previewImage = UIGraphicsGetImageFromCurrentImageContext(); - UIGraphicsEndImageContext(); + CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceGray(); + CGContextRef bitmapImage = CGBitmapContextCreate(mapExp, 256, 128, 8, 256, colorspace, kCGImageAlphaNone); + CGColorSpaceRelease(colorspace); + + CGImageRef previewCGImage = CGBitmapContextCreateImage(bitmapImage); + UIImage *previewImage = [[UIImage alloc] initWithCGImage:previewCGImage]; + CGImageRelease(previewCGImage); - // set the preview image (autoreleased) in the button and the maxhog label - [self.previewButton setBackgroundImage:previewImage forState:UIControlStateNormal]; - self.maxLabel.text = [NSString stringWithFormat:@"%d", maxHogs]; + // set the preview image (autoreleased) in the button and the maxhog label on the main thread to prevent a leak + [self performSelectorOnMainThread:@selector(setButtonImage:) withObject:[previewImage makeRoundCornersOfSize:CGSizeMake(12, 12)] waitUntilDone:NO]; + [self performSelectorOnMainThread:@selector(setLabelText:) withObject:[NSString stringWithFormat:@"%d", maxHogs] waitUntilDone:NO]; - // restore functionality of button and remove the spinning wheel - [self turnOnWidgets]; - UIActivityIndicatorView *indicator = (UIActivityIndicatorView *)[self.previewButton viewWithTag:INDICATOR_TAG]; - [indicator stopAnimating]; - [indicator removeFromSuperview]; + // restore functionality of button and remove the spinning wheel on the main thread to prevent a leak + [self performSelectorOnMainThread:@selector(turnOnWidgets) withObject:nil waitUntilDone:NO]; [pool release]; //Invoking this method should be avoided as it does not give your thread a chance to clean up any resources it allocated during its execution. @@ -134,13 +132,16 @@ /* // http://developer.apple.com/mac/library/qa/qa2001/qa1037.html - CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceGray(); - CGContextRef bitmapImage = CGBitmapContextCreate(mapExp, 128, 32, 8, 128, colorspace, kCGImageAlphaNone); - CGColorSpaceRelease(colorspace); + UIGraphicsBeginImageContext(CGSizeMake(256,128)); + CGContextRef context = UIGraphicsGetCurrentContext(); + UIGraphicsPushContext(context); + + CGContextSetRGBFillColor(context, 0.5, 0.5, 0.7, 1.0); + CGContextFillRect(context,CGRectMake(xc,yc,1,1)); - CGImageRef previewCGImage = CGBitmapContextCreateImage(bitmapImage); - UIImage *previewImage = [[UIImage alloc] initWithCGImage:previewCGImage]; - CGImageRelease(previewCGImage); + UIGraphicsPopContext(); + UIImage *previewImage = UIGraphicsGetImageFromCurrentImageContext(); + UIGraphicsEndImageContext(); */ } @@ -192,9 +193,8 @@ NSString *fileImage = [[NSString alloc] initWithFormat:@"%@/%@/preview.png", MAPS_DIRECTORY(),[self.mapArray objectAtIndex:index]]; UIImage *image = [[UIImage alloc] initWithContentsOfFile:fileImage]; [fileImage release]; - [self.previewButton setBackgroundImage:image forState:UIControlStateNormal]; - [image release]; - + [self.previewButton setImage:[image makeRoundCornersOfSize:CGSizeMake(12, 12)] forState:UIControlStateNormal]; + // update label maxHogs = 18; NSString *fileCfg = [[NSString alloc] initWithFormat:@"%@/%@/map.cfg", MAPS_DIRECTORY(),[self.mapArray objectAtIndex:index]]; @@ -227,8 +227,37 @@ self.segmentedControl.enabled = YES; self.slider.enabled = YES; busy = NO; + + UIActivityIndicatorView *indicator = (UIActivityIndicatorView *)[self.previewButton viewWithTag:INDICATOR_TAG]; + if (indicator) { + [indicator stopAnimating]; + [indicator removeFromSuperview]; + } } + +-(void) setLabelText:(NSString *)str { + self.maxLabel.text = str; +} + +-(void) setButtonImage:(UIImage *)img { + [self.previewButton setBackgroundImage:img forState:UIControlStateNormal]; +} + +-(void) restoreBackgroundImage { + // white rounded rectangle as background image for previewButton + UIGraphicsBeginImageContext(CGSizeMake(256,128)); + CGContextRef context = UIGraphicsGetCurrentContext(); + UIGraphicsPushContext(context); + + CGContextSetRGBFillColor(context, 1.0, 1.0, 1.0, 1.0); + CGContextFillRect(context,CGRectMake(0,0,256,128)); + UIGraphicsPopContext(); + UIImage *bkgImg = UIGraphicsGetImageFromCurrentImageContext(); + UIGraphicsEndImageContext(); + [self.previewButton setBackgroundImage:[[bkgImg retain] makeRoundCornersOfSize:CGSizeMake(12, 12)] forState:UIControlStateNormal]; +} + #pragma mark - #pragma mark Table view data source -(NSInteger) numberOfSectionsInTableView:(UITableView *)tableView { @@ -398,6 +427,7 @@ mapgen = @"e$mapgen 0"; self.slider.enabled = NO; self.sizeLabel.text = @"."; + [self restoreBackgroundImage]; break; case 2: // Maze @@ -458,6 +488,10 @@ self.tableView.rowHeight = 42; busy = NO; + + // draw a white background + [self restoreBackgroundImage]; + // initialize some "default" values self.sizeLabel.text = NSLocalizedString(@"All",@""); self.slider.value = 0.05f; diff -r 4619b1ae99b5 -r 07256e1ad559 cocoaTouch/otherSrc/UIImageExtra.h --- a/cocoaTouch/otherSrc/UIImageExtra.h Thu Jun 03 14:03:48 2010 +0000 +++ b/cocoaTouch/otherSrc/UIImageExtra.h Thu Jun 03 18:31:56 2010 +0000 @@ -15,6 +15,8 @@ -(UIImage *)mergeWith:(UIImage *)secondImage atPoint:(CGPoint) secondImagePoint; -(UIImage *)mergeWith:(UIImage *)secondImage atPoint:(CGPoint) secondImagePoint atSize:(CGSize) resultingSize; -(id) initWithContentsOfFile:(NSString *)path andCutAt:(CGRect) rect; --(UIImage *)convertImageToGrayScale:(UIImage *)image; +-(UIImage *)convertToGrayScale; +-(UIImage *)maskImageWith:(UIImage *)maskImage; +-(UIImage *)makeRoundCornersOfSize:(CGSize) sizewh; @end diff -r 4619b1ae99b5 -r 07256e1ad559 cocoaTouch/otherSrc/UIImageExtra.m --- a/cocoaTouch/otherSrc/UIImageExtra.m Thu Jun 03 14:03:48 2010 +0000 +++ b/cocoaTouch/otherSrc/UIImageExtra.m Thu Jun 03 18:31:56 2010 +0000 @@ -78,19 +78,19 @@ } } --(UIImage *)convertImageToGrayScale:(UIImage *)image { +-(UIImage *)convertToGrayScale { // Create image rectangle with current image width/height - CGRect imageRect = CGRectMake(0, 0, image.size.width, image.size.height); + CGRect imageRect = CGRectMake(0, 0, self.size.width, self.size.height); // Grayscale color space CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceGray(); // Create bitmap content with current image size and grayscale colorspace - CGContextRef context = CGBitmapContextCreate(nil, image.size.width, image.size.height, 8, 0, colorSpace, kCGImageAlphaNone); + CGContextRef context = CGBitmapContextCreate(nil, self.size.width, self.size.height, 8, 0, colorSpace, kCGImageAlphaNone); // Draw image into current context, with specified rectangle // using previously defined context (with grayscale colorspace) - CGContextDrawImage(context, imageRect, [image CGImage]); + CGContextDrawImage(context, imageRect, [self CGImage]); // Create bitmap image info from pixel data in current context CGImageRef imageRef = CGBitmapContextCreateImage(context); @@ -106,5 +106,84 @@ // Return the new grayscale image return newImage; } - + +// by http://iphonedevelopertips.com/cocoa/how-to-mask-an-image.html turned into a category by koda +-(UIImage*) maskImageWith:(UIImage *)maskImage { + CGImageRef maskRef = maskImage.CGImage; + + CGImageRef mask = CGImageMaskCreate(CGImageGetWidth(maskRef), + CGImageGetHeight(maskRef), + CGImageGetBitsPerComponent(maskRef), + CGImageGetBitsPerPixel(maskRef), + CGImageGetBytesPerRow(maskRef), + CGImageGetDataProvider(maskRef), NULL, false); + + CGImageRef masked = CGImageCreateWithMask([self CGImage], mask); + + CGImageRelease(mask); + + UIImage* retImage = [UIImage imageWithCGImage:masked]; + + CGImageRelease(masked); + + return retImage; +} + +// by http://blog.sallarp.com/iphone-uiimage-round-corners/ turned into a category by koda +void addRoundedRectToPath(CGContextRef context, CGRect rect, float ovalWidth, float ovalHeight) +{ + float fw, fh; + if (ovalWidth == 0 || ovalHeight == 0) { + CGContextAddRect(context, rect); + return; + } + CGContextSaveGState(context); + CGContextTranslateCTM (context, CGRectGetMinX(rect), CGRectGetMinY(rect)); + CGContextScaleCTM (context, ovalWidth, ovalHeight); + fw = CGRectGetWidth (rect) / ovalWidth; + fh = CGRectGetHeight (rect) / ovalHeight; + CGContextMoveToPoint(context, fw, fh/2); + CGContextAddArcToPoint(context, fw, fh, fw/2, fh, 1); + CGContextAddArcToPoint(context, 0, fh, 0, fh/2, 1); + CGContextAddArcToPoint(context, 0, 0, fw/2, 0, 1); + CGContextAddArcToPoint(context, fw, 0, fw, fh/2, 1); + CGContextClosePath(context); + CGContextRestoreGState(context); +} + +-(UIImage *)makeRoundCornersOfSize:(CGSize) sizewh { + UIImage * newImage = nil; + + NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; + + NSInteger cornerWidth = sizewh.width; + NSInteger cornerHeight = sizewh.height; + int w = self.size.width; + int h = self.size.height; + + CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); + CGContextRef context = CGBitmapContextCreate(NULL, w, h, 8, 4 * w, colorSpace, kCGImageAlphaPremultipliedFirst); + + CGContextBeginPath(context); + CGRect rect = CGRectMake(0, 0, w, h); + addRoundedRectToPath(context, rect, cornerWidth, cornerHeight); + CGContextClosePath(context); + CGContextClip(context); + + CGContextDrawImage(context, CGRectMake(0, 0, w, h), self.CGImage); + + CGImageRef imageMasked = CGBitmapContextCreateImage(context); + CGContextRelease(context); + CGColorSpaceRelease(colorSpace); + [self release]; + + newImage = [[UIImage imageWithCGImage:imageMasked] retain]; + CGImageRelease(imageMasked); + + [pool release]; + + return newImage; +} + + @end diff -r 4619b1ae99b5 -r 07256e1ad559 cocoaTouch/xib/MainMenuViewController-iPad.xib --- a/cocoaTouch/xib/MainMenuViewController-iPad.xib Thu Jun 03 14:03:48 2010 +0000 +++ b/cocoaTouch/xib/MainMenuViewController-iPad.xib Thu Jun 03 18:31:56 2010 +0000 @@ -12,7 +12,6 @@ YES - YES @@ -38,7 +37,7 @@ IBIPadFramework - + 292 YES @@ -192,7 +191,6 @@ {1024, 768} - 1 MCAwIDAAA @@ -350,7 +348,7 @@ YES MainMenuViewController UIResponder - {{224, 111}, {1024, 768}} + {{224, 119}, {1024, 768}} com.apple.InterfaceBuilder.IBCocoaTouchPlugin com.apple.InterfaceBuilder.IBCocoaTouchPlugin com.apple.InterfaceBuilder.IBCocoaTouchPlugin @@ -377,7 +375,7 @@ - 54 + 86 @@ -390,8 +388,17 @@ id - versionLabel - UILabel + YES + + YES + settingsSplitViewController + versionLabel + + + YES + UISplitViewController + UILabel + IBProjectSource @@ -588,6 +595,14 @@ + UISplitViewController + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UISplitViewController.h + + + UIView IBFrameworkSource @@ -618,10 +633,7 @@ UIViewController - - IBFrameworkSource - UIKit.framework/Headers/UISplitViewController.h - + UIViewController diff -r 4619b1ae99b5 -r 07256e1ad559 cocoaTouch/xib/MapConfigViewController-iPad.xib --- a/cocoaTouch/xib/MapConfigViewController-iPad.xib Thu Jun 03 14:03:48 2010 +0000 +++ b/cocoaTouch/xib/MapConfigViewController-iPad.xib Thu Jun 03 18:31:56 2010 +0000 @@ -109,7 +109,10 @@ 15 16 - 1 + 4 + 4 + 4 + 4 3 MQA @@ -449,7 +452,7 @@ - 48 + 49 diff -r 4619b1ae99b5 -r 07256e1ad559 hedgewars/hwengine.pas --- a/hedgewars/hwengine.pas Thu Jun 03 14:03:48 2010 +0000 +++ b/hedgewars/hwengine.pas Thu Jun 03 18:31:56 2010 +0000 @@ -416,8 +416,6 @@ initEverything(); WriteLnToConsole('Preview connecting on port ' + inttostr(port)); ipcPort:= port; - // this function is so quick that we need slow it down - SDL_Delay(250); {$ENDIF} InitIPC; IPCWaitPongEvent; diff -r 4619b1ae99b5 -r 07256e1ad559 project_files/HedgewarsMobile/Hedgewars.xcodeproj/project.pbxproj --- a/project_files/HedgewarsMobile/Hedgewars.xcodeproj/project.pbxproj Thu Jun 03 14:03:48 2010 +0000 +++ b/project_files/HedgewarsMobile/Hedgewars.xcodeproj/project.pbxproj Thu Jun 03 18:31:56 2010 +0000 @@ -1175,7 +1175,7 @@ CODE_SIGN_ENTITLEMENTS = "Entitlements-Distribution.plist"; CODE_SIGN_IDENTITY = "iPhone Distribution"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; - FPC_COMMON_OPTIONS = "-dIPHONEOS -Cs2000000 -vwi -B -Sgix -dLOWRES"; + FPC_COMMON_OPTIONS = "-dIPHONEOS -Cs2000000 -vwi -B -Sgix"; FPC_COMPILER_BINARY_DIR = /usr/local/lib/fpc/2.5.1; FPC_MAIN_FILE = "$(PROJECT_DIR)/../../hedgewars/hwLibrary.pas"; FPC_RTL_UNITS_BASE = /usr/local/lib/fpc; @@ -1285,7 +1285,7 @@ CODE_SIGN_IDENTITY = "iPhone Developer: Vittorio Giovara (DC2BRETXAC)"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer: Vittorio Giovara (DC2BRETXAC)"; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - FPC_COMMON_OPTIONS = "-dIPHONEOS -Cs2000000 -vwi -B -Sgix -dLOWRES"; + FPC_COMMON_OPTIONS = "-dIPHONEOS -Cs2000000 -vwi -B -Sgix"; FPC_COMPILER_BINARY_DIR = /usr/local/lib/fpc/2.5.1; FPC_MAIN_FILE = "$(PROJECT_DIR)/../../hedgewars/hwLibrary.pas"; FPC_RTL_UNITS_BASE = /usr/local/lib/fpc; @@ -1487,7 +1487,7 @@ CODE_SIGN_IDENTITY = "iPhone Developer: Vittorio Giovara (DC2BRETXAC)"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer: Vittorio Giovara (DC2BRETXAC)"; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - FPC_COMMON_OPTIONS = "-dIPHONEOS -Cs2000000 -vwi -B -Sgix -dLOWRES"; + FPC_COMMON_OPTIONS = "-dIPHONEOS -Cs2000000 -vwi -B -Sgix"; FPC_COMPILER_BINARY_DIR = /usr/local/lib/fpc/2.5.1; FPC_MAIN_FILE = "$(PROJECT_DIR)/../../hedgewars/hwLibrary.pas"; FPC_RTL_UNITS_BASE = /usr/local/lib/fpc; @@ -1526,7 +1526,7 @@ ARCHS = "$(ARCHS_STANDARD_32_BIT)"; CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - FPC_COMMON_OPTIONS = "-dIPHONEOS -Cs2000000 -vwi -B -Sgix -dLOWRES"; + FPC_COMMON_OPTIONS = "-dIPHONEOS -Cs2000000 -vwi -B -Sgix"; FPC_COMPILER_BINARY_DIR = /usr/local/lib/fpc/2.5.1; FPC_MAIN_FILE = "$(PROJECT_DIR)/../../hedgewars/hwLibrary.pas"; FPC_RTL_UNITS_BASE = /usr/local/lib/fpc;