# HG changeset patch # User Jens Alfke # Date 1212098646 25200 # Node ID a59acc68308048ddf98f93d8f12d064f9a6e6376 # Parent 45c82a071acab4309390d05fefcf45a80850d644 Finally fixed the slow animation performance of board games; all it took was changing the board's z index from 1 to 0, somehow. Games working well now. diff -r 45c82a071aca -r a59acc683080 GeekGameBoard-iPhone.xcodeproj/project.pbxproj --- a/GeekGameBoard-iPhone.xcodeproj/project.pbxproj Wed May 28 12:47:10 2008 -0700 +++ b/GeekGameBoard-iPhone.xcodeproj/project.pbxproj Thu May 29 15:04:06 2008 -0700 @@ -11,6 +11,8 @@ 1D60589B0D05DD56006BFB54 /* main-iPhone.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main-iPhone.m */; }; 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; }; 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; }; + 2740502B0DEF36DF0006A9EE /* Pop.aiff in Resources */ = {isa = PBXBuildFile; fileRef = 274050290DEF36DF0006A9EE /* Pop.aiff */; }; + 2740502C0DEF36DF0006A9EE /* Tink.aiff in Resources */ = {isa = PBXBuildFile; fileRef = 2740502A0DEF36DF0006A9EE /* Tink.aiff */; }; 279F4B590D85C51700B32DBF /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 279F4B580D85C51700B32DBF /* AudioToolbox.framework */; }; 279F4B5B0D85C51700B32DBF /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 279F4B5A0D85C51700B32DBF /* QuartzCore.framework */; }; 279F4B620D85C63000B32DBF /* GGBTextLayer.m in Sources */ = {isa = PBXBuildFile; fileRef = 279F4B610D85C63000B32DBF /* GGBTextLayer.m */; }; @@ -45,13 +47,20 @@ 27C99B210D820868005AFD4F /* QuartzUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = 27C99B0B0D820868005AFD4F /* QuartzUtils.m */; }; 27C99B220D820868005AFD4F /* GGBUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = 27C99B0D0D820868005AFD4F /* GGBUtils.m */; }; 27C99B510D82106E005AFD4F /* GGBLayer.m in Sources */ = {isa = PBXBuildFile; fileRef = 27C99B500D82106E005AFD4F /* GGBLayer.m */; }; + 27DBB52C0DEE059700616D85 /* Blue.png in Resources */ = {isa = PBXBuildFile; fileRef = 27DBB5270DEE059700616D85 /* Blue.png */; }; + 27DBB52D0DEE059800616D85 /* Gold.png in Resources */ = {isa = PBXBuildFile; fileRef = 27DBB5280DEE059700616D85 /* Gold.png */; }; + 27DBB52E0DEE059800616D85 /* Green.png in Resources */ = {isa = PBXBuildFile; fileRef = 27DBB5290DEE059700616D85 /* Green.png */; }; + 27DBB52F0DEE059900616D85 /* Red.png in Resources */ = {isa = PBXBuildFile; fileRef = 27DBB52A0DEE059700616D85 /* Red.png */; }; + 27DBB5300DEE059900616D85 /* Violet.png in Resources */ = {isa = PBXBuildFile; fileRef = 27DBB52B0DEE059700616D85 /* Violet.png */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ 1D30AB110D05D00D00671497 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 1D3623EB0D0F72F000981E51 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; - 1D6058910D05DD3D006BFB54 /* GGB-iPhone.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "GGB-iPhone.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + 1D6058910D05DD3D006BFB54 /* GeekGameBoard.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = GeekGameBoard.app; sourceTree = BUILT_PRODUCTS_DIR; }; 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; + 274050290DEF36DF0006A9EE /* Pop.aiff */ = {isa = PBXFileReference; lastKnownFileType = audio.aiff; name = Pop.aiff; path = /System/Library/Sounds/Pop.aiff; sourceTree = ""; }; + 2740502A0DEF36DF0006A9EE /* Tink.aiff */ = {isa = PBXFileReference; lastKnownFileType = audio.aiff; name = Tink.aiff; path = /System/Library/Sounds/Tink.aiff; sourceTree = ""; }; 279F4B580D85C51700B32DBF /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = System/Library/Frameworks/AudioToolbox.framework; sourceTree = SDKROOT; }; 279F4B5A0D85C51700B32DBF /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; }; 279F4B600D85C63000B32DBF /* GGBTextLayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GGBTextLayer.h; sourceTree = ""; }; @@ -109,6 +118,11 @@ 27C99B0D0D820868005AFD4F /* GGBUtils.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GGBUtils.m; sourceTree = ""; }; 27C99B4F0D82106E005AFD4F /* GGBLayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GGBLayer.h; sourceTree = ""; }; 27C99B500D82106E005AFD4F /* GGBLayer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GGBLayer.m; sourceTree = ""; }; + 27DBB5270DEE059700616D85 /* Blue.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Blue.png; sourceTree = ""; }; + 27DBB5280DEE059700616D85 /* Gold.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Gold.png; sourceTree = ""; }; + 27DBB5290DEE059700616D85 /* Green.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Green.png; sourceTree = ""; }; + 27DBB52A0DEE059700616D85 /* Red.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Red.png; sourceTree = ""; }; + 27DBB52B0DEE059700616D85 /* Violet.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Violet.png; sourceTree = ""; }; 29B97316FDCFA39411CA2CEA /* main-iPhone.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "main-iPhone.m"; path = "Source/main-iPhone.m"; sourceTree = ""; }; 32CA4F630368D1EE00C91783 /* GGB-iPhone_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "GGB-iPhone_Prefix.pch"; path = "Source/GGB-iPhone_Prefix.pch"; sourceTree = ""; }; 8D1107310486CEB800E47090 /* Info-iPhone.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "Info-iPhone.plist"; sourceTree = ""; }; @@ -150,7 +164,7 @@ 19C28FACFE9D520D11CA2CBB /* Products */ = { isa = PBXGroup; children = ( - 1D6058910D05DD3D006BFB54 /* GGB-iPhone.app */, + 1D6058910D05DD3D006BFB54 /* GeekGameBoard.app */, ); name = Products; sourceTree = ""; @@ -230,6 +244,18 @@ name = Games; sourceTree = ""; }; + 27DBB5260DEE059700616D85 /* Gingko */ = { + isa = PBXGroup; + children = ( + 27DBB5270DEE059700616D85 /* Blue.png */, + 27DBB5280DEE059700616D85 /* Gold.png */, + 27DBB5290DEE059700616D85 /* Green.png */, + 27DBB52A0DEE059700616D85 /* Red.png */, + 27DBB52B0DEE059700616D85 /* Violet.png */, + ); + path = Gingko; + sourceTree = ""; + }; 29B97314FDCFA39411CA2CEA /* CustomTemplate */ = { isa = PBXGroup; children = ( @@ -258,14 +284,17 @@ 29B97317FDCFA39411CA2CEA /* Resources */ = { isa = PBXGroup; children = ( + 274050290DEF36DF0006A9EE /* Pop.aiff */, + 2740502A0DEF36DF0006A9EE /* Tink.aiff */, 279F4E050D860B8800B32DBF /* Green Ball.png */, 279F4E060D860B8800B32DBF /* Red Ball.png */, 279F4E070D860B8800B32DBF /* White Ball.png */, - 279F4F1A0D86448100B32DBF /* Wood.jpg */, 279F4E090D860B8800B32DBF /* Yellow Ball.png */, - 279F4C730D85D43800B32DBF /* Background.png */, 279F4C1C0D85D0AF00B32DBF /* X.tiff */, 279F4C1E0D85D0CB00B32DBF /* O.tiff */, + 279F4F1A0D86448100B32DBF /* Wood.jpg */, + 27DBB5260DEE059700616D85 /* Gingko */, + 279F4C730D85D43800B32DBF /* Background.png */, 279F4B720D85CDE900B32DBF /* ToolbarAdvanced.icns */, 8D1107310486CEB800E47090 /* Info-iPhone.plist */, ); @@ -298,7 +327,7 @@ ); name = "GGB-iPhone"; productName = "GGB-iPhone"; - productReference = 1D6058910D05DD3D006BFB54 /* GGB-iPhone.app */; + productReference = 1D6058910D05DD3D006BFB54 /* GeekGameBoard.app */; productType = "com.apple.product-type.application"; }; /* End PBXNativeTarget section */ @@ -332,6 +361,13 @@ 279F4E0C0D860B8800B32DBF /* White Ball.png in Resources */, 279F4E0E0D860B8800B32DBF /* Yellow Ball.png in Resources */, 279F4F1B0D86448100B32DBF /* Wood.jpg in Resources */, + 27DBB52C0DEE059700616D85 /* Blue.png in Resources */, + 27DBB52D0DEE059800616D85 /* Gold.png in Resources */, + 27DBB52E0DEE059800616D85 /* Green.png in Resources */, + 27DBB52F0DEE059900616D85 /* Red.png in Resources */, + 27DBB5300DEE059900616D85 /* Violet.png in Resources */, + 2740502B0DEF36DF0006A9EE /* Pop.aiff in Resources */, + 2740502C0DEF36DF0006A9EE /* Tink.aiff in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -384,7 +420,7 @@ GCC_PREFIX_HEADER = "Source/GGB-iPhone_Prefix.pch"; INFOPLIST_FILE = "Resources/Info-iPhone.plist"; PREBINDING = NO; - PRODUCT_NAME = "GGB-iPhone"; + PRODUCT_NAME = GeekGameBoard; }; name = Debug; }; @@ -398,7 +434,7 @@ GCC_PREFIX_HEADER = "Source/GGB-iPhone_Prefix.pch"; INFOPLIST_FILE = "Resources/Info-iPhone.plist"; PREBINDING = NO; - PRODUCT_NAME = "GGB-iPhone"; + PRODUCT_NAME = GeekGameBoard; WRAPPER_EXTENSION = app; }; name = Release; @@ -429,6 +465,7 @@ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "Laurence ANDERSEN"; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_TREAT_WARNINGS_AS_ERRORS = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES; PREBINDING = NO; SDKROOT = iphoneos2.0; WARNING_CFLAGS = "-Wall"; diff -r 45c82a071aca -r a59acc683080 GeekGameBoard.xcodeproj/project.pbxproj --- a/GeekGameBoard.xcodeproj/project.pbxproj Wed May 28 12:47:10 2008 -0700 +++ b/GeekGameBoard.xcodeproj/project.pbxproj Thu May 29 15:04:06 2008 -0700 @@ -19,6 +19,11 @@ 2734B2620CC7F25A0070C008 /* HexchequerGame.m in Sources */ = {isa = PBXBuildFile; fileRef = 2734B2610CC7F25A0070C008 /* HexchequerGame.m */; }; 2734B4F00CCA5BDB0070C008 /* CheckersGame.m in Sources */ = {isa = PBXBuildFile; fileRef = 2734B4EF0CCA5BDB0070C008 /* CheckersGame.m */; }; 274124060CFCCF9D00842A9B /* DemoBoardView.m in Sources */ = {isa = PBXBuildFile; fileRef = 274124050CFCCF9D00842A9B /* DemoBoardView.m */; }; + 275167D90DEE2AB000247375 /* Blue.png in Resources */ = {isa = PBXBuildFile; fileRef = 275167D40DEE2AB000247375 /* Blue.png */; }; + 275167DA0DEE2AB000247375 /* Gold.png in Resources */ = {isa = PBXBuildFile; fileRef = 275167D50DEE2AB000247375 /* Gold.png */; }; + 275167DB0DEE2AB000247375 /* Green.png in Resources */ = {isa = PBXBuildFile; fileRef = 275167D60DEE2AB000247375 /* Green.png */; }; + 275167DC0DEE2AB000247375 /* Red.png in Resources */ = {isa = PBXBuildFile; fileRef = 275167D70DEE2AB000247375 /* Red.png */; }; + 275167DD0DEE2AB000247375 /* Violet.png in Resources */ = {isa = PBXBuildFile; fileRef = 275167D80DEE2AB000247375 /* Violet.png */; }; 276DFC410D00867000D329AE /* Green Ball.png in Resources */ = {isa = PBXBuildFile; fileRef = 276DFC400D00867000D329AE /* Green Ball.png */; }; 276DFC560D00890C00D329AE /* Red Ball.png in Resources */ = {isa = PBXBuildFile; fileRef = 276DFC530D00890C00D329AE /* Red Ball.png */; }; 276DFC570D00890C00D329AE /* Yellow Ball.png in Resources */ = {isa = PBXBuildFile; fileRef = 276DFC540D00890C00D329AE /* Yellow Ball.png */; }; @@ -73,6 +78,11 @@ 2734B4EF0CCA5BDB0070C008 /* CheckersGame.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CheckersGame.m; sourceTree = ""; }; 274124040CFCCF9D00842A9B /* DemoBoardView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DemoBoardView.h; sourceTree = ""; }; 274124050CFCCF9D00842A9B /* DemoBoardView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DemoBoardView.m; sourceTree = ""; }; + 275167D40DEE2AB000247375 /* Blue.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Blue.png; sourceTree = ""; }; + 275167D50DEE2AB000247375 /* Gold.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Gold.png; sourceTree = ""; }; + 275167D60DEE2AB000247375 /* Green.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Green.png; sourceTree = ""; }; + 275167D70DEE2AB000247375 /* Red.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Red.png; sourceTree = ""; }; + 275167D80DEE2AB000247375 /* Violet.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Violet.png; sourceTree = ""; }; 276DFC400D00867000D329AE /* Green Ball.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Green Ball.png"; path = "Resources/Green Ball.png"; sourceTree = ""; }; 276DFC530D00890C00D329AE /* Red Ball.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Red Ball.png"; path = "Resources/Red Ball.png"; sourceTree = ""; }; 276DFC540D00890C00D329AE /* Yellow Ball.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Yellow Ball.png"; path = "Resources/Yellow Ball.png"; sourceTree = ""; }; @@ -235,6 +245,19 @@ name = Games; sourceTree = ""; }; + 275167D30DEE2AB000247375 /* Gingko */ = { + isa = PBXGroup; + children = ( + 275167D40DEE2AB000247375 /* Blue.png */, + 275167D50DEE2AB000247375 /* Gold.png */, + 275167D60DEE2AB000247375 /* Green.png */, + 275167D70DEE2AB000247375 /* Red.png */, + 275167D80DEE2AB000247375 /* Violet.png */, + ); + name = Gingko; + path = Resources/Gingko; + sourceTree = ""; + }; 29B97314FDCFA39411CA2CEA /* BoardGame */ = { isa = PBXGroup; children = ( @@ -262,6 +285,7 @@ 29B97317FDCFA39411CA2CEA /* Resources */ = { isa = PBXGroup; children = ( + 275167D30DEE2AB000247375 /* Gingko */, 29B97318FDCFA39411CA2CEA /* MainMenu.nib */, 8D1107310486CEB800E47090 /* Info.plist */, 089C165CFE840E0CC02AAC07 /* InfoPlist.strings */, @@ -339,6 +363,11 @@ 279F4DB20D8607AD00B32DBF /* O.tiff in Resources */, 279F4DB30D8607AD00B32DBF /* X.tiff in Resources */, 279F4DE20D8609C200B32DBF /* Background.png in Resources */, + 275167D90DEE2AB000247375 /* Blue.png in Resources */, + 275167DA0DEE2AB000247375 /* Gold.png in Resources */, + 275167DB0DEE2AB000247375 /* Green.png in Resources */, + 275167DC0DEE2AB000247375 /* Red.png in Resources */, + 275167DD0DEE2AB000247375 /* Violet.png in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff -r 45c82a071aca -r a59acc683080 Source/Bit.h --- a/Source/Bit.h Wed May 28 12:47:10 2008 -0700 +++ b/Source/Bit.h Thu May 29 15:04:06 2008 -0700 @@ -29,7 +29,7 @@ /** Standard Z positions */ enum { - kBoardZ = 1, + kBoardZ = 0, kCardZ = 2, kPieceZ = 3, @@ -43,6 +43,7 @@ { @private int _restingZ; // Original z position, saved while pickedUp + BOOL _pickedUp; Player *_owner; // Player that owns this Bit } diff -r 45c82a071aca -r a59acc683080 Source/Bit.m --- a/Source/Bit.m Wed May 28 12:47:10 2008 -0700 +++ b/Source/Bit.m Thu May 29 15:04:06 2008 -0700 @@ -25,6 +25,15 @@ #import "QuartzUtils.h" +#ifdef TARGET_OS_IPHONE +#define kPickedUpScale 2.0 // more magnification, so piece shows up underneath fingertip +#define kPickedUpOpacity 0.6 +#else +#define kPickedUpScale 1.2 +#define kPickedUpOpacity 0.9 +#endif + + @implementation Bit @@ -84,29 +93,29 @@ - (BOOL) pickedUp { - return self.zPosition >= kPickedUpZ; + return _pickedUp; } - (void) setPickedUp: (BOOL)up { - if( up != self.pickedUp ) { + if( up != _pickedUp ) { CGFloat shadow, offset, radius, opacity, z, scale; if( up ) { shadow = 0.8; offset = 2; radius = 8; - opacity = 0.9; - scale = 1.2; + opacity = kPickedUpOpacity; + scale = kPickedUpScale; z = kPickedUpZ; _restingZ = self.zPosition; } else { shadow = offset = radius = 0.0; opacity = 1.0; - scale = 1.0/1.2; + scale = 1.0/kPickedUpScale; z = _restingZ; } - - self.zPosition = z; + + //self.zPosition = z; #if !TARGET_OS_IPHONE self.shadowOpacity = shadow; self.shadowOffset = CGSizeMake(offset,-offset); @@ -114,6 +123,7 @@ #endif self.opacity = opacity; self.scale *= scale; + _pickedUp = up; } } diff -r 45c82a071aca -r a59acc683080 Source/BoardUIView.m --- a/Source/BoardUIView.m Wed May 28 12:47:10 2008 -0700 +++ b/Source/BoardUIView.m Thu May 29 15:04:06 2008 -0700 @@ -199,11 +199,9 @@ CGPoint newPos = [_dragBit.superlayer convertPoint: pos fromLayer: self.layer]; [CATransaction flush]; - [CATransaction begin]; - [CATransaction setValue:(id)kCFBooleanTrue - forKey:kCATransactionDisableActions]; + BeginDisableAnimations(); _dragBit.position = newPos; - [CATransaction commit]; + EndDisableAnimations(); // Find what it's over: [self _findDropTarget: pos]; @@ -261,6 +259,7 @@ } else { [_dragBit removeFromSuperlayer]; } + Beep(); } } else { // Just a click, without a drag: diff -r 45c82a071aca -r a59acc683080 Source/BoardView.m --- a/Source/BoardView.m Wed May 28 12:47:10 2008 -0700 +++ b/Source/BoardView.m Thu May 29 15:04:06 2008 -0700 @@ -301,6 +301,7 @@ if( ! [_game clickedBit: _dragBit] ) NSBeep(); } + _dropTarget = nil; _dragBit = nil; [NSCursor pop]; diff -r 45c82a071aca -r a59acc683080 Source/CheckersGame.m --- a/Source/CheckersGame.m Wed May 28 12:47:10 2008 -0700 +++ b/Source/CheckersGame.m Thu May 29 15:04:06 2008 -0700 @@ -32,8 +32,8 @@ - (Piece*) pieceForPlayer: (int)playerNum { - Piece *p = [[Piece alloc] initWithImageNamed: (playerNum==0 ?@"Green Ball.png" :@"Red Ball.png") - scale: floor(_grid.spacing.width * 0.8)]; + Piece *p = [[Piece alloc] initWithImageNamed: (playerNum==0 ?@"Green.png" :@"Red.png") + scale: floor(_grid.spacing.width * 1.0)]; p.owner = [self.players objectAtIndex: playerNum]; p.name = playerNum ?@"2" :@"1"; return [p autorelease]; diff -r 45c82a071aca -r a59acc683080 Source/Dispenser.m --- a/Source/Dispenser.m Wed May 28 12:47:10 2008 -0700 +++ b/Source/Dispenser.m Thu May 29 15:04:06 2008 -0700 @@ -72,14 +72,12 @@ { NSAssert(_bit==nil,@"Already have a currentBit"); - [CATransaction begin]; - [CATransaction setValue: (id)kCFBooleanTrue - forKey: kCATransactionDisableActions]; + BeginDisableAnimations(); self.bit = [self createBit]; CGPoint pos = _bit.position; _bit.position = CGPointMake(pos.x, pos.y+70); [self addSublayer: _bit]; - [CATransaction commit]; + EndDisableAnimations(); _bit.position = pos; } diff -r 45c82a071aca -r a59acc683080 Source/GGBLayer.h --- a/Source/GGBLayer.h Wed May 28 12:47:10 2008 -0700 +++ b/Source/GGBLayer.h Thu May 29 15:04:06 2008 -0700 @@ -36,3 +36,14 @@ - (void) animateAndBlock: (NSString*)keyPath from: (id)from to: (id)to duration: (NSTimeInterval)duration; @end + + +/** Moves a layer from one superlayer to another, without changing its position onscreen. */ +void ChangeSuperlayer( CALayer *layer, CALayer *newSuperlayer, int index ); + +/** Removes a layer from its superlayer without any fade-out animation. */ +void RemoveImmediately( CALayer *layer ); + +/** Disables animations until EndDisableAnimations is called. */ +void BeginDisableAnimations(void); +void EndDisableAnimations(void); diff -r 45c82a071aca -r a59acc683080 Source/GGBLayer.m --- a/Source/GGBLayer.m Wed May 28 12:47:10 2008 -0700 +++ b/Source/GGBLayer.m Thu May 29 15:04:06 2008 -0700 @@ -116,6 +116,7 @@ - (CGFloat) cornerRadius {return _cornerRadius;} - (CGFloat) borderWidth {return _borderWidth;} +- (CGColorRef) backgroundColor {return _realBGColor;} - (CGColorRef) borderColor {return _borderColor;} - (void) setCornerRadius: (CGFloat)r @@ -236,3 +237,54 @@ @end + + + +#pragma mark - +#pragma mark UTILITIES: + + +void BeginDisableAnimations(void) +{ + [CATransaction begin]; + [CATransaction setValue:(id)kCFBooleanTrue + forKey:kCATransactionDisableActions]; +} + +void EndDisableAnimations(void) +{ + [CATransaction commit]; +} + + +void ChangeSuperlayer( CALayer *layer, CALayer *newSuperlayer, int index ) +{ + // Disable actions, else the layer will move to the wrong place and then back! + [CATransaction flush]; + BeginDisableAnimations(); + + CGPoint pos = layer.position; + if( layer.superlayer ) + pos = [newSuperlayer convertPoint: pos fromLayer: layer.superlayer]; + [layer retain]; + [layer removeFromSuperlayer]; + layer.position = pos; + if( index >= 0 ) + [newSuperlayer insertSublayer: layer atIndex: index]; + else + [newSuperlayer addSublayer: layer]; + [layer release]; + + EndDisableAnimations(); +} + + +void RemoveImmediately( CALayer *layer ) +{ + [CATransaction flush]; + BeginDisableAnimations(); + [layer removeFromSuperlayer]; + EndDisableAnimations(); +} + + diff -r 45c82a071aca -r a59acc683080 Source/GGBTextLayer.m --- a/Source/GGBTextLayer.m Wed May 28 12:47:10 2008 -0700 +++ b/Source/GGBTextLayer.m Thu May 29 15:04:06 2008 -0700 @@ -61,14 +61,15 @@ label.alignmentMode = mode; // Get the bounds of the interior of the superlayer: - CGFloat inset = round(font.pointSize/8); + CGFloat yinset = 0; if( [superlayer respondsToSelector: @selector(borderWidth)] ) - inset += ((GGBLayer*)superlayer).borderWidth; - CGRect bounds = CGRectInset(superlayer.bounds, inset, inset); - if( mode==@"center" ) { - // horizontal centering: ignore x inset: - bounds = CGRectInset(bounds,-inset,0); - } + yinset += ((GGBLayer*)superlayer).borderWidth; + CGFloat xinset; + if( mode==@"center" ) + xinset = 0; + else + xinset = yinset + round(font.pointSize/3.0); + CGRect bounds = CGRectInset(superlayer.bounds, xinset,yinset); // Compute y position of bottom of layer's frame. (Remember, descender is negative!) CGFloat y = bounds.origin.y; diff -r 45c82a071aca -r a59acc683080 Source/GGBUtils.m --- a/Source/GGBUtils.m Wed May 28 12:47:10 2008 -0700 +++ b/Source/GGBUtils.m Thu May 29 15:04:06 2008 -0700 @@ -42,9 +42,47 @@ } +#if TARGET_OS_IPHONE +static SystemSoundID GetSound( NSString *name ) +{ + static NSMutableDictionary *sSoundIDs; + NSNumber *soundIDObj = [sSoundIDs objectForKey: name]; + if( ! soundIDObj ) { + NSLog(@"Loading sound '%@'",name); + NSString *type = name.pathExtension; + if( ! type.length ) + type = @"aiff"; + NSString *path = [[NSBundle mainBundle] pathForResource: name.stringByDeletingPathExtension + ofType: type]; + NSURL *url; + if( path ) + url = [NSURL fileURLWithPath: path]; + else { + NSLog(@"Couldn't find sound %@",name); + return 0; + } + //url = [NSURL fileURLWithPath: [@"/Library/Sounds/" stringByAppendingPathComponent: name]]; + SystemSoundID soundID; + if( AudioServicesCreateSystemSoundID((CFURLRef)url,&soundID) != noErr ) { + NSLog(@"Couldn't load sound %@",url); + return 0; + } + + soundIDObj = [NSNumber numberWithUnsignedInt: soundID]; + if( ! sSoundIDs ) + sSoundIDs = [[NSMutableDictionary alloc] init]; + [sSoundIDs setObject: soundIDObj forKey: name]; + } + return [soundIDObj unsignedIntValue]; +} +#endif + + void PreloadSound( NSString* name ) { -#if ! TARGET_OS_IPHONE +#if TARGET_OS_IPHONE + GetSound(name); +#else NSSound *sound = [[NSSound soundNamed: @"Pop"] copy]; sound.volume = 0; [sound play]; @@ -56,13 +94,7 @@ void PlaySound( NSString* name ) { #if TARGET_OS_IPHONE - NSURL *url = [NSURL fileURLWithPath: [@"/Library/Sounds/" stringByAppendingPathComponent: name]]; - SystemSoundID soundID; - if( AudioServicesCreateSystemSoundID((CFURLRef)url,&soundID) != noErr ) { - NSLog(@"Couldn't load sound %@",url); - return; - } - AudioServicesPlaySystemSound(soundID); + AudioServicesPlaySystemSound( GetSound(name) ); #else [[NSSound soundNamed: name] play]; #endif @@ -71,7 +103,7 @@ void Beep() { #if TARGET_OS_IPHONE - AudioServicesPlayAlertSound(0x00001000/*kSystemSoundID_UserPreferredAlert*/); + AudioServicesPlayAlertSound(kSystemSoundID_Vibrate); #else NSBeep(); #endif diff -r 45c82a071aca -r a59acc683080 Source/Game.m --- a/Source/Game.m Wed May 28 12:47:10 2008 -0700 +++ b/Source/Game.m Thu May 29 15:04:06 2008 -0700 @@ -196,11 +196,9 @@ if( turn==_currentTurn+1 ) { [self applyMoveString: [_moves objectAtIndex: _currentTurn]]; } else { - [CATransaction begin]; - [CATransaction setValue:(id)kCFBooleanTrue - forKey:kCATransactionDisableActions]; + BeginDisableAnimations(); self.stateString = [_states objectAtIndex: turn]; - [CATransaction commit]; + EndDisableAnimations(); } _currentTurn = turn; self.currentPlayer = [_players objectAtIndex: (turn % _players.count)]; diff -r 45c82a071aca -r a59acc683080 Source/Piece.h --- a/Source/Piece.h Wed May 28 12:47:10 2008 -0700 +++ b/Source/Piece.h Thu May 29 15:04:06 2008 -0700 @@ -38,10 +38,12 @@ - (id) initWithImageNamed: (NSString*)imageName scale: (CGFloat)scale; +- (void) setImageNamed: (NSString*)imageName scale: (CGFloat)scale; - (void) setImage: (CGImageRef)image scale: (CGFloat)scale; - (void) setImage: (CGImageRef)image; - (void) setImageNamed: (NSString*)name; @property (copy) NSString* imageName; + @end diff -r 45c82a071aca -r a59acc683080 Source/Piece.m --- a/Source/Piece.m Wed May 28 12:47:10 2008 -0700 +++ b/Source/Piece.m Thu May 29 15:04:06 2008 -0700 @@ -32,8 +32,7 @@ { self = [super init]; if (self != nil) { - self.imageName = imageName; - [self setImage: GetCGImageNamed(imageName) scale: scale]; + [self setImageNamed: imageName scale: scale]; self.zPosition = kPieceZ; } return self; @@ -66,20 +65,25 @@ @synthesize imageName=_imageName; +- (void) _setImage: (CGImageRef)image +{ + self.contents = (id) image; + self.bounds = CGRectMake(0,0,CGImageGetWidth(image),CGImageGetHeight(image)); + self.contentsGravity = kCAGravityResizeAspect; + self.minificationFilter = kCAFilterLinear; + self.imageName = nil; +} + + - (void) setImage: (CGImageRef)image scale: (CGFloat)scale { - self.contents = (id) image; - self.contentsGravity = @"resize"; - self.minificationFilter = kCAFilterLinear; - int width = CGImageGetWidth(image), height = CGImageGetHeight(image); - if( scale > 0 ) { - if( scale >= 4.0 ) - scale /= MAX(width,height); // interpret scale as target dimensions - width = ceil( width * scale); - height= ceil( height* scale); - } - self.bounds = CGRectMake(0,0,width,height); - self.imageName = nil; + [self _setImage: CreateScaledImage(image,scale)]; +} + +- (void) setImageNamed: (NSString*)imageName scale: (CGFloat)scale +{ + [self _setImage: GetScaledImageNamed(imageName,scale)]; + self.imageName = imageName; } - (void) setImage: (CGImageRef)image diff -r 45c82a071aca -r a59acc683080 Source/QuartzUtils.h --- a/Source/QuartzUtils.h Wed May 28 12:47:10 2008 -0700 +++ b/Source/QuartzUtils.h Thu May 29 15:04:06 2008 -0700 @@ -39,13 +39,6 @@ #endif -/** Moves a layer from one superlayer to another, without changing its position onscreen. */ -void ChangeSuperlayer( CALayer *layer, CALayer *newSuperlayer, int index ); - -/** Removes a layer from its superlayer without any fade-out animation. */ -void RemoveImmediately( CALayer *layer ); - - /** Loads an image or pattern file into a CGImage or CGPattern. If the name begins with "/", it's interpreted as an absolute filesystem path. Otherwise, it's the name of a resource that's looked up in the app bundle. @@ -61,6 +54,9 @@ CGImageRef GetCGImageFromPasteboard( NSPasteboard *pb ); #endif +CGImageRef CreateScaledImage( CGImageRef srcImage, CGFloat scale ); +CGImageRef GetScaledImageNamed( NSString *imageName, CGFloat scale ); + /** Creates a CGPattern from a CGImage. Caller must release it. */ CGPatternRef CreateImagePattern( CGImageRef image ); diff -r 45c82a071aca -r a59acc683080 Source/QuartzUtils.m --- a/Source/QuartzUtils.m Wed May 28 12:47:10 2008 -0700 +++ b/Source/QuartzUtils.m Thu May 29 15:04:06 2008 -0700 @@ -22,6 +22,7 @@ */ #import "QuartzUtils.h" #import +#import "Piece.h" CGColorRef kBlackColor, kWhiteColor, @@ -63,41 +64,6 @@ #endif -void ChangeSuperlayer( CALayer *layer, CALayer *newSuperlayer, int index ) -{ - // Disable actions, else the layer will move to the wrong place and then back! - [CATransaction flush]; - [CATransaction begin]; - [CATransaction setValue:(id)kCFBooleanTrue - forKey:kCATransactionDisableActions]; - - CGPoint pos = layer.position; - if( layer.superlayer ) - pos = [newSuperlayer convertPoint: pos fromLayer: layer.superlayer]; - [layer retain]; - [layer removeFromSuperlayer]; - layer.position = pos; - if( index >= 0 ) - [newSuperlayer insertSublayer: layer atIndex: index]; - else - [newSuperlayer addSublayer: layer]; - [layer release]; - - [CATransaction commit]; -} - - -void RemoveImmediately( CALayer *layer ) -{ - [CATransaction flush]; - [CATransaction begin]; - [CATransaction setValue:(id)kCFBooleanTrue - forKey:kCATransactionDisableActions]; - [layer removeFromSuperlayer]; - [CATransaction commit]; -} - - CGImageRef CreateCGImageFromFile( NSString *path ) { #if TARGET_OS_IPHONE @@ -195,6 +161,47 @@ #endif +CGImageRef CreateScaledImage( CGImageRef srcImage, CGFloat scale ) +{ + int width = CGImageGetWidth(srcImage), height = CGImageGetHeight(srcImage); + if( scale > 0 ) { + if( scale >= 4.0 ) + scale /= MAX(width,height); // interpret scale as target dimensions + width = ceil( width * scale); + height= ceil( height* scale); + } + + CGColorSpaceRef space = CGColorSpaceCreateDeviceRGB(); + CGContextRef ctx = CGBitmapContextCreate(NULL, width, height, 8, 4*width, space, + kCGBitmapByteOrderDefault | kCGImageAlphaPremultipliedLast); + CGColorSpaceRelease(space); + CGContextSetInterpolationQuality(ctx,kCGInterpolationHigh); + CGContextDrawImage(ctx, CGRectMake(0, 0, width, height), srcImage); + CGImageRef dstImage = CGBitmapContextCreateImage(ctx); + CGContextRelease(ctx); + return dstImage; +} + + +CGImageRef GetScaledImageNamed( NSString *imageName, CGFloat scale ) +{ + // For efficiency, loaded images are cached in a dictionary by name. + static NSMutableDictionary *sMap; + if( ! sMap ) + sMap = [[NSMutableDictionary alloc] init]; + + NSArray *key = [NSArray arrayWithObjects: imageName, [NSNumber numberWithFloat: scale], nil]; + CGImageRef image = (CGImageRef) [sMap objectForKey: key]; + if( ! image ) { + // Hasn't been cached yet, so load it: + image = CreateScaledImage(GetCGImageNamed(imageName), scale); + [sMap setObject: (id)image forKey: key]; + CGImageRelease(image); + } + return image; +} + + float GetPixelAlpha( CGImageRef image, CGSize imageSize, CGPoint pt ) { #if TARGET_OS_IPHONE diff -r 45c82a071aca -r a59acc683080 Source/iPhoneAppDelegate.m --- a/Source/iPhoneAppDelegate.m Wed May 28 12:47:10 2008 -0700 +++ b/Source/iPhoneAppDelegate.m Thu May 29 15:04:06 2008 -0700 @@ -13,6 +13,19 @@ #import "GGBUtils.h" +// Temporary HACK to fix logging problem in beta 6 iPhone OS +extern void _NSSetLogCStringFunction(void (*)(const char *string, unsigned length, BOOL withSyslogBanner)); +static void PrintNSLogMessage(const char *string, unsigned length, BOOL withSyslogBanner) +{ + puts(string); +} +static void HackNSLog(void) __attribute__((constructor)); +static void HackNSLog(void) +{ + _NSSetLogCStringFunction(PrintNSLogMessage); +} + + @implementation GGB_iPhoneAppDelegate @@ -23,9 +36,6 @@ - (void)applicationDidFinishLaunching:(UIApplication *)application { - for( NSString *family in [UIFont familyNames] ) - NSLog(@"%@: (%@)", family, [[UIFont fontNamesForFamilyName: family] componentsJoinedByString: @", "]); - // Create window self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease]; _window.layer.backgroundColor = GetCGPatternNamed(@"Background.png"); @@ -48,7 +58,7 @@ [_window addSubview: _headline]; // Start game: - [self startGameNamed: @"KlondikeGame"]; + [self startGameNamed: @"CheckersGame"]; // Show window [_window makeKeyAndVisible];