# HG changeset patch # User Jens Alfke # Date 1205195457 25200 # Node ID 3eb7be1dd7b693cf6c94b970783eacb193d5ff36 # Parent e9f7ba4718e1441c578052e8f4d11aa16d0cddb0 Tic-tac-toe works on the iPhone simulator! diff -r e9f7ba4718e1 -r 3eb7be1dd7b6 GeekGameBoard-iPhone.xcodeproj/project.pbxproj --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/GeekGameBoard-iPhone.xcodeproj/project.pbxproj Mon Mar 10 17:30:57 2008 -0700 @@ -0,0 +1,438 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 45; + objects = { + +/* Begin PBXBuildFile section */ + 1D3623EC0D0F72F000981E51 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D3623EB0D0F72F000981E51 /* CoreGraphics.framework */; }; + 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 */; }; + 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 */; }; + 279F4B6A0D85CBFC00B32DBF /* iPhoneAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 279F4B690D85CBFC00B32DBF /* iPhoneAppDelegate.m */; }; + 279F4B740D85CDE900B32DBF /* ToolbarAdvanced.icns in Resources */ = {isa = PBXBuildFile; fileRef = 279F4B720D85CDE900B32DBF /* ToolbarAdvanced.icns */; }; + 279F4C1D0D85D0AF00B32DBF /* X.tiff in Resources */ = {isa = PBXBuildFile; fileRef = 279F4C1C0D85D0AF00B32DBF /* X.tiff */; }; + 279F4C1F0D85D0CB00B32DBF /* O.tiff in Resources */ = {isa = PBXBuildFile; fileRef = 279F4C1E0D85D0CB00B32DBF /* O.tiff */; }; + 279F4C740D85D43800B32DBF /* Background.png in Resources */ = {isa = PBXBuildFile; fileRef = 279F4C730D85D43800B32DBF /* Background.png */; }; + 27C99B0F0D820868005AFD4F /* BoardUIView.m in Sources */ = {isa = PBXBuildFile; fileRef = 27C99AE40D820868005AFD4F /* BoardUIView.m */; }; + 27C99B100D820868005AFD4F /* Bit.m in Sources */ = {isa = PBXBuildFile; fileRef = 27C99AE60D820868005AFD4F /* Bit.m */; }; + 27C99B110D820868005AFD4F /* BitHolder.m in Sources */ = {isa = PBXBuildFile; fileRef = 27C99AE80D820868005AFD4F /* BitHolder.m */; }; + 27C99B120D820868005AFD4F /* Stack.m in Sources */ = {isa = PBXBuildFile; fileRef = 27C99AEA0D820868005AFD4F /* Stack.m */; }; + 27C99B130D820868005AFD4F /* Card.m in Sources */ = {isa = PBXBuildFile; fileRef = 27C99AED0D820868005AFD4F /* Card.m */; }; + 27C99B140D820868005AFD4F /* Deck.m in Sources */ = {isa = PBXBuildFile; fileRef = 27C99AEF0D820868005AFD4F /* Deck.m */; }; + 27C99B150D820868005AFD4F /* PlayingCard.m in Sources */ = {isa = PBXBuildFile; fileRef = 27C99AF10D820868005AFD4F /* PlayingCard.m */; }; + 27C99B160D820868005AFD4F /* Piece.m in Sources */ = {isa = PBXBuildFile; fileRef = 27C99AF40D820868005AFD4F /* Piece.m */; }; + 27C99B170D820868005AFD4F /* DiscPiece.m in Sources */ = {isa = PBXBuildFile; fileRef = 27C99AF60D820868005AFD4F /* DiscPiece.m */; }; + 27C99B180D820868005AFD4F /* Grid.m in Sources */ = {isa = PBXBuildFile; fileRef = 27C99AF80D820868005AFD4F /* Grid.m */; }; + 27C99B190D820868005AFD4F /* HexGrid.m in Sources */ = {isa = PBXBuildFile; fileRef = 27C99AFA0D820868005AFD4F /* HexGrid.m */; }; + 27C99B1A0D820868005AFD4F /* Dispenser.m in Sources */ = {isa = PBXBuildFile; fileRef = 27C99AFC0D820868005AFD4F /* Dispenser.m */; }; + 27C99B1B0D820868005AFD4F /* Game.m in Sources */ = {isa = PBXBuildFile; fileRef = 27C99AFF0D820868005AFD4F /* Game.m */; }; + 27C99B1C0D820868005AFD4F /* TicTacToeGame.m in Sources */ = {isa = PBXBuildFile; fileRef = 27C99B010D820868005AFD4F /* TicTacToeGame.m */; }; + 27C99B1D0D820868005AFD4F /* CheckersGame.m in Sources */ = {isa = PBXBuildFile; fileRef = 27C99B030D820868005AFD4F /* CheckersGame.m */; }; + 27C99B1E0D820868005AFD4F /* HexchequerGame.m in Sources */ = {isa = PBXBuildFile; fileRef = 27C99B050D820868005AFD4F /* HexchequerGame.m */; }; + 27C99B1F0D820868005AFD4F /* GoGame.m in Sources */ = {isa = PBXBuildFile; fileRef = 27C99B070D820868005AFD4F /* GoGame.m */; }; + 27C99B200D820868005AFD4F /* KlondikeGame.m in Sources */ = {isa = PBXBuildFile; fileRef = 27C99B090D820868005AFD4F /* KlondikeGame.m */; }; + 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 */; }; +/* 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; }; + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; + 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 = ""; }; + 279F4B610D85C63000B32DBF /* GGBTextLayer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GGBTextLayer.m; sourceTree = ""; }; + 279F4B680D85CBFC00B32DBF /* iPhoneAppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = iPhoneAppDelegate.h; path = Source/iPhoneAppDelegate.h; sourceTree = ""; }; + 279F4B690D85CBFC00B32DBF /* iPhoneAppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = iPhoneAppDelegate.m; path = Source/iPhoneAppDelegate.m; sourceTree = ""; }; + 279F4B720D85CDE900B32DBF /* ToolbarAdvanced.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; name = ToolbarAdvanced.icns; path = /System/Library/CoreServices/CoreTypes.bundle/Contents/Resources/ToolbarAdvanced.icns; sourceTree = ""; }; + 279F4C1C0D85D0AF00B32DBF /* X.tiff */ = {isa = PBXFileReference; lastKnownFileType = image.tiff; path = X.tiff; sourceTree = ""; }; + 279F4C1E0D85D0CB00B32DBF /* O.tiff */ = {isa = PBXFileReference; lastKnownFileType = image.tiff; path = O.tiff; sourceTree = ""; }; + 279F4C730D85D43800B32DBF /* Background.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Background.png; sourceTree = ""; }; + 27C99AE30D820868005AFD4F /* BoardUIView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BoardUIView.h; sourceTree = ""; }; + 27C99AE40D820868005AFD4F /* BoardUIView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BoardUIView.m; sourceTree = ""; }; + 27C99AE50D820868005AFD4F /* Bit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Bit.h; sourceTree = ""; }; + 27C99AE60D820868005AFD4F /* Bit.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Bit.m; sourceTree = ""; }; + 27C99AE70D820868005AFD4F /* BitHolder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BitHolder.h; sourceTree = ""; }; + 27C99AE80D820868005AFD4F /* BitHolder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BitHolder.m; sourceTree = ""; }; + 27C99AE90D820868005AFD4F /* Stack.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Stack.h; sourceTree = ""; }; + 27C99AEA0D820868005AFD4F /* Stack.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Stack.m; sourceTree = ""; }; + 27C99AEC0D820868005AFD4F /* Card.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Card.h; sourceTree = ""; }; + 27C99AED0D820868005AFD4F /* Card.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Card.m; sourceTree = ""; }; + 27C99AEE0D820868005AFD4F /* Deck.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Deck.h; sourceTree = ""; }; + 27C99AEF0D820868005AFD4F /* Deck.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Deck.m; sourceTree = ""; }; + 27C99AF00D820868005AFD4F /* PlayingCard.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PlayingCard.h; sourceTree = ""; }; + 27C99AF10D820868005AFD4F /* PlayingCard.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PlayingCard.m; sourceTree = ""; }; + 27C99AF30D820868005AFD4F /* Piece.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Piece.h; sourceTree = ""; }; + 27C99AF40D820868005AFD4F /* Piece.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Piece.m; sourceTree = ""; }; + 27C99AF50D820868005AFD4F /* DiscPiece.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DiscPiece.h; sourceTree = ""; }; + 27C99AF60D820868005AFD4F /* DiscPiece.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DiscPiece.m; sourceTree = ""; }; + 27C99AF70D820868005AFD4F /* Grid.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Grid.h; sourceTree = ""; }; + 27C99AF80D820868005AFD4F /* Grid.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Grid.m; sourceTree = ""; }; + 27C99AF90D820868005AFD4F /* HexGrid.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HexGrid.h; sourceTree = ""; }; + 27C99AFA0D820868005AFD4F /* HexGrid.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HexGrid.m; sourceTree = ""; }; + 27C99AFB0D820868005AFD4F /* Dispenser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Dispenser.h; sourceTree = ""; }; + 27C99AFC0D820868005AFD4F /* Dispenser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Dispenser.m; sourceTree = ""; }; + 27C99AFE0D820868005AFD4F /* Game.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Game.h; sourceTree = ""; }; + 27C99AFF0D820868005AFD4F /* Game.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Game.m; sourceTree = ""; }; + 27C99B000D820868005AFD4F /* TicTacToeGame.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TicTacToeGame.h; sourceTree = ""; }; + 27C99B010D820868005AFD4F /* TicTacToeGame.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TicTacToeGame.m; sourceTree = ""; }; + 27C99B020D820868005AFD4F /* CheckersGame.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CheckersGame.h; sourceTree = ""; }; + 27C99B030D820868005AFD4F /* CheckersGame.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CheckersGame.m; sourceTree = ""; }; + 27C99B040D820868005AFD4F /* HexchequerGame.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HexchequerGame.h; sourceTree = ""; }; + 27C99B050D820868005AFD4F /* HexchequerGame.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HexchequerGame.m; sourceTree = ""; }; + 27C99B060D820868005AFD4F /* GoGame.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GoGame.h; sourceTree = ""; }; + 27C99B070D820868005AFD4F /* GoGame.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GoGame.m; sourceTree = ""; }; + 27C99B080D820868005AFD4F /* KlondikeGame.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KlondikeGame.h; sourceTree = ""; }; + 27C99B090D820868005AFD4F /* KlondikeGame.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KlondikeGame.m; sourceTree = ""; }; + 27C99B0A0D820868005AFD4F /* QuartzUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = QuartzUtils.h; sourceTree = ""; }; + 27C99B0B0D820868005AFD4F /* QuartzUtils.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = QuartzUtils.m; sourceTree = ""; }; + 27C99B0C0D820868005AFD4F /* GGBUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GGBUtils.h; sourceTree = ""; }; + 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 = ""; }; + 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 = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 1D60588F0D05DD3D006BFB54 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */, + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */, + 1D3623EC0D0F72F000981E51 /* CoreGraphics.framework in Frameworks */, + 279F4B590D85C51700B32DBF /* AudioToolbox.framework in Frameworks */, + 279F4B5B0D85C51700B32DBF /* QuartzCore.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 1058C7A0FEA54F0111CA2CBB /* Linked Frameworks */ = { + isa = PBXGroup; + children = ( + 1D3623EB0D0F72F000981E51 /* CoreGraphics.framework */, + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */, + 1D30AB110D05D00D00671497 /* Foundation.framework */, + ); + name = "Linked Frameworks"; + sourceTree = ""; + }; + 1058C7A2FEA54F0111CA2CBB /* Other Frameworks */ = { + isa = PBXGroup; + children = ( + ); + name = "Other Frameworks"; + sourceTree = ""; + }; + 19C28FACFE9D520D11CA2CBB /* Products */ = { + isa = PBXGroup; + children = ( + 1D6058910D05DD3D006BFB54 /* GGB-iPhone.app */, + ); + name = Products; + sourceTree = ""; + }; + 27C99AE00D820868005AFD4F /* Source */ = { + isa = PBXGroup; + children = ( + 27C99AE30D820868005AFD4F /* BoardUIView.h */, + 27C99AE40D820868005AFD4F /* BoardUIView.m */, + 27C99B4F0D82106E005AFD4F /* GGBLayer.h */, + 27C99B500D82106E005AFD4F /* GGBLayer.m */, + 279F4B600D85C63000B32DBF /* GGBTextLayer.h */, + 279F4B610D85C63000B32DBF /* GGBTextLayer.m */, + 27C99AE50D820868005AFD4F /* Bit.h */, + 27C99AE60D820868005AFD4F /* Bit.m */, + 27C99AE70D820868005AFD4F /* BitHolder.h */, + 27C99AE80D820868005AFD4F /* BitHolder.m */, + 27C99AE90D820868005AFD4F /* Stack.h */, + 27C99AEA0D820868005AFD4F /* Stack.m */, + 27C99AF20D820868005AFD4F /* Boards and Pieces */, + 27C99AEB0D820868005AFD4F /* Cards */, + 27C99AFD0D820868005AFD4F /* Games */, + 27C99B0A0D820868005AFD4F /* QuartzUtils.h */, + 27C99B0B0D820868005AFD4F /* QuartzUtils.m */, + 27C99B0C0D820868005AFD4F /* GGBUtils.h */, + 27C99B0D0D820868005AFD4F /* GGBUtils.m */, + ); + path = Source; + sourceTree = ""; + }; + 27C99AEB0D820868005AFD4F /* Cards */ = { + isa = PBXGroup; + children = ( + 27C99AEC0D820868005AFD4F /* Card.h */, + 27C99AED0D820868005AFD4F /* Card.m */, + 27C99AEE0D820868005AFD4F /* Deck.h */, + 27C99AEF0D820868005AFD4F /* Deck.m */, + 27C99AF00D820868005AFD4F /* PlayingCard.h */, + 27C99AF10D820868005AFD4F /* PlayingCard.m */, + ); + name = Cards; + sourceTree = ""; + }; + 27C99AF20D820868005AFD4F /* Boards and Pieces */ = { + isa = PBXGroup; + children = ( + 27C99AF30D820868005AFD4F /* Piece.h */, + 27C99AF40D820868005AFD4F /* Piece.m */, + 27C99AF50D820868005AFD4F /* DiscPiece.h */, + 27C99AF60D820868005AFD4F /* DiscPiece.m */, + 27C99AF70D820868005AFD4F /* Grid.h */, + 27C99AF80D820868005AFD4F /* Grid.m */, + 27C99AF90D820868005AFD4F /* HexGrid.h */, + 27C99AFA0D820868005AFD4F /* HexGrid.m */, + 27C99AFB0D820868005AFD4F /* Dispenser.h */, + 27C99AFC0D820868005AFD4F /* Dispenser.m */, + ); + name = "Boards and Pieces"; + sourceTree = ""; + }; + 27C99AFD0D820868005AFD4F /* Games */ = { + isa = PBXGroup; + children = ( + 27C99AFE0D820868005AFD4F /* Game.h */, + 27C99AFF0D820868005AFD4F /* Game.m */, + 27C99B000D820868005AFD4F /* TicTacToeGame.h */, + 27C99B010D820868005AFD4F /* TicTacToeGame.m */, + 27C99B020D820868005AFD4F /* CheckersGame.h */, + 27C99B030D820868005AFD4F /* CheckersGame.m */, + 27C99B040D820868005AFD4F /* HexchequerGame.h */, + 27C99B050D820868005AFD4F /* HexchequerGame.m */, + 27C99B060D820868005AFD4F /* GoGame.h */, + 27C99B070D820868005AFD4F /* GoGame.m */, + 27C99B080D820868005AFD4F /* KlondikeGame.h */, + 27C99B090D820868005AFD4F /* KlondikeGame.m */, + ); + name = Games; + sourceTree = ""; + }; + 29B97314FDCFA39411CA2CEA /* CustomTemplate */ = { + isa = PBXGroup; + children = ( + 27C99AE00D820868005AFD4F /* Source */, + 29B97315FDCFA39411CA2CEA /* Other Sources */, + 29B97317FDCFA39411CA2CEA /* Resources */, + 29B97323FDCFA39411CA2CEA /* Frameworks */, + 19C28FACFE9D520D11CA2CBB /* Products */, + 279F4B580D85C51700B32DBF /* AudioToolbox.framework */, + 279F4B5A0D85C51700B32DBF /* QuartzCore.framework */, + ); + name = CustomTemplate; + sourceTree = ""; + }; + 29B97315FDCFA39411CA2CEA /* Other Sources */ = { + isa = PBXGroup; + children = ( + 279F4B680D85CBFC00B32DBF /* iPhoneAppDelegate.h */, + 279F4B690D85CBFC00B32DBF /* iPhoneAppDelegate.m */, + 32CA4F630368D1EE00C91783 /* GGB-iPhone_Prefix.pch */, + 29B97316FDCFA39411CA2CEA /* main-iPhone.m */, + ); + name = "Other Sources"; + sourceTree = ""; + }; + 29B97317FDCFA39411CA2CEA /* Resources */ = { + isa = PBXGroup; + children = ( + 279F4C730D85D43800B32DBF /* Background.png */, + 279F4C1C0D85D0AF00B32DBF /* X.tiff */, + 279F4C1E0D85D0CB00B32DBF /* O.tiff */, + 279F4B720D85CDE900B32DBF /* ToolbarAdvanced.icns */, + 8D1107310486CEB800E47090 /* Info-iPhone.plist */, + ); + path = Resources; + sourceTree = ""; + }; + 29B97323FDCFA39411CA2CEA /* Frameworks */ = { + isa = PBXGroup; + children = ( + 1058C7A0FEA54F0111CA2CBB /* Linked Frameworks */, + 1058C7A2FEA54F0111CA2CBB /* Other Frameworks */, + ); + name = Frameworks; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 1D6058900D05DD3D006BFB54 /* GGB-iPhone */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "GGB-iPhone" */; + buildPhases = ( + 1D60588D0D05DD3D006BFB54 /* Resources */, + 1D60588E0D05DD3D006BFB54 /* Sources */, + 1D60588F0D05DD3D006BFB54 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "GGB-iPhone"; + productName = "GGB-iPhone"; + productReference = 1D6058910D05DD3D006BFB54 /* GGB-iPhone.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 29B97313FDCFA39411CA2CEA /* Project object */ = { + isa = PBXProject; + buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "GeekGameBoard-iPhone" */; + compatibilityVersion = "Xcode 3.1"; + hasScannedForEncodings = 1; + mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 1D6058900D05DD3D006BFB54 /* GGB-iPhone */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 1D60588D0D05DD3D006BFB54 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 279F4B740D85CDE900B32DBF /* ToolbarAdvanced.icns in Resources */, + 279F4C1D0D85D0AF00B32DBF /* X.tiff in Resources */, + 279F4C1F0D85D0CB00B32DBF /* O.tiff in Resources */, + 279F4C740D85D43800B32DBF /* Background.png in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 1D60588E0D05DD3D006BFB54 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589B0D05DD56006BFB54 /* main-iPhone.m in Sources */, + 27C99B0F0D820868005AFD4F /* BoardUIView.m in Sources */, + 27C99B100D820868005AFD4F /* Bit.m in Sources */, + 27C99B110D820868005AFD4F /* BitHolder.m in Sources */, + 27C99B120D820868005AFD4F /* Stack.m in Sources */, + 27C99B130D820868005AFD4F /* Card.m in Sources */, + 27C99B140D820868005AFD4F /* Deck.m in Sources */, + 27C99B150D820868005AFD4F /* PlayingCard.m in Sources */, + 27C99B160D820868005AFD4F /* Piece.m in Sources */, + 27C99B170D820868005AFD4F /* DiscPiece.m in Sources */, + 27C99B180D820868005AFD4F /* Grid.m in Sources */, + 27C99B190D820868005AFD4F /* HexGrid.m in Sources */, + 27C99B1A0D820868005AFD4F /* Dispenser.m in Sources */, + 27C99B1B0D820868005AFD4F /* Game.m in Sources */, + 27C99B1C0D820868005AFD4F /* TicTacToeGame.m in Sources */, + 27C99B1D0D820868005AFD4F /* CheckersGame.m in Sources */, + 27C99B1E0D820868005AFD4F /* HexchequerGame.m in Sources */, + 27C99B1F0D820868005AFD4F /* GoGame.m in Sources */, + 27C99B200D820868005AFD4F /* KlondikeGame.m in Sources */, + 27C99B210D820868005AFD4F /* QuartzUtils.m in Sources */, + 27C99B220D820868005AFD4F /* GGBUtils.m in Sources */, + 27C99B510D82106E005AFD4F /* GGBLayer.m in Sources */, + 279F4B620D85C63000B32DBF /* GGBTextLayer.m in Sources */, + 279F4B6A0D85CBFC00B32DBF /* iPhoneAppDelegate.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + 1D6058940D05DD3E006BFB54 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "Source/GGB-iPhone_Prefix.pch"; + INFOPLIST_FILE = "Resources/Info-iPhone.plist"; + PREBINDING = NO; + PRODUCT_NAME = "GGB-iPhone"; + }; + name = Debug; + }; + 1D6058950D05DD3E006BFB54 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = YES; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "Source/GGB-iPhone_Prefix.pch"; + INFOPLIST_FILE = "Resources/Info-iPhone.plist"; + PREBINDING = NO; + PRODUCT_NAME = "GGB-iPhone"; + WRAPPER_EXTENSION = app; + }; + name = Release; + }; + C01FCF4F08A954540054247B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + "CODE_SIGN_IDENTITY[sdk=aspen*]" = "iPhone Developer"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_TREAT_WARNINGS_AS_ERRORS = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + ONLY_ACTIVE_ARCH = YES; + PREBINDING = NO; + SDKROOT = aspen1.2; + WARNING_CFLAGS = "-Wall"; + }; + name = Debug; + }; + C01FCF5008A954540054247B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + GCC_TREAT_WARNINGS_AS_ERRORS = YES; + PREBINDING = NO; + SDKROOT = aspen1.2; + WARNING_CFLAGS = "-Wall"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "GGB-iPhone" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1D6058940D05DD3E006BFB54 /* Debug */, + 1D6058950D05DD3E006BFB54 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + C01FCF4E08A954540054247B /* Build configuration list for PBXProject "GeekGameBoard-iPhone" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + C01FCF4F08A954540054247B /* Debug */, + C01FCF5008A954540054247B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 29B97313FDCFA39411CA2CEA /* Project object */; +} diff -r e9f7ba4718e1 -r 3eb7be1dd7b6 GeekGameBoard.xcodeproj/project.pbxproj --- a/GeekGameBoard.xcodeproj/project.pbxproj Fri Mar 07 11:43:02 2008 -0800 +++ b/GeekGameBoard.xcodeproj/project.pbxproj Mon Mar 10 17:30:57 2008 -0700 @@ -24,6 +24,11 @@ 276DFC570D00890C00D329AE /* Yellow Ball.png in Resources */ = {isa = PBXBuildFile; fileRef = 276DFC540D00890C00D329AE /* Yellow Ball.png */; }; 276DFC580D00890C00D329AE /* White Ball.png in Resources */ = {isa = PBXBuildFile; fileRef = 276DFC550D00890C00D329AE /* White Ball.png */; }; 2795C2B80CC278C800D7B2BD /* Piece.m in Sources */ = {isa = PBXBuildFile; fileRef = 2795C2B70CC278C800D7B2BD /* Piece.m */; }; + 279F4D870D8606C200B32DBF /* GGBLayer.m in Sources */ = {isa = PBXBuildFile; fileRef = 279F4D840D8606C200B32DBF /* GGBLayer.m */; }; + 279F4D880D8606C200B32DBF /* GGBTextLayer.m in Sources */ = {isa = PBXBuildFile; fileRef = 279F4D860D8606C200B32DBF /* GGBTextLayer.m */; }; + 279F4DB20D8607AD00B32DBF /* O.tiff in Resources */ = {isa = PBXBuildFile; fileRef = 279F4DB00D8607AD00B32DBF /* O.tiff */; }; + 279F4DB30D8607AD00B32DBF /* X.tiff in Resources */ = {isa = PBXBuildFile; fileRef = 279F4DB10D8607AD00B32DBF /* X.tiff */; }; + 279F4DE20D8609C200B32DBF /* Background.png in Resources */ = {isa = PBXBuildFile; fileRef = 279F4DE10D8609C200B32DBF /* Background.png */; }; 27B7543E0D08884F000516B9 /* Wood.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 27B7543D0D08884F000516B9 /* Wood.jpg */; }; 27C999C30D81185E005AFD4F /* GGBUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = 27C999C20D81185E005AFD4F /* GGBUtils.m */; }; 27CCA8050CB8A3F9001CFE24 /* BoardView.m in Sources */ = {isa = PBXBuildFile; fileRef = 27CCA8040CB8A3F9001CFE24 /* BoardView.m */; }; @@ -73,9 +78,18 @@ 276DFC550D00890C00D329AE /* White Ball.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "White Ball.png"; path = "Resources/White Ball.png"; sourceTree = ""; }; 2795C2B60CC278C800D7B2BD /* Piece.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Piece.h; sourceTree = ""; }; 2795C2B70CC278C800D7B2BD /* Piece.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Piece.m; sourceTree = ""; }; + 279F4D830D8606C200B32DBF /* GGBLayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GGBLayer.h; sourceTree = ""; }; + 279F4D840D8606C200B32DBF /* GGBLayer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GGBLayer.m; sourceTree = ""; }; + 279F4D850D8606C200B32DBF /* GGBTextLayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GGBTextLayer.h; sourceTree = ""; }; + 279F4D860D8606C200B32DBF /* GGBTextLayer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GGBTextLayer.m; sourceTree = ""; }; + 279F4DB00D8607AD00B32DBF /* O.tiff */ = {isa = PBXFileReference; lastKnownFileType = image.tiff; name = O.tiff; path = Resources/O.tiff; sourceTree = ""; }; + 279F4DB10D8607AD00B32DBF /* X.tiff */ = {isa = PBXFileReference; lastKnownFileType = image.tiff; name = X.tiff; path = Resources/X.tiff; sourceTree = ""; }; + 279F4DE10D8609C200B32DBF /* Background.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Background.png; path = Resources/Background.png; sourceTree = ""; }; 27B7543D0D08884F000516B9 /* Wood.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; name = Wood.jpg; path = Resources/Wood.jpg; sourceTree = ""; }; 27C999C10D81185E005AFD4F /* GGBUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GGBUtils.h; sourceTree = ""; }; 27C999C20D81185E005AFD4F /* GGBUtils.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GGBUtils.m; sourceTree = ""; }; + 27C99AB40D820500005AFD4F /* BoardUIView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BoardUIView.h; sourceTree = ""; }; + 27C99AB50D820500005AFD4F /* BoardUIView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BoardUIView.m; sourceTree = ""; }; 27CCA8030CB8A3F9001CFE24 /* BoardView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BoardView.h; sourceTree = ""; }; 27CCA8040CB8A3F9001CFE24 /* BoardView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BoardView.m; sourceTree = ""; }; 27CCA95E0CB8A74D001CFE24 /* Quartz.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Quartz.framework; path = /System/Library/Frameworks/Quartz.framework; sourceTree = ""; }; @@ -118,6 +132,8 @@ children = ( 27CCA8030CB8A3F9001CFE24 /* BoardView.h */, 27CCA8040CB8A3F9001CFE24 /* BoardView.m */, + 27C99AB40D820500005AFD4F /* BoardUIView.h */, + 27C99AB50D820500005AFD4F /* BoardUIView.m */, 27CCABBD0CB9496B001CFE24 /* Bit.h */, 27CCABBE0CB9496B001CFE24 /* Bit.m */, 2731E2A60CD5630600E6E4C8 /* BitHolder.h */, @@ -127,6 +143,10 @@ 27275C440CC70095009C4C6C /* Cards */, 27275C450CC700C4009C4C6C /* Boards and Pieces */, 27275C480CC700D8009C4C6C /* Games */, + 279F4D830D8606C200B32DBF /* GGBLayer.h */, + 279F4D840D8606C200B32DBF /* GGBLayer.m */, + 279F4D850D8606C200B32DBF /* GGBTextLayer.h */, + 279F4D860D8606C200B32DBF /* GGBTextLayer.m */, 2722526D0CC2E86600814095 /* QuartzUtils.h */, 2722526E0CC2E86600814095 /* QuartzUtils.m */, 27C999C10D81185E005AFD4F /* GGBUtils.h */, @@ -240,11 +260,14 @@ 29B97318FDCFA39411CA2CEA /* MainMenu.nib */, 8D1107310486CEB800E47090 /* Info.plist */, 089C165CFE840E0CC02AAC07 /* InfoPlist.strings */, + 279F4DE10D8609C200B32DBF /* Background.png */, 276DFC400D00867000D329AE /* Green Ball.png */, 276DFC530D00890C00D329AE /* Red Ball.png */, 276DFC540D00890C00D329AE /* Yellow Ball.png */, 276DFC550D00890C00D329AE /* White Ball.png */, 27B7543D0D08884F000516B9 /* Wood.jpg */, + 279F4DB00D8607AD00B32DBF /* O.tiff */, + 279F4DB10D8607AD00B32DBF /* X.tiff */, ); name = Resources; sourceTree = ""; @@ -308,6 +331,9 @@ 276DFC570D00890C00D329AE /* Yellow Ball.png in Resources */, 276DFC580D00890C00D329AE /* White Ball.png in Resources */, 27B7543E0D08884F000516B9 /* Wood.jpg in Resources */, + 279F4DB20D8607AD00B32DBF /* O.tiff in Resources */, + 279F4DB30D8607AD00B32DBF /* X.tiff in Resources */, + 279F4DE20D8609C200B32DBF /* Background.png in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -340,6 +366,8 @@ 2731E2A80CD5630600E6E4C8 /* BitHolder.m in Sources */, 274124060CFCCF9D00842A9B /* DemoBoardView.m in Sources */, 27C999C30D81185E005AFD4F /* GGBUtils.m in Sources */, + 279F4D870D8606C200B32DBF /* GGBLayer.m in Sources */, + 279F4D880D8606C200B32DBF /* GGBTextLayer.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -412,6 +440,7 @@ GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; PREBINDING = NO; + SDKROOT = "$(DEVELOPER_SDK_DIR)/MacOSX10.5.sdk"; WARNING_CFLAGS = "-Wall"; }; name = Debug; @@ -429,6 +458,7 @@ GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNUSED_VARIABLE = YES; PREBINDING = NO; + SDKROOT = "$(DEVELOPER_SDK_DIR)/MacOSX10.5.sdk"; WARNING_CFLAGS = "-Wall"; }; name = Release; diff -r e9f7ba4718e1 -r 3eb7be1dd7b6 Resources/Background.png Binary file Resources/Background.png has changed diff -r e9f7ba4718e1 -r 3eb7be1dd7b6 Resources/Info-iPhone.plist --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Resources/Info-iPhone.plist Mon Mar 10 17:30:57 2008 -0700 @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleDisplayName + ${PRODUCT_NAME} + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIconFile + + CFBundleIdentifier + com.yourcompany.${PRODUCT_NAME:identifier} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + APPL + CFBundleSignature + ???? + CFBundleVersion + 1.0 + + \ No newline at end of file diff -r e9f7ba4718e1 -r 3eb7be1dd7b6 Resources/O.tiff Binary file Resources/O.tiff has changed diff -r e9f7ba4718e1 -r 3eb7be1dd7b6 Resources/X.tiff Binary file Resources/X.tiff has changed diff -r e9f7ba4718e1 -r 3eb7be1dd7b6 Source/Bit.h --- a/Source/Bit.h Fri Mar 07 11:43:02 2008 -0800 +++ b/Source/Bit.h Mon Mar 10 17:30:57 2008 -0700 @@ -20,7 +20,7 @@ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#import +#import "GGBLayer.h" @class Game, Player; @@ -39,7 +39,7 @@ /** A moveable item in a card/board game. Abstract superclass of Card and Piece. */ -@interface Bit : CALayer +@interface Bit : GGBLayer { @private int _restingZ; // Original z position, saved while pickedUp diff -r e9f7ba4718e1 -r 3eb7be1dd7b6 Source/Bit.m --- a/Source/Bit.m Fri Mar 07 11:43:02 2008 -0800 +++ b/Source/Bit.m Mon Mar 10 17:30:57 2008 -0700 @@ -30,43 +30,11 @@ - (id) copyWithZone: (NSZone*)zone { - // NSLayer isn't copyable, but it is archivable. So create a copy by archiving to - // a temporary data block, then unarchiving a new layer from that block. - - // One complication is that, due to a bug in Core Animation, CALayer can't archive - // a pattern-based CGColor. So as a workaround, clear the background before archiving, - // then restore it afterwards. - - // Also, archiving a CALayer with an image in it leaks memory. (Filed as rdar://5786865 ) - // As a workaround, clear the contents before archiving, then restore. - - CGColorRef bg = CGColorRetain(self.backgroundColor); - self.backgroundColor = NULL; - id contents = [self.contents retain]; - self.contents = nil; - - NSData *data = [NSKeyedArchiver archivedDataWithRootObject: self]; - - self.backgroundColor = bg; - self.contents = contents; - - Bit *clone = [NSKeyedUnarchiver unarchiveObjectWithData: data]; - clone.backgroundColor = bg; - clone.contents = contents; - CGColorRelease(bg); - [contents release]; - - clone->_owner = _owner; // _owner is not archived - return [clone retain]; + Bit *clone = [super copyWithZone: zone]; + clone->_owner = _owner; + return clone; } - -- (NSString*) description -{ - return [NSString stringWithFormat: @"%@[(%g,%g)]", self.class,self.position.x,self.position.y]; -} - - @synthesize owner=_owner; - (BOOL) isFriendly {return _owner.friendly;} @@ -124,9 +92,11 @@ } self.zPosition = z; +#if !TARGET_OS_ASPEN self.shadowOpacity = shadow; self.shadowOffset = CGSizeMake(offset,-offset); self.shadowRadius = radius; +#endif self.opacity = opacity; self.scale *= scale; } diff -r e9f7ba4718e1 -r 3eb7be1dd7b6 Source/BitHolder.h --- a/Source/BitHolder.h Fri Mar 07 11:43:02 2008 -0800 +++ b/Source/BitHolder.h Mon Mar 10 17:30:57 2008 -0700 @@ -20,7 +20,7 @@ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#import +#import "GGBLayer.h" @class Bit; @@ -63,7 +63,7 @@ /** A basic implementation of the BitHolder protocol. */ -@interface BitHolder : CALayer +@interface BitHolder : GGBLayer { @protected Bit *_bit; diff -r e9f7ba4718e1 -r 3eb7be1dd7b6 Source/BoardUIView.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/BoardUIView.h Mon Mar 10 17:30:57 2008 -0700 @@ -0,0 +1,43 @@ +// +// BoardUIView.h +// GeekGameBoard +// +// Created by Jens Alfke on 3/7/08. +// Copyright 2008 __MyCompanyName__. All rights reserved. +// + +#import +@class GGBLayer, Bit, Card, Grid, Game; +@protocol BitHolder; + + +/** NSView that hosts a game. */ +@interface BoardUIView : UIView +{ + @private + Game *_game; // Current Game + GGBLayer *_gameboard; // Game's main layer + + // Used during mouse-down tracking: + CGPoint _dragStartPos; // Starting position of mouseDown + Bit *_dragBit; // Bit being dragged + id _oldHolder; // Bit's original holder + CALayer *_oldSuperlayer; // Bit's original superlayer + int _oldLayerIndex; // Bit's original index in _oldSuperlayer.layers + CGPoint _oldPos; // Bit's original x/y position + CGPoint _dragOffset; // Offset of mouse position from _dragBit's origin + BOOL _dragMoved; // Has the mouse moved more than 3 pixels since mouseDown? + id _dropTarget; // Current BitHolder the cursor is over + + // Used while handling incoming drags: + GGBLayer *_viewDropTarget; // Current drop target during an incoming drag-n-drop +} + +- (void) startGameNamed: (NSString*)gameClassName; + +@property (readonly) Game *game; +@property (readonly) GGBLayer *gameboard; + +- (CGRect) gameBoardFrame; + +@end diff -r e9f7ba4718e1 -r 3eb7be1dd7b6 Source/BoardUIView.m --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/BoardUIView.m Mon Mar 10 17:30:57 2008 -0700 @@ -0,0 +1,222 @@ +// +// BoardUIView.m +// GeekGameBoard +// +// Created by Jens Alfke on 3/7/08. +// Copyright 2008 __MyCompanyName__. All rights reserved. +// + +#import "BoardUIView.h" +#import "Bit.h" +#import "BitHolder.h" +#import "Game.h" +#import "QuartzUtils.h" +#import "GGBUtils.h" + + +@implementation BoardUIView + + +- (id)initWithFrame:(CGRect)frame { + if ( (self = [super initWithFrame:frame]) ) { + // Initialization code here. + } + return self; +} + + +- (void)dealloc +{ + [_game release]; + [super dealloc]; +} + + +@synthesize game=_game, gameboard=_gameboard; + + +- (void) startGameNamed: (NSString*)gameClassName +{ + if( _gameboard ) { + [_gameboard removeFromSuperlayer]; + _gameboard = nil; + } + _gameboard = [[GGBLayer alloc] init]; + _gameboard.frame = [self gameBoardFrame]; + _gameboard.autoresizingMask = kCALayerWidthSizable | kCALayerHeightSizable; + [self.layer addSublayer: _gameboard]; + [_gameboard release]; + + Class gameClass = NSClassFromString(gameClassName); + NSAssert1(gameClass,@"Unknown game '%@'",gameClassName); + setObj(&_game, [[gameClass alloc] initWithBoard: _gameboard]); +} + + +- (CGRect) gameBoardFrame +{ + return self.layer.bounds; +} + + +#pragma mark - +#pragma mark HIT-TESTING: + + +// Hit-testing callbacks (to identify which layers caller is interested in): +typedef BOOL (*LayerMatchCallback)(CALayer*); + +static BOOL layerIsBit( CALayer* layer ) {return [layer isKindOfClass: [Bit class]];} +static BOOL layerIsBitHolder( CALayer* layer ) {return [layer conformsToProtocol: @protocol(BitHolder)];} + + +/** Locates the layer at a given point in window coords. + If the leaf layer doesn't pass the layer-match callback, the nearest ancestor that does is returned. + If outOffset is provided, the point's position relative to the layer is stored into it. */ +- (CALayer*) hitTestPoint: (CGPoint)where + forLayerMatching: (LayerMatchCallback)match + offset: (CGPoint*)outOffset +{ + where = [_gameboard convertPoint: where fromLayer: self.layer]; + CALayer *layer = [_gameboard hitTest: where]; + while( layer ) { + if( match(layer) ) { + CGPoint bitPos = [self.layer convertPoint: layer.position + fromLayer: layer.superlayer]; + if( outOffset ) + *outOffset = CGPointMake( bitPos.x-where.x, bitPos.y-where.y); + return layer; + } else + layer = layer.superlayer; + } + return nil; +} + + +#pragma mark - +#pragma mark MOUSE CLICKS & DRAGS: + + +- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event +{ + NSAssert(touches.count==1,@"No multitouch support yet"); + UITouch *touch = touches.anyObject; + + _dragStartPos = touch.locationInView; + _dragBit = (Bit*) [self hitTestPoint: _dragStartPos + forLayerMatching: layerIsBit + offset: &_dragOffset]; + if( _dragBit ) { + _dragMoved = NO; + _dropTarget = nil; + _oldHolder = _dragBit.holder; + // Ask holder's and game's permission before dragging: + if( _oldHolder ) + _dragBit = [_oldHolder canDragBit: _dragBit]; + if( _dragBit && ! [_game canBit: _dragBit moveFrom: _oldHolder] ) { + [_oldHolder cancelDragBit: _dragBit]; + _dragBit = nil; + } + if( ! _dragBit ) { + _oldHolder = nil; + Beep(); + return; + } + // Start dragging: + _oldSuperlayer = _dragBit.superlayer; + _oldLayerIndex = [_oldSuperlayer.sublayers indexOfObjectIdenticalTo: _dragBit]; + _oldPos = _dragBit.position; + ChangeSuperlayer(_dragBit, self.layer, self.layer.sublayers.count); + _dragBit.pickedUp = YES; + } else + Beep(); +} + + +- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event +{ + NSAssert(touches.count==1,@"No multitouch support yet"); + UITouch *touch = touches.anyObject; + + if( _dragBit ) { + // Get the mouse position, and see if we've moved 3 pixels since the mouseDown: + CGPoint pos = touch.locationInView; + if( fabs(pos.x-_dragStartPos.x)>=3 || fabs(pos.y-_dragStartPos.y)>=3 ) + _dragMoved = YES; + + // Move the _dragBit (without animation -- it's unnecessary and slows down responsiveness): + pos.x += _dragOffset.x; + pos.y += _dragOffset.y; + + CGPoint newPos = [_dragBit.superlayer convertPoint: pos fromLayer: self.layer]; + + [CATransaction flush]; + [CATransaction begin]; + [CATransaction setValue:(id)kCFBooleanTrue + forKey:kCATransactionDisableActions]; + _dragBit.position = newPos; + [CATransaction commit]; + + // Find what it's over: + id target = (id) [self hitTestPoint: pos + forLayerMatching: layerIsBitHolder + offset: NULL]; + if( target == _oldHolder ) + target = nil; + if( target != _dropTarget ) { + [_dropTarget willNotDropBit: _dragBit]; + _dropTarget.highlighted = NO; + _dropTarget = nil; + } + if( target ) { + CGPoint targetPos = [(CALayer*)target convertPoint: _dragBit.position + fromLayer: _dragBit.superlayer]; + if( [target canDropBit: _dragBit atPoint: targetPos] + && [_game canBit: _dragBit moveFrom: _oldHolder to: target] ) { + _dropTarget = target; + _dropTarget.highlighted = YES; + } + } + } +} + + +- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event +{ + if( _dragBit ) { + if( _dragMoved ) { + // Update the drag tracking to the final mouse position: + [self touchesMoved: touches withEvent: event]; + _dropTarget.highlighted = NO; + _dragBit.pickedUp = NO; + + // Is the move legal? + if( _dropTarget && [_dropTarget dropBit: _dragBit + atPoint: [(CALayer*)_dropTarget convertPoint: _dragBit.position + fromLayer: _dragBit.superlayer]] ) { + // Yes, notify the interested parties: + [_oldHolder draggedBit: _dragBit to: _dropTarget]; + [_game bit: _dragBit movedFrom: _oldHolder to: _dropTarget]; + } else { + // Nope, cancel: + [_dropTarget willNotDropBit: _dragBit]; + ChangeSuperlayer(_dragBit, _oldSuperlayer, _oldLayerIndex); + _dragBit.position = _oldPos; + [_oldHolder cancelDragBit: _dragBit]; + } + } else { + // Just a click, without a drag: + _dropTarget.highlighted = NO; + _dragBit.pickedUp = NO; + ChangeSuperlayer(_dragBit, _oldSuperlayer, _oldLayerIndex); + [_oldHolder cancelDragBit: _dragBit]; + if( ! [_game clickedBit: _dragBit] ) + Beep(); + } + _dropTarget = nil; + _dragBit = nil; + } +} + + +@end diff -r e9f7ba4718e1 -r 3eb7be1dd7b6 Source/BoardView.h --- a/Source/BoardView.h Fri Mar 07 11:43:02 2008 -0800 +++ b/Source/BoardView.h Mon Mar 10 17:30:57 2008 -0700 @@ -21,7 +21,7 @@ THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #import -@class Bit, Card, Grid, Game; +@class GGBLayer, Bit, Card, Grid, Game; @protocol BitHolder; @@ -30,7 +30,7 @@ { @private Game *_game; // Current Game - CALayer *_gameboard; // Game's main layer + GGBLayer *_gameboard; // Game's main layer // Used during mouse-down tracking: NSPoint _dragStartPos; // Starting position of mouseDown diff -r e9f7ba4718e1 -r 3eb7be1dd7b6 Source/Card.h --- a/Source/Card.h Fri Mar 07 11:43:02 2008 -0800 +++ b/Source/Card.h Mon Mar 10 17:30:57 2008 -0700 @@ -35,7 +35,7 @@ { @private int _serialNumber; - CALayer *_front, *_back; + GGBLayer *_front, *_back; BOOL _faceUp; } @@ -56,11 +56,11 @@ /** Creates the sub-layer that displays the front side of the card. Subclasses should probably call the superclass method, configure the layer it returns (based on the card's serialNumber) and then return that layer. */ -- (CALayer*) createFront; +- (GGBLayer*) createFront; /** Creates the sub-layer that displays the back side of the card. Subclasses should probably call the superclass method, configure the layer it returns and return that layer. */ -- (CALayer*) createBack; +- (GGBLayer*) createBack; @end diff -r e9f7ba4718e1 -r 3eb7be1dd7b6 Source/Card.m --- a/Source/Card.m Fri Mar 07 11:43:02 2008 -0800 +++ b/Source/Card.m Mon Mar 10 17:30:57 2008 -0700 @@ -21,6 +21,7 @@ THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #import "Card.h" +#import "GGBTextLayer.h" #import "QuartzUtils.h" @@ -68,19 +69,11 @@ } -- (void)encodeWithCoder:(NSCoder *)aCoder +- (id) copyWithZone: (NSZone*)zone { - [super encodeWithCoder: aCoder]; - [aCoder encodeInt: _serialNumber forKey: @"serialNumber"]; -} - -- (id)initWithCoder:(NSCoder *)aDecoder -{ - self = [super initWithCoder: aDecoder]; - if( self ) { - _serialNumber = [aDecoder decodeIntForKey: @"serialNumber"]; - } - return self; + Card *clone = [super copyWithZone: zone]; + clone->_serialNumber = _serialNumber; + return clone; } @@ -115,25 +108,25 @@ } -- (CALayer*) createFront +- (GGBLayer*) createFront { - CALayer *front = [[CALayer alloc] init]; + GGBLayer *front = [[GGBLayer alloc] init]; front.bounds = CGRectMake(0,0,kCardWidth,kCardHeight); front.position = CGPointMake(kCardWidth/2,kCardHeight/2); front.edgeAntialiasingMask = 0; front.backgroundColor = kWhiteColor; front.cornerRadius = 8; front.borderWidth = 1; - front.borderColor = CGColorCreateGenericGray(0.7, 1.0); + front.borderColor = CreateGray(0.7, 1.0); front.doubleSided = NO; // this makes the layer invisible when it's flipped return [front autorelease]; } -- (CALayer*) createBack +- (GGBLayer*) createBack { CGSize size = self.bounds.size; - CALayer *back = [[CALayer alloc] init]; + GGBLayer *back = [[GGBLayer alloc] init]; back.bounds = CGRectMake(0,0,size.width,size.height); back.position = CGPointMake(kCardWidth/2,kCardHeight/2); back.contents = (id) GetCGImageNamed(@"/Library/Desktop Pictures/Classic Aqua Blue.jpg"); @@ -145,10 +138,11 @@ back.edgeAntialiasingMask = 0; back.doubleSided = NO; // this makes the layer invisible when it's flipped - CATextLayer *label = AddTextLayer(back, @"\u2603", // Unicode snowman character - [NSFont systemFontOfSize: 0.9*size.width], - kCALayerWidthSizable|kCALayerHeightSizable); - label.foregroundColor = CGColorCreateGenericGray(1.0,0.5); + GGBTextLayer *label = [GGBTextLayer textLayerInSuperlayer: back + withText: @"\u2603" // Unicode snowman character + fontSize: 0.9*size.width + alignment: kCALayerWidthSizable|kCALayerHeightSizable]; + label.foregroundColor = CreateGray(1.0,0.5); return [back autorelease]; } @@ -157,6 +151,8 @@ #pragma mark DRAG-AND-DROP: +#if ! TARGET_OS_ASPEN + // An image from another app can be dragged onto a Card to change its background. */ @@ -173,7 +169,7 @@ { CGImageRef image = GetCGImageFromPasteboard([sender draggingPasteboard]); if( image ) { - CALayer *face = _faceUp ?_front :_back; + GGBLayer *face = _faceUp ?_front :_back; face.contents = (id) image; face.contentsGravity = kCAGravityResizeAspectFill; face.masksToBounds = YES; @@ -182,5 +178,6 @@ return NO; } +#endif @end diff -r e9f7ba4718e1 -r 3eb7be1dd7b6 Source/CheckersGame.m --- a/Source/CheckersGame.m Fri Mar 07 11:43:02 2008 -0800 +++ b/Source/CheckersGame.m Mon Mar 10 17:30:57 2008 -0700 @@ -24,6 +24,7 @@ #import "Grid.h" #import "Piece.h" #import "QuartzUtils.h" +#import "GGBUtils.h" @implementation CheckersGame @@ -64,8 +65,8 @@ grid.position = pos; grid.allowsMoves = YES; grid.allowsCaptures = NO; - grid.cellColor = CGColorCreateGenericGray(0.0, 0.25); - grid.altCellColor = CGColorCreateGenericGray(1.0, 0.25); + grid.cellColor = CreateGray(0.0, 0.25); + grid.altCellColor = CreateGray(1.0, 0.25); grid.lineColor = nil; [self addPieces: @"Green Ball.png" toGrid: grid forPlayer: 0 rows: NSMakeRange(0,3) alternating: YES]; [self addPieces: @"Red Ball.png" toGrid: grid forPlayer: 1 rows: NSMakeRange(5,3) alternating: YES]; @@ -73,7 +74,7 @@ } -- (id) initWithBoard: (CALayer*)board +- (id) initWithBoard: (GGBLayer*)board { self = [super initWithBoard: board]; if (self != nil) { @@ -102,12 +103,12 @@ int playerIndex = self.currentPlayer.index; BOOL isKing = ([bit valueForKey: @"King"] != nil); - [[NSSound soundNamed: (isKing ?@"Funk" :@"Tink")] play]; + PlaySound(isKing ?@"Funk" :@"Tink"); // "King" a piece that made it to the last row: if( dst.row == (playerIndex ?0 :7) ) if( ! isKing ) { - [[NSSound soundNamed: @"Blow"] play]; + PlaySound(@"Blow"); bit.scale = 1.4; [bit setValue: @"King" forKey: @"King"]; // don't set isKing flag - piece can't jump again after being kinged. @@ -125,7 +126,7 @@ capture = src.br; if( capture ) { - [[NSSound soundNamed: @"Pop"] play]; + PlaySound(@"Pop"); Bit *bit = capture.bit; _numPieces[bit.owner.index]--; [bit destroy]; diff -r e9f7ba4718e1 -r 3eb7be1dd7b6 Source/DemoBoardView.m --- a/Source/DemoBoardView.m Fri Mar 07 11:43:02 2008 -0800 +++ b/Source/DemoBoardView.m Mon Mar 10 17:30:57 2008 -0700 @@ -22,6 +22,7 @@ */ #import "DemoBoardView.h" #import "Game.h" +#import "GGBTextLayer.h" #import "QuartzUtils.h" @@ -79,12 +80,13 @@ [self registerForDraggedTypes: [NSArray arrayWithObject: NSFilenamesPboardType]]; CGRect bounds = self.layer.bounds; - self.layer.backgroundColor = GetCGPatternNamed(@"/Library/Desktop Pictures/Small Ripples graphite.png"); + self.layer.backgroundColor = GetCGPatternNamed(@"Background.png"); bounds.size.height -= 32; - _headline = AddTextLayer(self.layer, - nil, [NSFont boldSystemFontOfSize: 24], - kCALayerWidthSizable | kCALayerMinYMargin); + _headline = [GGBTextLayer textLayerInSuperlayer: self.layer + withText: nil + fontSize: 24 + alignment: kCALayerWidthSizable | kCALayerMinYMargin]; [self startGameNamed: sCurrentGameName]; } diff -r e9f7ba4718e1 -r 3eb7be1dd7b6 Source/Dispenser.m --- a/Source/Dispenser.m Fri Mar 07 11:43:02 2008 -0800 +++ b/Source/Dispenser.m Mon Mar 10 17:30:57 2008 -0700 @@ -163,6 +163,8 @@ #pragma mark DRAG-AND-DROP: +#if ! TARGET_OS_ASPEN + // An image from another app can be dragged onto a Dispenser to change the Piece's appearance. @@ -191,4 +193,6 @@ } +#endif + @end diff -r e9f7ba4718e1 -r 3eb7be1dd7b6 Source/GGB-iPhone_Prefix.pch --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/GGB-iPhone_Prefix.pch Mon Mar 10 17:30:57 2008 -0700 @@ -0,0 +1,9 @@ +// +// Prefix header for all source files of the 'GGB-iPhone' target in the 'GGB-iPhone' project +// + +#ifdef __OBJC__ + #import + #import + #import +#endif diff -r e9f7ba4718e1 -r 3eb7be1dd7b6 Source/GGBLayer.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/GGBLayer.h Mon Mar 10 17:30:57 2008 -0700 @@ -0,0 +1,46 @@ +// +// GGBLayer.h +// GGB-iPhone +// +// Created by Jens Alfke on 3/7/08. +// Copyright 2008 __MyCompanyName__. All rights reserved. +// + +#if TARGET_OS_ASPEN +#import +#else +#import +#endif + + +@interface GGBLayer : CALayer + +#if TARGET_OS_ASPEN +// For some reason, the CALayer class on iPhone OS doesn't have these! +{ + CGFloat _cornerRadius, _borderWidth; + CGColorRef _borderColor, _realBGColor; + unsigned int _autoresizingMask; +} +@property CGFloat cornerRadius, borderWidth; +@property CGColorRef borderColor; +@property unsigned int autoresizingMask; +#endif + +@end + + +#if TARGET_OS_ASPEN +/* Bit definitions for `autoresizingMask' property. */ + +enum CAAutoresizingMask +{ + kCALayerNotSizable = 0, + kCALayerMinXMargin = 1U << 0, + kCALayerWidthSizable = 1U << 1, + kCALayerMaxXMargin = 1U << 2, + kCALayerMinYMargin = 1U << 3, + kCALayerHeightSizable = 1U << 4, + kCALayerMaxYMargin = 1U << 5 +}; +#endif diff -r e9f7ba4718e1 -r 3eb7be1dd7b6 Source/GGBLayer.m --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/GGBLayer.m Mon Mar 10 17:30:57 2008 -0700 @@ -0,0 +1,191 @@ +// +// GGBLayer.m +// GGB-iPhone +// +// Created by Jens Alfke on 3/7/08. +// Copyright 2008 __MyCompanyName__. All rights reserved. +// + +#import "GGBLayer.h" +#import "QuartzUtils.h" + + +@implementation GGBLayer + + +- (NSString*) description +{ + return [NSString stringWithFormat: @"%@[(%g,%g)]", self.class,self.position.x,self.position.y]; +} + + +#if TARGET_OS_ASPEN + +#pragma mark - +#pragma mark IPHONE VERSION: + + +- (id) copyWithZone: (NSZone*)zone +{ + GGBLayer *clone = [[[self class] alloc] init]; + clone.bounds = self.bounds; + clone.position = self.position; + clone.zPosition = self.zPosition; + clone.anchorPoint = self.anchorPoint; + clone.transform = self.transform; + clone.hidden = self.hidden; + clone.doubleSided = self.doubleSided; + clone.sublayerTransform = self.sublayerTransform; + clone.masksToBounds = self.masksToBounds; + clone.contents = self.contents; // doesn't copy contents (shallow-copy) + clone.contentsRect = self.contentsRect; + clone.contentsGravity = self.contentsGravity; + clone.minificationFilter = self.minificationFilter; + clone.magnificationFilter = self.magnificationFilter; + clone.opaque = self.opaque; + clone.needsDisplayOnBoundsChange = self.needsDisplayOnBoundsChange; + clone.edgeAntialiasingMask = self.edgeAntialiasingMask; + clone.backgroundColor = self.backgroundColor; + clone.opacity = self.opacity; + clone.compositingFilter = self.compositingFilter; + clone.filters = self.filters; + clone.backgroundFilters = self.backgroundFilters; + clone.actions = self.actions; + clone.name = self.name; + clone.style = self.style; + + clone.cornerRadius = self.cornerRadius; + clone.borderWidth = self.borderWidth; + clone.borderColor = self.borderColor; + clone.autoresizingMask = self.autoresizingMask; + + for( GGBLayer *sublayer in self.sublayers ) { + sublayer = [sublayer copyWithZone: zone]; + [clone addSublayer: sublayer]; + } + return clone; +} + + +@synthesize autoresizingMask=_autoresizingMask; + +- (CGFloat) cornerRadius {return _cornerRadius;} +- (CGFloat) borderWidth {return _borderWidth;} +- (CGColorRef) borderColor {return _borderColor;} + +- (void) setCornerRadius: (CGFloat)r +{ + if( r != _cornerRadius ) { + _cornerRadius = r; + [self setNeedsDisplay]; + } +} + + +- (void) setBorderWidth: (CGFloat)w +{ + if( w != _borderWidth ) { + _borderWidth = w; + self.needsDisplayOnBoundsChange = (_borderWidth>0.0 && _borderColor!=NULL); + [self setNeedsDisplay]; + } +} + + +- (void) setBackgroundColor: (CGColorRef)color +{ + if( color != _realBGColor ) { + CGColorRelease(_realBGColor); + _realBGColor = CGColorRetain(color); + [self setNeedsDisplay]; + } +} + + +- (void) setBorderColor: (CGColorRef)color +{ + if( color != _borderColor ) { + CGColorRelease(_borderColor); + _borderColor = CGColorRetain(color); + self.needsDisplayOnBoundsChange = (_borderWidth>0.0 && _borderColor!=NULL); + [self setNeedsDisplay]; + } +} + + +- (void)drawInContext:(CGContextRef)ctx +{ + CGContextSaveGState(ctx); + + if( _realBGColor ) { + CGRect interior = CGRectInset(self.bounds, _borderWidth,_borderWidth); + CGContextSetFillColorWithColor(ctx, _realBGColor); + if( _cornerRadius <= 0.0 ) { + CGContextFillRect(ctx,interior); + } else { + CGContextBeginPath(ctx); + AddRoundRect(ctx,interior,_cornerRadius); + CGContextFillPath(ctx); + } + } + + if( _borderWidth > 0.0 && _borderColor!=NULL ) { + CGRect border = CGRectInset(self.bounds, _borderWidth/2.0, _borderWidth/2.0); + CGContextSetStrokeColorWithColor(ctx, _borderColor); + CGContextSetLineWidth(ctx, _borderWidth); + + if( _cornerRadius <= 0.0 ) { + CGContextStrokeRect(ctx,border); + } else { + CGContextBeginPath(ctx); + AddRoundRect(ctx,border,_cornerRadius); + CGContextStrokePath(ctx); + } + } + + CGContextRestoreGState(ctx); +} + + +#else + +#pragma mark - +#pragma mark MAC OS VERSION: + + +- (id) copyWithZone: (NSZone*)zone +{ + // NSLayer isn't copyable, but it is archivable. So create a copy by archiving to + // a temporary data block, then unarchiving a new layer from that block. + + // One complication is that, due to a bug in Core Animation, CALayer can't archive + // a pattern-based CGColor. So as a workaround, clear the background before archiving, + // then restore it afterwards. + + // Also, archiving a CALayer with an image in it leaks memory. (Filed as rdar://5786865 ) + // As a workaround, clear the contents before archiving, then restore. + + CGColorRef bg = CGColorRetain(self.backgroundColor); + self.backgroundColor = NULL; + id contents = [self.contents retain]; + self.contents = nil; + + NSData *data = [NSKeyedArchiver archivedDataWithRootObject: self]; + + self.backgroundColor = bg; + self.contents = contents; + + GGBLayer *clone = [NSKeyedUnarchiver unarchiveObjectWithData: data]; + clone.backgroundColor = bg; + clone.contents = contents; + CGColorRelease(bg); + [contents release]; + + return [clone retain]; +} + + +#endif + + +@end diff -r e9f7ba4718e1 -r 3eb7be1dd7b6 Source/GGBTextLayer.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/GGBTextLayer.h Mon Mar 10 17:30:57 2008 -0700 @@ -0,0 +1,37 @@ +// +// GGBTextLayer.h +// GGB-iPhone +// +// Created by Jens Alfke on 3/10/08. +// Copyright 2008 __MyCompanyName__. All rights reserved. +// + +#import "GGBLayer.h" + + +#if TARGET_OS_ASPEN +@interface GGBTextLayer : GGBLayer +{ + NSString *_string; + CGFloat _fontSize; + CGColorRef _foregroundColor; + NSString *_alignmentMode; +} + +@property(copy) id string; +@property CGFloat fontSize; +@property CGColorRef foregroundColor; +@property (copy) NSString *alignmentMode; + +#else +@interface GGBTextLayer : CATextLayer +#endif + ++ (GGBTextLayer*) textLayerInSuperlayer: (CALayer*)superlayer + withText: (NSString*)text + fontSize: (float) fontSize + alignment: (enum CAAutoresizingMask) align; + +@end + + diff -r e9f7ba4718e1 -r 3eb7be1dd7b6 Source/GGBTextLayer.m --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/GGBTextLayer.m Mon Mar 10 17:30:57 2008 -0700 @@ -0,0 +1,73 @@ +// +// GGBTextLayer.m +// GGB-iPhone +// +// Created by Jens Alfke on 3/10/08. +// Copyright 2008 __MyCompanyName__. All rights reserved. +// + +#import "GGBTextLayer.h" +#import "QuartzUtils.h" + + +@implementation GGBTextLayer + + ++ (GGBTextLayer*) textLayerInSuperlayer: (CALayer*)superlayer + withText: (NSString*)text + fontSize: (float) fontSize + alignment: (enum CAAutoresizingMask) align +{ + GGBTextLayer *label = [[self alloc] init]; + label.string = text; + +#if TARGET_OS_ASPEN + UIFont *font = [UIFont systemFontOfSize: fontSize]; +#else + NSFont *font = [NSFont systemFontOfSize: fontSize]; + label.font = font; +#endif + + label.fontSize = fontSize; + label.foregroundColor = kBlackColor; + + NSString *mode; + if( align & kCALayerWidthSizable ) + mode = @"center"; + else if( align & kCALayerMinXMargin ) + mode = @"right"; + else + mode = @"left"; + align |= kCALayerWidthSizable; + label.alignmentMode = mode; + + CGFloat inset = 3; + if( [superlayer respondsToSelector: @selector(borderWidth)] ) + inset += ((GGBLayer*)superlayer).borderWidth; + CGRect bounds = CGRectInset(superlayer.bounds, inset, inset); + CGFloat height = font.ascender; + CGFloat y = bounds.origin.y; + if( align & kCALayerHeightSizable ) + y += (bounds.size.height-height)/2.0; + else if( align & kCALayerMinYMargin ) + y += bounds.size.height - height; + align &= ~kCALayerHeightSizable; + label.bounds = CGRectMake(0, font.descender, + bounds.size.width, height - font.descender); + label.position = CGPointMake(bounds.origin.x,y+font.descender); + label.anchorPoint = CGPointMake(0,0); + + label.autoresizingMask = align; + [superlayer addSublayer: label]; + [label release]; + return label; +} + + +#if TARGET_OS_ASPEN +@synthesize string=_string, fontSize=_fontSize, + foregroundColor=_foregroundColor, alignmentMode=_alignmentMode; +#endif + + +@end diff -r e9f7ba4718e1 -r 3eb7be1dd7b6 Source/GGBUtils.h --- a/Source/GGBUtils.h Fri Mar 07 11:43:02 2008 -0800 +++ b/Source/GGBUtils.h Mon Mar 10 17:30:57 2008 -0700 @@ -18,7 +18,7 @@ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#import + /** Handy utility for assigning a new value to a retained instance variable. Use as: setObj(&_instanceVar, newValue); @@ -26,6 +26,9 @@ void setObj( id *variable, id newValue ); - /** Just like setObj except that it _copies_ the new value. */ void setObjCopy( id *variable, id newValue ); + + +void PlaySound( NSString* name ); +void Beep( void ); \ No newline at end of file diff -r e9f7ba4718e1 -r 3eb7be1dd7b6 Source/GGBUtils.m --- a/Source/GGBUtils.m Fri Mar 07 11:43:02 2008 -0800 +++ b/Source/GGBUtils.m Mon Mar 10 17:30:57 2008 -0700 @@ -20,6 +20,10 @@ */ #import "GGBUtils.h" +#if TARGET_OS_ASPEN +#import +#endif + void setObj( id *variable, id newValue ) { @@ -36,3 +40,28 @@ *variable = [(id)newValue copy]; } } + + +void PlaySound( NSString* name ) +{ +#if TARGET_OS_ASPEN + 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); +#else + [[NSSound soundNamed: name] play]; +#endif +} + +void Beep() +{ +#if TARGET_OS_ASPEN + AudioServicesPlaySystemSound(kSystemSoundID_UserPreferredAlert); +#else + NSBeep(); +#endif +} diff -r e9f7ba4718e1 -r 3eb7be1dd7b6 Source/Game.h --- a/Source/Game.h Fri Mar 07 11:43:02 2008 -0800 +++ b/Source/Game.h Mon Mar 10 17:30:57 2008 -0700 @@ -20,15 +20,14 @@ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#import -@class Bit, Player; +@class GGBLayer, Bit, Player; @protocol BitHolder; /** Abstract superclass. Keeps track of the rules and turns of a game. */ @interface Game : NSObject { - CALayer *_board; + GGBLayer *_board; NSArray *_players; Player *_currentPlayer, *_winner; } @@ -45,7 +44,7 @@ /** Designated initializer. After calling the superclass implementation, it should add the necessary Grids, Pieces, Cards, Decks etc. to the board. */ -- (id) initWithBoard: (CALayer*)board; +- (id) initWithBoard: (GGBLayer*)board; /** Should return YES if it is legal for the given bit to be moved from its current holder. Default implementation always returns YES. */ diff -r e9f7ba4718e1 -r 3eb7be1dd7b6 Source/Game.m --- a/Source/Game.m Fri Mar 07 11:43:02 2008 -0800 +++ b/Source/Game.m Mon Mar 10 17:30:57 2008 -0700 @@ -51,7 +51,7 @@ } -- (id) initWithBoard: (CALayer*)board +- (id) initWithBoard: (GGBLayer*)board { self = [super init]; if (self != nil) { diff -r e9f7ba4718e1 -r 3eb7be1dd7b6 Source/GoGame.m --- a/Source/GoGame.m Fri Mar 07 11:43:02 2008 -0800 +++ b/Source/GoGame.m Mon Mar 10 17:30:57 2008 -0700 @@ -26,6 +26,7 @@ #import "Dispenser.h" #import "Stack.h" #import "QuartzUtils.h" +#import "GGBUtils.h" @implementation GoGame @@ -44,7 +45,7 @@ } -- (id) initWithBoard: (CALayer*)board +- (id) initWithBoard: (GGBLayer*)board { self = [super initWithBoard: board]; if (self != nil) { @@ -153,7 +154,7 @@ } } if( captured ) - [[NSSound soundNamed: @"Pop"] play]; + PlaySound(@"Pop"); [self nextPlayer]; } diff -r e9f7ba4718e1 -r 3eb7be1dd7b6 Source/Grid.h --- a/Source/Grid.h Fri Mar 07 11:43:02 2008 -0800 +++ b/Source/Grid.h Mon Mar 10 17:30:57 2008 -0700 @@ -25,7 +25,7 @@ /** Abstract superclass of regular geometric grids of GridCells that Bits can be placed on. */ -@interface Grid : CALayer +@interface Grid : GGBLayer { unsigned _nRows, _nColumns; CGSize _spacing; diff -r e9f7ba4718e1 -r 3eb7be1dd7b6 Source/Grid.m --- a/Source/Grid.m Fri Mar 07 11:43:02 2008 -0800 +++ b/Source/Grid.m Mon Mar 10 17:30:57 2008 -0700 @@ -40,7 +40,7 @@ _nColumns = nColumns; _spacing = spacing; _cellClass = [GridCell class]; - _lineColor = kBlackColor; + self.lineColor = kBlackColor; _allowsMoves = YES; _usesDiagonals = YES; @@ -328,6 +328,8 @@ #pragma mark DRAG-AND-DROP: +#if ! TARGET_OS_ASPEN + // An image from another app can be dragged onto a Dispenser to change the Piece's appearance. @@ -353,6 +355,7 @@ return NO; } +#endif @end @@ -430,6 +433,8 @@ - (Square*) l {return self.fwdIsN ?self.w :self.e;} +#if ! TARGET_OS_ASPEN + - (BOOL)performDragOperation:(id )sender { CGImageRef image = GetCGImageFromPasteboard([sender draggingPasteboard]); @@ -447,6 +452,8 @@ return NO; } +#endif + @end @@ -483,4 +490,5 @@ } } + @end diff -r e9f7ba4718e1 -r 3eb7be1dd7b6 Source/HexchequerGame.m --- a/Source/HexchequerGame.m Fri Mar 07 11:43:02 2008 -0800 +++ b/Source/HexchequerGame.m Mon Mar 10 17:30:57 2008 -0700 @@ -24,6 +24,7 @@ #import "HexGrid.h" #import "Piece.h" #import "QuartzUtils.h" +#import "GGBUtils.h" @implementation HexchequerGame @@ -38,7 +39,7 @@ [grid addCellsInHexagon]; grid.allowsMoves = YES; grid.allowsCaptures = NO; // no land-on captures, that is - grid.cellColor = CGColorCreateGenericGray(1.0, 0.25); + grid.cellColor = CreateGray(1.0, 0.25); grid.lineColor = kTranslucentLightGrayColor; [self addPieces: @"Green Ball.png" toGrid: grid forPlayer: 0 rows: NSMakeRange(0,2) alternating: NO]; @@ -65,12 +66,12 @@ int playerIndex = self.currentPlayer.index; BOOL isKing = ([bit valueForKey: @"King"] != nil); - [[NSSound soundNamed: (isKing ?@"Funk" :@"Tink")] play]; + PlaySound(isKing ?@"Funk" :@"Tink"); // "King" a piece that made it to the last row: if( dst.row == (playerIndex ?0 :8) ) if( ! isKing ) { - [[NSSound soundNamed: @"Blow"] play]; + PlaySound(@"Blow"); bit.scale = 1.4; [bit setValue: @"King" forKey: @"King"]; // don't set isKing flag - piece can't capture again after being kinged. @@ -92,7 +93,7 @@ capture = src.r; if( capture ) { - [[NSSound soundNamed: @"Pop"] play]; + PlaySound(@"Pop"); Bit *bit = capture.bit; _numPieces[bit.owner.index]--; [bit destroy]; diff -r e9f7ba4718e1 -r 3eb7be1dd7b6 Source/KlondikeGame.m --- a/Source/KlondikeGame.m Fri Mar 07 11:43:02 2008 -0800 +++ b/Source/KlondikeGame.m Mon Mar 10 17:30:57 2008 -0700 @@ -41,7 +41,7 @@ @implementation KlondikeGame -- (id) initWithBoard: (CALayer*)board +- (id) initWithBoard: (GGBLayer*)board { self = [super initWithBoard: board]; if (self != nil) { diff -r e9f7ba4718e1 -r 3eb7be1dd7b6 Source/Piece.m --- a/Source/Piece.m Fri Mar 07 11:43:02 2008 -0800 +++ b/Source/Piece.m Mon Mar 10 17:30:57 2008 -0700 @@ -40,20 +40,11 @@ } -- (id) initWithCoder: (NSCoder*)decoder +- (id) copyWithZone: (NSZone*)zone { - self = [super initWithCoder: decoder]; - if( self ) { - self.imageName = [decoder decodeObjectForKey: @"imageName"]; - // (actual image (self.contents) was already restord by superclass) - } - return self; -} - -- (void) encodeWithCoder: (NSCoder*)coder -{ - [super encodeWithCoder: coder]; - [coder encodeObject: _imageName forKey: @"imageName"]; + Piece *clone = [super copyWithZone: zone]; + clone.imageName = self.imageName; + return clone; } diff -r e9f7ba4718e1 -r 3eb7be1dd7b6 Source/PlayingCard.m --- a/Source/PlayingCard.m Fri Mar 07 11:43:02 2008 -0800 +++ b/Source/PlayingCard.m Mon Mar 10 17:30:57 2008 -0700 @@ -21,6 +21,7 @@ THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #import "PlayingCard.h" +#import "GGBTextLayer.h" #import "QuartzUtils.h" @@ -33,25 +34,31 @@ } -- (CALayer*) createFront +- (GGBLayer*) createFront { - CALayer *front = [super createFront]; + GGBLayer *front = [super createFront]; NSString *name = [NSString stringWithFormat: @"%@%@", self.rankString, self.suitString]; CGColorRef suitColor = self.suitColor; - CATextLayer *label; - label = AddTextLayer(front, name, [NSFont systemFontOfSize: 18], - kCALayerMaxXMargin | kCALayerMinYMargin); + GGBTextLayer *label; + label = [GGBTextLayer textLayerInSuperlayer: front + withText: name + fontSize: 18.0 + alignment: kCALayerMaxXMargin | kCALayerMinYMargin]; label.foregroundColor = suitColor; - label = AddTextLayer(front, name, [NSFont systemFontOfSize: 18], - kCALayerMaxXMargin | kCALayerMaxYMargin); + label = [GGBTextLayer textLayerInSuperlayer: front + withText: name + fontSize: 18.0 + alignment: kCALayerMaxXMargin | kCALayerMaxYMargin]; label.foregroundColor = suitColor; label.anchorPoint = CGPointMake(1,1); [label setValue: [NSNumber numberWithFloat: M_PI] forKeyPath: @"transform.rotation"]; - label = AddTextLayer(front, self.faceSymbol, [NSFont systemFontOfSize: 80], - kCALayerWidthSizable | kCALayerHeightSizable); + label = [GGBTextLayer textLayerInSuperlayer: front + withText: self.faceSymbol + fontSize: 80 + alignment: kCALayerWidthSizable | kCALayerHeightSizable]; label.foregroundColor = suitColor; return front; } @@ -86,7 +93,7 @@ static CGColorRef kSuitColor[4]; if( ! kSuitColor[0] ) { kSuitColor[0] = kSuitColor[3] = kBlackColor; - kSuitColor[1] = kSuitColor[2] = CGColorCreateGenericRGB(1, 0, 0, 1); + kSuitColor[1] = kSuitColor[2] = CreateRGB(1, 0, 0, 1); } return kSuitColor[self.suit]; } diff -r e9f7ba4718e1 -r 3eb7be1dd7b6 Source/QuartzUtils.h --- a/Source/QuartzUtils.h Fri Mar 07 11:43:02 2008 -0800 +++ b/Source/QuartzUtils.h Mon Mar 10 17:30:57 2008 -0700 @@ -20,7 +20,7 @@ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#import +#import "GGBLayer.h" /** Constants for various commonly used colors. */ @@ -29,6 +29,15 @@ kAlmostInvisibleWhiteColor, kHighlightColor; +#if TARGET_OS_ASPEN +// These don't exist on iPhone, so I implement them: +CGColorRef CreateGray(CGFloat gray, CGFloat alpha); +CGColorRef CreateRGB(CGFloat red, CGFloat green, CGFloat blue, CGFloat alpha); +#else +#define CreateGray CGColorCreateGenericGray +#define CreateRGB CGColorCreateGenericRGB +#endif + /** Moves a layer from one superlayer to another, without changing its position onscreen. */ void ChangeSuperlayer( CALayer *layer, CALayer *newSuperlayer, int index ); @@ -36,11 +45,6 @@ /** Removes a layer from its superlayer without any fade-out animation. */ void RemoveImmediately( CALayer *layer ); -/** Convenience for creating a CATextLayer. */ -CATextLayer* AddTextLayer( CALayer *superlayer, - NSString *text, NSFont* font, - enum CAAutoresizingMask align ); - /** Loads an image or pattern file into a CGImage or CGPattern. If the name begins with "/", it's interpreted as an absolute filesystem path. @@ -52,8 +56,10 @@ CGImageRef GetCGImageNamed( NSString *name ); CGColorRef GetCGPatternNamed( NSString *name ); +#if ! TARGET_OS_ASPEN /** Loads image data from the pasteboard into a CGImage. */ CGImageRef GetCGImageFromPasteboard( NSPasteboard *pb ); +#endif /** Creates a CGPattern from a CGImage. Caller must release it. */ CGPatternRef CreateImagePattern( CGImageRef image ); @@ -67,4 +73,6 @@ /** Returns the center point of a CGRect. */ static inline CGPoint GetCGRectCenter( CGRect rect ) { return CGPointMake(CGRectGetMidX(rect),CGRectGetMidY(rect)); -} \ No newline at end of file +} + +void AddRoundRect( CGContextRef ctx, CGRect rect, CGFloat radius ); diff -r e9f7ba4718e1 -r 3eb7be1dd7b6 Source/QuartzUtils.m --- a/Source/QuartzUtils.m Fri Mar 07 11:43:02 2008 -0800 +++ b/Source/QuartzUtils.m Mon Mar 10 17:30:57 2008 -0700 @@ -21,6 +21,7 @@ THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #import "QuartzUtils.h" +#import CGColorRef kBlackColor, kWhiteColor, @@ -32,15 +33,36 @@ __attribute__((constructor)) // Makes this function run when the app loads static void InitQuartzUtils() { - kBlackColor = CGColorCreateGenericGray(0.0, 1.0); - kWhiteColor = CGColorCreateGenericGray(1.0, 1.0); - kTranslucentGrayColor = CGColorCreateGenericGray(0.0, 0.5); - kTranslucentLightGrayColor = CGColorCreateGenericGray(0.0, 0.25); - kAlmostInvisibleWhiteColor = CGColorCreateGenericGray(1, 0.05); - kHighlightColor = CGColorCreateGenericRGB(1, 1, 0, 0.5); + kBlackColor = CreateGray(0.0, 1.0); + kWhiteColor = CreateGray(1.0, 1.0); + kTranslucentGrayColor = CreateGray(0.0, 0.5); + kTranslucentLightGrayColor = CreateGray(0.0, 0.25); + kAlmostInvisibleWhiteColor = CreateGray(1, 0.05); + kHighlightColor = CreateRGB(1, 1, 0, 0.5); } +#if TARGET_OS_ASPEN +CGColorRef CreateGray(CGFloat gray, CGFloat alpha) +{ + CGColorSpaceRef graySpace = CGColorSpaceCreateDeviceGray(); + CGFloat components[2] = {gray,alpha}; + CGColorRef color = CGColorCreate(graySpace, components); + CGColorSpaceRelease(graySpace); + return color; +} + +CGColorRef CreateRGB(CGFloat red, CGFloat green, CGFloat blue, CGFloat alpha) +{ + CGColorSpaceRef rgbSpace = CGColorSpaceCreateDeviceRGB(); + CGFloat components[4] = {red,green,blue,alpha}; + CGColorRef color = CGColorCreate(rgbSpace, components); + CGColorSpaceRelease(rgbSpace); + return color; +} +#endif + + void ChangeSuperlayer( CALayer *layer, CALayer *newSuperlayer, int index ) { // Disable actions, else the layer will move to the wrong place and then back! @@ -75,49 +97,13 @@ } -CATextLayer* AddTextLayer( CALayer *superlayer, - NSString *text, NSFont* font, - enum CAAutoresizingMask align ) -{ - CATextLayer *label = [[CATextLayer alloc] init]; - label.string = text; - label.font = font; - label.fontSize = font.pointSize; - label.foregroundColor = kBlackColor; - - NSString *mode; - if( align & kCALayerWidthSizable ) - mode = @"center"; - else if( align & kCALayerMinXMargin ) - mode = @"right"; - else - mode = @"left"; - align |= kCALayerWidthSizable; - label.alignmentMode = mode; - - CGFloat inset = superlayer.borderWidth + 3; - CGRect bounds = CGRectInset(superlayer.bounds, inset, inset); - CGFloat height = font.ascender; - CGFloat y = bounds.origin.y; - if( align & kCALayerHeightSizable ) - y += (bounds.size.height-height)/2.0; - else if( align & kCALayerMinYMargin ) - y += bounds.size.height - height; - align &= ~kCALayerHeightSizable; - label.bounds = CGRectMake(0, font.descender, - bounds.size.width, height - font.descender); - label.position = CGPointMake(bounds.origin.x,y+font.descender); - label.anchorPoint = CGPointMake(0,0); - - label.autoresizingMask = align; - [superlayer addSublayer: label]; - [label release]; - return label; -} - - CGImageRef CreateCGImageFromFile( NSString *path ) { +#if TARGET_OS_ASPEN + UIImage *uiImage = [UIImage imageWithContentsOfFile: path]; + if(!uiImage) NSLog(@"Warning: UIImage imageWithContentsOfFile failed on file %@",path); + return CGImageRetain(uiImage.CGImage); +#else CGImageRef image = NULL; CFURLRef url = (CFURLRef) [NSURL fileURLWithPath: path]; CGImageSourceRef src = CGImageSourceCreateWithURL(url, NULL); @@ -127,11 +113,18 @@ if(!image) NSLog(@"Warning: CGImageSourceCreateImageAtIndex failed on file %@ (ptr size=%u)",path,sizeof(void*)); } return image; +#endif } CGImageRef GetCGImageNamed( NSString *name ) { +#if TARGET_OS_ASPEN + name = name.lastPathComponent; + UIImage *uiImage = [UIImage imageNamed: name]; + NSCAssert1(uiImage,@"Couldn't find bundle image resource '%@'",name); + return uiImage.CGImage; +#else // For efficiency, loaded images are cached in a dictionary by name. static NSMutableDictionary *sMap; if( ! sMap ) @@ -153,6 +146,7 @@ CGImageRelease(image); } return image; +#endif } @@ -173,6 +167,7 @@ } +#if ! TARGET_OS_ASPEN CGImageRef GetCGImageFromPasteboard( NSPasteboard *pb ) { CGImageSourceRef src = NULL; @@ -195,11 +190,17 @@ return image; } else return NULL; -} +} +#endif float GetPixelAlpha( CGImageRef image, CGSize imageSize, CGPoint pt ) { +#if TARGET_OS_ASPEN + // iPhone uses "flipped" (i.e. normal) coords, so images are wrong-way-up + pt.y = imageSize.height - pt.y; +#endif + // Trivial reject: if( pt.x<0 || pt.x>=imageSize.width || pt.y<0 || pt.y>=imageSize.height ) return 0.0; @@ -271,3 +272,24 @@ CGPatternRelease(pattern); return color; } + + +#pragma mark - +#pragma mark PATHS: + + +void AddRoundRect( CGContextRef ctx, CGRect rect, CGFloat radius ) +{ + radius = MIN(radius, floorf(rect.size.width/2)); + float x0 = CGRectGetMinX(rect), y0 = CGRectGetMinY(rect), + x1 = CGRectGetMaxX(rect), y1 = CGRectGetMaxY(rect); + + CGContextBeginPath(ctx); + CGContextMoveToPoint(ctx,x0+radius,y0); + CGContextAddArcToPoint(ctx,x1,y0, x1,y1, radius); + CGContextAddArcToPoint(ctx,x1,y1, x0,y1, radius); + CGContextAddArcToPoint(ctx,x0,y1, x0,y0, radius); + CGContextAddArcToPoint(ctx,x0,y0, x1,y0, radius); + CGContextClosePath(ctx); +} + diff -r e9f7ba4718e1 -r 3eb7be1dd7b6 Source/Stack.m --- a/Source/Stack.m Fri Mar 07 11:43:02 2008 -0800 +++ b/Source/Stack.m Mon Mar 10 17:30:57 2008 -0700 @@ -72,7 +72,7 @@ - (void) dump { printf("Stack = "); - for( CALayer *layer in self.sublayers ) + for( GGBLayer *layer in self.sublayers ) printf("%s @z=%g ", [[layer description] UTF8String],layer.zPosition); printf("\n"); } diff -r e9f7ba4718e1 -r 3eb7be1dd7b6 Source/TicTacToeGame.m --- a/Source/TicTacToeGame.m Fri Mar 07 11:43:02 2008 -0800 +++ b/Source/TicTacToeGame.m Mon Mar 10 17:30:57 2008 -0700 @@ -29,16 +29,24 @@ @implementation TicTacToeGame -- (void) x_createDispenser: (NSString*)imageName forPlayer: (int)playerNumber x: (int)x +- (void) x_createDispenser: (NSString*)imageName forPlayer: (int)playerNumber { Piece *p = [[Piece alloc] initWithImageNamed: imageName scale: 80]; p.owner = [self.players objectAtIndex: playerNumber]; + CGFloat x = floor(CGRectGetMidX(_board.bounds)); +#if TARGET_OS_ASPEN + x = x - 80 + 160*playerNumber; + CGFloat y = 360; +#else + x += (playerNumber==0 ?-230 :230); + CGFloat y = 175; +#endif _dispenser[playerNumber] = [[Dispenser alloc] initWithPrototype: p quantity: 0 - frame: CGRectMake(x,16, 120,120)]; + frame: CGRectMake(x-45,y-45, 90,90)]; [_board addSublayer: _dispenser[playerNumber]]; } -- (id) initWithBoard: (CALayer*)board +- (id) initWithBoard: (GGBLayer*)board { self = [super initWithBoard: board]; if (self != nil) { @@ -46,18 +54,16 @@ // Create a 3x3 grid: CGFloat center = floor(CGRectGetMidX(board.bounds)); - _grid = [[RectGrid alloc] initWithRows: 3 columns: 3 frame: CGRectMake(center-150,16, 300,300)]; + _grid = [[RectGrid alloc] initWithRows: 3 columns: 3 frame: CGRectMake(center-150,0, 300,300)]; [_grid addAllCells]; _grid.allowsMoves = _grid.allowsCaptures = NO; - _grid.cellColor = CGColorCreateGenericGray(1.0, 0.25); + _grid.cellColor = CreateGray(1.0, 0.25); _grid.lineColor = kTranslucentLightGrayColor; [board addSublayer: _grid]; // Create piece dispensers for the two players: - [self x_createDispenser: @"/System/Library/CoreServices/CoreTypes.bundle/Contents/Resources/ToolbarUtilitiesFolderIcon.icns" - forPlayer: 0 x: center-290]; - [self x_createDispenser: @"/System/Library/CoreServices/CoreTypes.bundle/Contents/Resources/ToolbarAdvanced.icns" - forPlayer: 1 x: center+170]; + [self x_createDispenser: @"X.tiff" forPlayer: 0]; + [self x_createDispenser: @"O.tiff" forPlayer: 1]; // And they're off! [self nextPlayer]; diff -r e9f7ba4718e1 -r 3eb7be1dd7b6 Source/iPhoneAppDelegate.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/iPhoneAppDelegate.h Mon Mar 10 17:30:57 2008 -0700 @@ -0,0 +1,25 @@ +// +// GGB_iPhoneAppDelegate.h +// GGB-iPhone +// +// Created by Jens Alfke on 3/7/08. +// Copyright __MyCompanyName__ 2008. All rights reserved. +// + +#import + +@class BoardUIView; + +@interface GGB_iPhoneAppDelegate : NSObject { + UIWindow *_window; + BoardUIView *_contentView; + UILabel *_headline; +} + +@property (nonatomic, retain) UIWindow *window; +@property (nonatomic, retain) BoardUIView *contentView; +@property (nonatomic, retain) UILabel *headline; + +- (void) startGameNamed: (NSString*)gameClassName; + +@end diff -r e9f7ba4718e1 -r 3eb7be1dd7b6 Source/iPhoneAppDelegate.m --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/iPhoneAppDelegate.m Mon Mar 10 17:30:57 2008 -0700 @@ -0,0 +1,126 @@ +// +// GGB_iPhoneAppDelegate.m +// GGB-iPhone +// +// Created by Jens Alfke on 3/7/08. +// Copyright __MyCompanyName__ 2008. All rights reserved. +// + +#import "GGB_iPhoneAppDelegate.h" +#import "BoardUIView.h" +#import "Game.h" +#import "QuartzUtils.h" +#import "GGBUtils.h" + + +@implementation GGB_iPhoneAppDelegate + + +@synthesize window=_window; +@synthesize contentView=_contentView; +@synthesize headline=_headline; + + +- (void)applicationDidFinishLaunching:(UIApplication *)application +{ + // Create window + self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease]; + _window.layer.backgroundColor = GetCGPatternNamed(@"Background.png"); + + // Set up content view + CGRect rHeadline,rContent; + CGRectDivide([[UIScreen mainScreen] applicationFrame], + &rHeadline, &rContent, 35, CGRectMinYEdge); + + self.contentView = [[[BoardUIView alloc] initWithFrame: rContent] autorelease]; + [_window addSubview: _contentView]; + + self.headline = [[[UILabel alloc] initWithFrame: rHeadline] autorelease]; + _headline.backgroundColor = nil; + _headline.opaque = NO; + _headline.textAlignment = UITextAlignmentCenter; + _headline.font = [UIFont boldSystemFontOfSize: 20]; + _headline.minimumFontSize = 14; + _headline.adjustsFontSizeToFit = YES; + [_window addSubview: _headline]; + + // Start game: + [self startGameNamed: @"TicTacToeGame"]; + + // Show window + [_window makeKeyAndVisible]; +} + + +- (void)dealloc +{ + [_contentView release]; + [_headline release]; + [_window release]; + [super dealloc]; +} + + +- (void) startGameNamed: (NSString*)gameClassName +{ + Game *game = _contentView.game; + [game removeObserver: self forKeyPath: @"currentPlayer"]; + [game removeObserver: self forKeyPath: @"winner"]; + + if( gameClassName == nil ) + gameClassName = [[game class] className]; + + [_contentView startGameNamed: gameClassName]; + + game = _contentView.game; + [game addObserver: self + forKeyPath: @"currentPlayer" + options: NSKeyValueObservingOptionInitial + context: NULL]; + [game addObserver: self + forKeyPath: @"winner" + options: 0 + context: NULL]; +} + + +- (void)observeValueForKeyPath:(NSString *)keyPath + ofObject:(id)object + change:(NSDictionary *)change + context:(void *)context +{ + Game *game = _contentView.game; + if( object == game ) { + Player *p = game.winner; + NSString *msg; + if( p ) { + PlaySound(@"Sosumi"); + msg = @"%@ wins!"; + } else { + p = game.currentPlayer; + msg = @"Your turn, %@"; + } + _headline.text = [NSString stringWithFormat: msg, p.name]; + + if( game.winner ) { + UIAlertView *alert; + alert = [[UIAlertView alloc] initWithTitle: msg + message: @"Congratulations!" + delegate:self + defaultButton:@"OK" + cancelButton:nil otherButtons:nil]; + [alert show]; + [alert release]; + } + } +} + + +- (void)modalView:(UIModalView *)modalView didDismissWithButtonIndex:(NSInteger)buttonIndex; +{ + // Start new game: + [self startGameNamed: nil]; +} + + +@end diff -r e9f7ba4718e1 -r 3eb7be1dd7b6 Source/main-iPhone.m --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Source/main-iPhone.m Mon Mar 10 17:30:57 2008 -0700 @@ -0,0 +1,17 @@ +// +// main.m +// GGB-iPhone +// +// Created by Jens Alfke on 3/7/08. +// Copyright __MyCompanyName__ 2008. All rights reserved. +// + +#import + +int main(int argc, char *argv[]) +{ + NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; + int retVal = UIApplicationMain(argc, argv, nil, @"GGB_iPhoneAppDelegate"); + [pool release]; + return retVal; +}