# HG changeset patch # User unc0rr # Date 1277659708 -14400 # Node ID d85bdd5dc835c51ef061dcb28fd52671c110a223 # Parent ae89cf0735dc76c802c1076effac1059490b496b# Parent f7a7ca7270cf16aa910c3e8e202f68aeaa464c12 merge diff -r ae89cf0735dc -r d85bdd5dc835 .hgignore --- a/.hgignore Sun Jun 27 21:27:26 2010 +0400 +++ b/.hgignore Sun Jun 27 21:28:28 2010 +0400 @@ -14,3 +14,11 @@ glob:CPackConfig.cmake glob:CPackSourceConfig.cmake glob:tools/cmake_uninstall.cmake +glob:install_manifest.txt +glob:.DS_Store +glob:*.swp +glob:*.orig +glob:*.diff +glob:project_files/HedgewarsMobile/Data/ +glob:project_files/HedgewarsMobile/build/ +glob:project_files/HedgewarsMobile/Hedgewars.xcodeproj/vittorio.* diff -r ae89cf0735dc -r d85bdd5dc835 hedgewars/GSHandlers.inc --- a/hedgewars/GSHandlers.inc Sun Jun 27 21:27:26 2010 +0400 +++ b/hedgewars/GSHandlers.inc Sun Jun 27 21:28:28 2010 +0400 @@ -16,6 +16,54 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA *) +procedure doStepPerPixel(Gear: PGear; step: TGearStepProcedure; onlyCheckIfChanged: boolean); +var + dX, dY, sX, sY: hwFloat; + i, steps: LongWord; + caller: TGearStepProcedure; +begin + dX:= Gear^.dX; + dY:= Gear^.dY; + steps:= max(abs(hwRound(Gear^.X+dX)-hwRound(Gear^.X)), abs(hwRound(Gear^.Y+dY)-hwRound(Gear^.Y))); + + // Gear is still on the same Pixel it was before + if steps < 1 then + begin + if onlyCheckIfChanged then + begin + Gear^.X := Gear^.X + dX; + Gear^.Y := Gear^.Y + dY; + EXIT; + end + else + steps := 1; + end; + + if steps > 1 then + begin + sX:= dX / steps; + sY:= dY / steps; + end + else + begin + sX:= dX; + sY:= dY; + end; + + caller:= Gear^.doStep; + + for i:= 1 to steps do + begin + Gear^.X := Gear^.X + sX; + Gear^.Y := Gear^.Y + sY; + step(Gear); + if (Gear^.doStep <> caller) + or ((Gear^.State and gstCollision) <> 0) + or ((Gear^.State and gstMoving) = 0) then + break; + end; +end; + procedure makeHogsWorry(x, y: hwFloat; r: LongInt); var gi: PGear; @@ -3157,7 +3205,7 @@ procedure doStepPortal(Gear: PGear); var iterator, conPortal: PGear; - s, acptRadius, cdxy: hwFloat; + s, acptRadius, nx, ny, ox, oy, poffs, noffs, pspeed, nspeed: hwFloat; noTrap, hasdxy: Boolean; begin doPortalColorSwitch(); @@ -3192,15 +3240,15 @@ while true do begin + // iterate through GearsList if iterator = nil then - iterator := GearsList // start + iterator := GearsList else iterator := iterator^.NextGear; - // iterate through GearsList - + + // end of list? if iterator = nil then break; - // end of list // don't port portals or other gear that wouldn't make sense if (iterator^.Kind = gtPortal) or (iterator^.Kind = gtRope) or (iterator^.PortalCounter > 20) then @@ -3212,29 +3260,45 @@ gtRope) then continue; + // check if gear fits through portal if (iterator^.Radius > Gear^.Radius) then continue; - // sorry, you're too fat! - - // this is the range we accept incoming gears in + + // this is the max range we accept incoming gears in acptRadius := Int2hwFloat(iterator^.Radius+Gear^.Radius); + // too far away? if (iterator^.X < Gear^.X - acptRadius) or (iterator^.X > Gear^.X + acptRadius) or (iterator^.Y < Gear^.Y - acptRadius) or (iterator^.Y > Gear^.Y + acptRadius) then continue; - // too far away! hasdxy := ((iterator^.dX.QWordValue <> 0) or (iterator^.dY.QWordValue <> 0)); + // won't port stuff that moves away from me! if hasdxy and not (Gear^.dX*iterator^.dX + Gear^.dY*iterator^.dY).isNegative then - continue; - // won't port stuff that moves away from me! - - // wow! good candidate there, let's see if the distance really is small enough! - if (Distance(Gear^.X-iterator^.X,Gear^.Y-iterator^.Y) > acptRadius) then - continue; + continue; + + if (iterator^.Kind <> gtCake) then + begin + // wow! good candidate there, let's see if the distance and direction is okay! + if hasdxy then + begin + s := int2hwFloat(iterator^.Radius) / Distance(iterator^.dX, iterator^.dY); + ox:= iterator^.X + s * iterator^.dX; + oy:= iterator^.Y + s * iterator^.dY; + end + else + begin + ox:= iterator^.X; + oy:= iterator^.Y + Int2hwFloat(iterator^.Radius); + end; + + if (hwRound(Distance(Gear^.X-ox,Gear^.Y-oy)) > Gear^.Radius) then + continue; + end; + (* noTrap := ((not Gear^.dY.isNegative or (Gear^.dY.QWordValue = 0)) // can't be entered from above @@ -3252,36 +3316,54 @@ // Until loops are reliably broken inc(iterator^.PortalCounter); - // TODO: more accurate porting - cdxy := Distance(conPortal^.dX, conPortal^.dY); - s := (Int2hwFloat(Gear^.Radius)) / cdxy; - - if iterator^.Kind = gtCake then + // find out how much speed parallel to the portal vector + // the gear has, also get the vector offset + pspeed:= (Gear^.dX * iterator^.dX + Gear^.dY * iterator^.dY); + ox := (iterator^.X - Gear^.X); + oy := (iterator^.Y - Gear^.Y); + poffs:= (Gear^.dX * ox + Gear^.dY * oy); + // create a normal of the portal vector + nx := - Gear^.dY; + ny := Gear^.dX; + // pick the normal vector that's pointing skywards + if (not ny.isNegative) then begin - iterator^.X := conPortal^.X ; - iterator^.Y := conPortal^.Y ; - end - else + nx.isNegative := not nx.isNegative; + ny.isNegative := not ny.isNegative; + end; + // now let's find out how much speed the gear has in the + // direction of that normal + nspeed:= (nx * iterator^.dX + ny * iterator^.dY); + noffs:= (nx * ox + ny * oy); + + // now let's project those back to the connected portal's vectors + nx := - conPortal^.dY; + ny := conPortal^.dX; + if ny.isNegative then begin - iterator^.X := conPortal^.X + s * conPortal^.dX; - iterator^.Y := conPortal^.Y + s * conPortal^.dY; - - s := Distance(iterator^.dX, iterator^.dY) / cdxy; - - iterator^.dX := s * conPortal^.dX; - iterator^.dY := s * conPortal^.dY + nx.isNegative := not nx.isNegative; + ny.isNegative := not ny.isNegative; end; +//AddFileLog('poffs:'+cstr(poffs)+' noffs:'+cstr(noffs)+' pspeed:'+cstr(pspeed)+' nspeed:'+cstr(nspeed)); + iterator^.dX := -pspeed * conPortal^.dX - nspeed * nx; + iterator^.dY := -pspeed * conPortal^.dY - nspeed * ny; + if iterator^.Kind = gtCake then + poffs := poffs * _0_5; + iterator^.X := conPortal^.X + poffs * conPortal^.dX + noffs * nx; + iterator^.Y := conPortal^.Y + poffs * conPortal^.dY + noffs * ny; FollowGear := iterator; - +//AddFileLog('portal''d'); + +{ s := _0_2 + _0_008 * Gear^.Health; iterator^.dX := s * iterator^.dX; iterator^.dY := s * iterator^.dY; +} if Gear^.Health > 1 then dec(Gear^.Health); - //dec(iterator^.Health);?? - - // breaks (some) loops + +{ // breaks (some) loops if Distance(iterator^.dX, iterator^.dY) > _0_96 then begin iterator^.dX := iterator^.dX + signAs(cGravity * getRandom(1000),iterator^.dX); @@ -3290,13 +3372,13 @@ iterator^.dX := s * iterator^.dX; iterator^.dY := s * iterator^.dX; end; +} end; end; -procedure doStepMovingPortal(Gear: PGear); +procedure doStepMovingPortal_real(Gear: PGear); var x, y, tx, ty: LongInt; - //, bx, by, tangle: LongInt; s: hwFloat; procedure loadNewPortalBall(oldPortal: PGear; destroyGear: Boolean); @@ -3322,17 +3404,6 @@ end; begin - if (Gear^.Timer < 1) - or (PHedgehog(Gear^.Hedgehog) <> CurrentHedgehog) then - begin - deleteGear(Gear); - EXIT; - end; - - doPortalColorSwitch(); - - Gear^.X := Gear^.X + Gear^.dX; - Gear^.Y := Gear^.Y + Gear^.dY; x := hwRound(Gear^.X); y := hwRound(Gear^.Y); tx := 0; @@ -3341,6 +3412,8 @@ if ((y and LAND_HEIGHT_MASK) = 0) and ((x and LAND_WIDTH_MASK) = 0) and (Land[y, x] > 255) then begin + Gear^.State := Gear^.State or gstCollision; + Gear^.State := Gear^.State and not gstMoving; if not calcSlopeTangent(Gear, x, y, tx, ty, 255) or (DistanceI(tx,ty) < _12) then // reject shots at too irregular terrain begin @@ -3373,6 +3446,15 @@ loadNewPortalBall(Gear, true); end; +procedure doStepMovingPortal(Gear: PGear); +begin + doPortalColorSwitch(); + doStepPerPixel(Gear, @doStepMovingPortal_real, true); + if (Gear^.Timer < 1) + or (PHedgehog(Gear^.Hedgehog) <> CurrentHedgehog) then + deleteGear(Gear); +end; + procedure doStepPortalShot(newPortal: PGear); var iterator: PGear; @@ -3422,6 +3504,8 @@ iterator := iterator^.NextGear end; end; + newPortal^.State := newPortal^.State and not gstCollision; + newPortal^.State := newPortal^.State or gstMoving; newPortal^.doStep := @doStepMovingPortal; end; diff -r ae89cf0735dc -r d85bdd5dc835 hedgewars/uCollisions.pas --- a/hedgewars/uCollisions.pas Sun Jun 27 21:27:26 2010 +0400 +++ b/hedgewars/uCollisions.pas Sun Jun 27 21:28:28 2010 +0400 @@ -321,31 +321,39 @@ var ldx, ldy, rdx, rdy: LongInt; i, j, mx, my, li, ri, jfr, jto, tmpo : ShortInt; tmpx, tmpy: LongWord; - dx, dy: hwFloat; + dx, dy, s: hwFloat; offset: Array[0..7,0..1] of ShortInt; begin dx:= Gear^.dX; dy:= Gear^.dY; - // we start searching from the direction the gear center is at + // we start searching from the direction the gear came from + if (dx.QWordValue > _0_995.QWordValue ) + or (dy.QWordValue > _0_995.QWordValue ) then + begin // scale + s := _1 / Distance(dx,dy); + dx := s * dx; + dy := s * dy; + end; + mx:= hwRound(Gear^.X-dx) - hwRound(Gear^.X); my:= hwRound(Gear^.Y-dy) - hwRound(Gear^.Y); li:= -1; ri:= -1; - + // go around collision pixel, checking for first/last collisions // this will determinate what angles will be tried to crawl along for i:= 0 to 7 do begin offset[i,0]:= mx; offset[i,1]:= my; - + tmpx:= collisionX + mx; tmpy:= collisionY + my; - if (((tmpy) and LAND_HEIGHT_MASK) = 0) and (((tmpx) and LAND_WIDTH_MASK) = 0) then + if (((tmpy) and LAND_HEIGHT_MASK) = 0) and (((tmpx) and LAND_WIDTH_MASK) = 0) then if (Land[tmpy,tmpx] > TestWord) then begin // remember the index belonging to the first and last collision (if in 1st half) diff -r ae89cf0735dc -r d85bdd5dc835 hedgewars/uConsts.pas --- a/hedgewars/uConsts.pas Sun Jun 27 21:27:26 2010 +0400 +++ b/hedgewars/uConsts.pas Sun Jun 27 21:28:28 2010 +0400 @@ -2015,7 +2015,7 @@ SkipTurns: 0; PosCount: 1; PosSprite: sprWater; - ejectX: 0; //29; + ejectX: -5; //29; ejectY: -7), // Piano diff -r ae89cf0735dc -r d85bdd5dc835 project_files/HedgewarsMobile/Classes/CommodityFunctions.m --- a/project_files/HedgewarsMobile/Classes/CommodityFunctions.m Sun Jun 27 21:27:26 2010 +0400 +++ b/project_files/HedgewarsMobile/Classes/CommodityFunctions.m Sun Jun 27 21:28:28 2010 +0400 @@ -84,7 +84,7 @@ [NSNumber numberWithBool:NO], //lowgravity [NSNumber numberWithBool:NO], //lasersight [NSNumber numberWithBool:NO], //invulnerable - [NSNumber numberWithBool:NO], //addmines + [NSNumber numberWithBool:YES], //addmines [NSNumber numberWithBool:NO], //vampirism [NSNumber numberWithBool:NO], //karma [NSNumber numberWithBool:NO], //artillery diff -r ae89cf0735dc -r d85bdd5dc835 project_files/HedgewarsMobile/Classes/GameSetup.m --- a/project_files/HedgewarsMobile/Classes/GameSetup.m Sun Jun 27 21:27:26 2010 +0400 +++ b/project_files/HedgewarsMobile/Classes/GameSetup.m Sun Jun 27 21:28:28 2010 +0400 @@ -306,7 +306,7 @@ break; case '?': // without this sleep sometimes frontend replies before engine has processed any flag (resulting in an error) - [NSThread sleepForTimeInterval:0.6]; + [NSThread sleepForTimeInterval:0.7]; DLog(@"Ping? Pong!"); [self sendToEngine:@"!"]; break; diff -r ae89cf0735dc -r d85bdd5dc835 project_files/HedgewarsMobile/Classes/GeneralSettingsViewController.m --- a/project_files/HedgewarsMobile/Classes/GeneralSettingsViewController.m Sun Jun 27 21:27:26 2010 +0400 +++ b/project_files/HedgewarsMobile/Classes/GeneralSettingsViewController.m Sun Jun 27 21:28:28 2010 +0400 @@ -349,7 +349,8 @@ } */ - +/* + causes segfault if pressing twice cancel #pragma mark - #pragma mark Table view delegate -(void) tableView:(UITableView *)aTableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { @@ -365,7 +366,7 @@ [aTableView deselectRowAtIndexPath:indexPath animated:NO]; } } - +*/ #pragma mark - #pragma mark Memory management diff -r ae89cf0735dc -r d85bdd5dc835 project_files/HedgewarsMobile/Classes/SingleSchemeViewController.m --- a/project_files/HedgewarsMobile/Classes/SingleSchemeViewController.m Sun Jun 27 21:27:26 2010 +0400 +++ b/project_files/HedgewarsMobile/Classes/SingleSchemeViewController.m Sun Jun 27 21:28:28 2010 +0400 @@ -11,6 +11,9 @@ #import "CommodityFunctions.h" #import "UIImageExtra.h" +#define LABEL_TAG 12345 +#define SLIDER_TAG 54321 + @implementation SingleSchemeViewController @synthesize textFieldBeingEdited, schemeArray, basicSettingList, gameModifierArray; @@ -80,15 +83,24 @@ [mods release]; NSArray *basicSettings = [[NSArray alloc] initWithObjects: - [NSDictionary dictionaryWithObjectsAndKeys:NSLocalizedString(@"Damage Modifier",@""),@"title",@"Damage",@"image",nil], - [NSDictionary dictionaryWithObjectsAndKeys:NSLocalizedString(@"Turn Time",@""),@"title",@"Time",@"image",nil], - [NSDictionary dictionaryWithObjectsAndKeys:NSLocalizedString(@"Initial Health",@""),@"title",@"Health",@"image",nil], - [NSDictionary dictionaryWithObjectsAndKeys:NSLocalizedString(@"Sudden Death Timeout",@""),@"title",@"SuddenDeath",@"image",nil], - [NSDictionary dictionaryWithObjectsAndKeys:NSLocalizedString(@"Crate Drops",@""),@"title",@"Box",@"image",nil], - [NSDictionary dictionaryWithObjectsAndKeys:NSLocalizedString(@"Mines Time",@""),@"title",@"Time",@"image",nil], - [NSDictionary dictionaryWithObjectsAndKeys:NSLocalizedString(@"Mines Number",@""),@"title",@"Mine",@"image",nil], - [NSDictionary dictionaryWithObjectsAndKeys:NSLocalizedString(@"Dud Mines Probability",@""),@"title",@"Dud",@"image",nil], - [NSDictionary dictionaryWithObjectsAndKeys:NSLocalizedString(@"Explosives",@""),@"title",@"Damage",@"image",nil], + [NSDictionary dictionaryWithObjectsAndKeys:NSLocalizedString(@"Damage Modifier",@""),@"title",@"Damage",@"image", + [NSNumber numberWithInt:100],@"default",[NSNumber numberWithInt:10],@"min",[NSNumber numberWithInt:300],@"max",nil], + [NSDictionary dictionaryWithObjectsAndKeys:NSLocalizedString(@"Turn Time",@""),@"title",@"Time",@"image", + [NSNumber numberWithInt:45],@"default",[NSNumber numberWithInt:1],@"min",[NSNumber numberWithInt:99],@"max",nil], + [NSDictionary dictionaryWithObjectsAndKeys:NSLocalizedString(@"Initial Health",@""),@"title",@"Health",@"image", + [NSNumber numberWithInt:100],@"default",[NSNumber numberWithInt:50],@"min",[NSNumber numberWithInt:200],@"max",nil], + [NSDictionary dictionaryWithObjectsAndKeys:NSLocalizedString(@"Sudden Death Timeout",@""),@"title",@"SuddenDeath",@"image", + [NSNumber numberWithInt:15],@"default",[NSNumber numberWithInt:0],@"min",[NSNumber numberWithInt:50],@"max",nil], + [NSDictionary dictionaryWithObjectsAndKeys:NSLocalizedString(@"Crate Drops",@""),@"title",@"Box",@"image", + [NSNumber numberWithInt:5],@"default",[NSNumber numberWithInt:0],@"min",[NSNumber numberWithInt:9],@"max",nil], + [NSDictionary dictionaryWithObjectsAndKeys:NSLocalizedString(@"Mines Time",@""),@"title",@"Time",@"image", + [NSNumber numberWithInt:3],@"default",[NSNumber numberWithInt:0],@"min",[NSNumber numberWithInt:3],@"max",nil], + [NSDictionary dictionaryWithObjectsAndKeys:NSLocalizedString(@"Mines Number",@""),@"title",@"Mine",@"image", + [NSNumber numberWithInt:4],@"default",[NSNumber numberWithInt:1],@"min",[NSNumber numberWithInt:80],@"max",nil], + [NSDictionary dictionaryWithObjectsAndKeys:NSLocalizedString(@"Dud Mines Probability",@""),@"title",@"Dud",@"image", + [NSNumber numberWithInt:0],@"default",[NSNumber numberWithInt:0],@"min",[NSNumber numberWithInt:100],@"max",nil], + [NSDictionary dictionaryWithObjectsAndKeys:NSLocalizedString(@"Explosives",@""),@"title",@"Damage",@"image", + [NSNumber numberWithInt:2],@"default",[NSNumber numberWithInt:0],@"min",[NSNumber numberWithInt:40],@"max",nil], nil]; self.basicSettingList = basicSettings; [basicSettings release]; @@ -126,6 +138,9 @@ // set the new value -(BOOL) save:(id) sender { if (textFieldBeingEdited != nil) { + if ([textFieldBeingEdited.text length] == 0) + textFieldBeingEdited.text = self.title; + [[NSFileManager defaultManager] removeItemAtPath:[NSString stringWithFormat:@"%@/%@.plist",SCHEMES_DIRECTORY(),self.title] error:NULL]; self.title = self.textFieldBeingEdited.text; [self.schemeArray writeToFile:[NSString stringWithFormat:@"%@/%@.plist",SCHEMES_DIRECTORY(),self.title] atomically:YES]; @@ -193,7 +208,7 @@ return 0; } --(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { +-(UITableViewCell *)tableView:(UITableView *)aTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *CellIdentifier0 = @"Cell0"; static NSString *CellIdentifier1 = @"Cell1"; static NSString *CellIdentifier2 = @"Cell2"; @@ -203,7 +218,7 @@ switch ([indexPath section]) { case 0: - cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier0]; + cell = [aTableView dequeueReusableCellWithIdentifier:CellIdentifier0]; if (cell == nil) { cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier0] autorelease]; @@ -231,22 +246,52 @@ } cell.detailTextLabel.text = nil; cell.imageView.image = nil; + cell.selectionStyle = UITableViewCellSelectionStyleNone; break; case 1: - cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier1]; + cell = [aTableView dequeueReusableCellWithIdentifier:CellIdentifier1]; + NSDictionary *detail = [self.basicSettingList objectAtIndex:row]; + // need to offset this section (see format in CommodityFunctions.m and above) + NSInteger gmSize = [self.gameModifierArray count]; if (cell == nil) { - cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault + cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier1] autorelease]; + UISlider *slider = [[UISlider alloc] initWithFrame:CGRectMake(260, 12, 150, 23)]; + slider.maximumValue = [[detail objectForKey:@"max"] floatValue]; + slider.minimumValue = [[detail objectForKey:@"min"] floatValue]; + slider.tag = row+gmSize; + [slider addTarget:self action:@selector(sliderChanged:) forControlEvents:UIControlEventValueChanged]; + [cell.contentView addSubview:slider]; + [slider release]; + + UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(50, 7, 200, 30)]; + label.tag = LABEL_TAG; + label.backgroundColor = [UIColor clearColor]; + label.font = [UIFont boldSystemFontOfSize:[UIFont labelFontSize]]; + [cell.contentView addSubview:label]; + [label release]; } UIImage *img = [[UIImage alloc] initWithContentsOfFile:[NSString stringWithFormat:@"%@/icon%@.png",BTN_DIRECTORY(),[[self.basicSettingList objectAtIndex:row] objectForKey:@"image"]]]; cell.imageView.image = [img scaleToSize:CGSizeMake(40, 40)]; [img release]; - cell.textLabel.text = [[self.basicSettingList objectAtIndex:row] objectForKey:@"title"]; - cell.detailTextLabel.text = nil; + + UILabel *cellLabel = (UILabel *)[cell.contentView viewWithTag:LABEL_TAG]; + cellLabel.text = [[self.basicSettingList objectAtIndex:row] objectForKey:@"title"]; + + UISlider *cellSlider = (UISlider *)[cell.contentView viewWithTag:row+gmSize]; + cellSlider.value = [[self.schemeArray objectAtIndex:row+gmSize] floatValue]; + + // forced to use this weird format otherwise the label disappears when size of the text is bigger than the original + NSString *prestring = [NSString stringWithFormat:@"%d",[[self.schemeArray objectAtIndex:row+gmSize] intValue]]; + while ([prestring length] <= 4) + prestring = [NSString stringWithFormat:@" %@",prestring]; + cell.detailTextLabel.text = prestring; + + cell.selectionStyle = UITableViewCellSelectionStyleBlue; break; case 2: - cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier2]; + cell = [aTableView dequeueReusableCellWithIdentifier:CellIdentifier2]; if (cell == nil) { cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier2] autorelease]; @@ -261,10 +306,13 @@ cell.imageView.image = image; [image release]; [cell.imageView.layer setCornerRadius:7.0f]; + [cell.imageView.layer setBorderWidth:1]; [cell.imageView.layer setMasksToBounds:YES]; cell.textLabel.text = [[self.gameModifierArray objectAtIndex:row] objectForKey:@"title"]; cell.detailTextLabel.text = [[self.gameModifierArray objectAtIndex:row] objectForKey:@"description"]; [(UISwitch *)cell.accessoryView setOn:[[self.schemeArray objectAtIndex:row] boolValue] animated:NO]; + + cell.selectionStyle = UITableViewCellSelectionStyleNone; } return cell; @@ -275,20 +323,54 @@ [self.schemeArray replaceObjectAtIndex:theSwitch.tag withObject:[NSNumber numberWithBool:theSwitch.on]]; } +-(void) sliderChanged:(id) sender { + // need to offset this section (see format in CommodityFunctions.m and above) + NSInteger gmSize = [self.gameModifierArray count]; + // the slider that changed is sent as object + UISlider *theSlider = (UISlider *)sender; + // create the indexPath of the row of the slider + NSIndexPath *indexPath = [NSIndexPath indexPathForRow:theSlider.tag-gmSize inSection:1]; + // get its cell + UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath]; + // grab the associated label + UILabel *label = (UILabel *)cell.detailTextLabel; + // modify it + label.text = [NSString stringWithFormat:@"%d",(int)theSlider.value]; + // save changes in the main array (remember that you need to offset it) + [self.schemeArray replaceObjectAtIndex:theSlider.tag withObject:[NSNumber numberWithInt:(int)theSlider.value]]; +} #pragma mark - #pragma mark Table view delegate -(void) tableView:(UITableView *)aTableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { + UITableViewCell *cell = [aTableView cellForRowAtIndexPath:indexPath]; + UISwitch *sw = nil; + UISlider *cellSlider = nil; - if ([indexPath section] == 0) { - UITableViewCell *cell = [aTableView cellForRowAtIndexPath:indexPath]; - for (UIView *oneView in cell.contentView.subviews) { - if ([oneView isMemberOfClass:[UITextField class]]) { - textFieldBeingEdited = (UITextField *)oneView; - [textFieldBeingEdited becomeFirstResponder]; + switch ([indexPath section]) { + case 0: + for (UIView *oneView in cell.contentView.subviews) { + if ([oneView isMemberOfClass:[UITextField class]]) { + textFieldBeingEdited = (UITextField *)oneView; + [textFieldBeingEdited becomeFirstResponder]; + } } - } + break; + case 1: + cellSlider = (UISlider *)[cell.contentView viewWithTag:[indexPath row]+[self.gameModifierArray count]]; + [cellSlider setValue:[[[self.basicSettingList objectAtIndex:[indexPath row]] objectForKey:@"default"] floatValue] animated:YES]; + [self sliderChanged:cellSlider]; + //cell.detailTextLabel.text = [[[self.basicSettingList objectAtIndex:[indexPath row]] objectForKey:@"default"] stringValue]; + break; + case 2: + /*sw = (UISwitch *)cell.accessoryView; + [sw setOn:!sw.on animated:YES]; + [self toggleSwitch:sw];*/ + break; + default: + break; } + [aTableView deselectRowAtIndexPath:indexPath animated:YES]; } diff -r ae89cf0735dc -r d85bdd5dc835 project_files/HedgewarsMobile/Classes/SingleTeamViewController.m --- a/project_files/HedgewarsMobile/Classes/SingleTeamViewController.m Sun Jun 27 21:27:26 2010 +0400 +++ b/project_files/HedgewarsMobile/Classes/SingleTeamViewController.m Sun Jun 27 21:28:28 2010 +0400 @@ -40,8 +40,14 @@ if (textFieldBeingEdited != nil) { if (TEAMNAME_TAG == index) { + if ([textFieldBeingEdited.text length] == 0) + textFieldBeingEdited.text = self.title; [self.teamDictionary setObject:textFieldBeingEdited.text forKey:@"teamname"]; + self.title = textFieldBeingEdited.text; } else { + if ([textFieldBeingEdited.text length] == 0) + textFieldBeingEdited.text = [NSString stringWithFormat:@"hedgehog %d",index]; + //replace the old value with the new one NSMutableDictionary *hog = [[teamDictionary objectForKey:@"hedgehogs"] objectAtIndex:index]; [hog setObject:textFieldBeingEdited.text forKey:@"hogname"]; diff -r ae89cf0735dc -r d85bdd5dc835 project_files/HedgewarsMobile/Classes/UIImageExtra.m --- a/project_files/HedgewarsMobile/Classes/UIImageExtra.m Sun Jun 27 21:27:26 2010 +0400 +++ b/project_files/HedgewarsMobile/Classes/UIImageExtra.m Sun Jun 27 21:28:28 2010 +0400 @@ -12,21 +12,22 @@ @implementation UIImage (extra) -(UIImage *)scaleToSize:(CGSize) size { - // Create a bitmap graphics context - // This will also set it as the current context - UIGraphicsBeginImageContext(size); - - // Draw the scaled image in the current context - [self drawInRect:CGRectMake(0, 0, size.width, size.height)]; - - // Create a new image from current context - UIImage* scaledImage = UIGraphicsGetImageFromCurrentImageContext(); - - // Pop the current context from the stack - UIGraphicsEndImageContext(); - - // Return our new scaled image (autoreleased) - return scaledImage; + DLog(@"warning - this is a very expensive operation, you should avoid using it"); + + // Create a bitmap graphics context; this will also set it as the current context + UIGraphicsBeginImageContext(size); + + // Draw the scaled image in the current context + [self drawInRect:CGRectMake(0, 0, size.width, size.height)]; + + // Create a new image from current context + UIImage* scaledImage = UIGraphicsGetImageFromCurrentImageContext(); + + // Pop the current context from the stack + UIGraphicsEndImageContext(); + + // Return our new scaled image (autoreleased) + return scaledImage; } -(UIImage *)mergeWith:(UIImage *)secondImage atPoint:(CGPoint) secondImagePoint { @@ -35,12 +36,13 @@ } -(UIImage *)mergeWith:(UIImage *)secondImage atPoint:(CGPoint) secondImagePoint atSize:(CGSize) resultingSize { + // Create a bitmap graphics context; this will also set it as the current context UIGraphicsBeginImageContext(resultingSize); - // drav the background image + // draw the background image in the current context [self drawAtPoint:CGPointMake(0,0)]; - // draw the image on top of the first image + // draw the image on top of the first image (because the context is the same) [secondImage drawAtPoint:secondImagePoint]; // create an image from the current contex (not thread safe) @@ -79,38 +81,40 @@ } -(UIImage *)convertToGrayScale { - // Create image rectangle with current image width/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, 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, [self CGImage]); - - // Create bitmap image info from pixel data in current context - CGImageRef imageRef = CGBitmapContextCreateImage(context); - - // Create a new UIImage object - UIImage *newImage = [UIImage imageWithCGImage:imageRef]; - - // Release colorspace, context and bitmap information - CGColorSpaceRelease(colorSpace); - CGContextRelease(context); - CFRelease(imageRef); - - // Return the new grayscale image - return newImage; + // Create image rectangle with current image width/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, 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, [self CGImage]); + + // Create bitmap image info from pixel data in current context + CGImageRef imageRef = CGBitmapContextCreateImage(context); + + // Create a new UIImage object + UIImage *newImage = [UIImage imageWithCGImage:imageRef]; + + // Release colorspace, context and bitmap information + CGColorSpaceRelease(colorSpace); + CGContextRelease(context); + CFRelease(imageRef); + + // 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; + // prepare the reference image + CGImageRef maskRef = [maskImage CGImage]; + // create the mask using parameters of the mask reference CGImageRef mask = CGImageMaskCreate(CGImageGetWidth(maskRef), CGImageGetHeight(maskRef), CGImageGetBitsPerComponent(maskRef), @@ -118,21 +122,19 @@ CGImageGetBytesPerRow(maskRef), CGImageGetDataProvider(maskRef), NULL, false); + // create an image in the current context 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; +void addRoundedRectToPath(CGContextRef context, CGRect rect, CGFloat ovalWidth, CGFloat ovalHeight) { + CGFloat fw, fh; if (ovalWidth == 0 || ovalHeight == 0) { CGContextAddRect(context, rect); return; @@ -151,13 +153,11 @@ CGContextRestoreGState(context); } --(UIImage *)makeRoundCornersOfSize:(CGSize) sizewh { - UIImage * newImage = nil; - - NSInteger cornerWidth = sizewh.width; - NSInteger cornerHeight = sizewh.height; - int w = self.size.width; - int h = self.size.height; +-(UIImage *)makeRoundCornersOfSize:(CGSize) sizewh { + CGFloat cornerWidth = sizewh.width; + CGFloat cornerHeight = sizewh.height; + CGFloat w = self.size.width; + CGFloat h = self.size.height; CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); CGContextRef context = CGBitmapContextCreate(NULL, w, h, 8, 4 * w, colorSpace, kCGImageAlphaPremultipliedFirst); @@ -168,17 +168,16 @@ CGContextClosePath(context); CGContextClip(context); - CGContextDrawImage(context, CGRectMake(0, 0, w, h), self.CGImage); + CGContextDrawImage(context, CGRectMake(0, 0, w, h), [self CGImage]); CGImageRef imageMasked = CGBitmapContextCreateImage(context); CGContextRelease(context); CGColorSpaceRelease(colorSpace); - newImage = [UIImage imageWithCGImage:imageMasked]; + UIImage *newImage = [UIImage imageWithCGImage:imageMasked]; CGImageRelease(imageMasked); return newImage; } - @end