# HG changeset patch # User Jens Alfke # Date 1215648465 25200 # Node ID 73f8c889f053baa2b545f205f428f27c9c7b2e9b # Parent 4585c74d809cd08644f420ed4a6f45d1dd07ccd4 More tweaks, including a "reversed" property for Grids to show the second player's perspective without turning the pieces upside-down. diff -r 4585c74d809c -r 73f8c889f053 Source/BitHolder.m --- a/Source/BitHolder.m Tue Jul 08 20:32:52 2008 -0700 +++ b/Source/BitHolder.m Wed Jul 09 17:07:45 2008 -0700 @@ -54,6 +54,8 @@ } setObj(&_bit,bit); ChangeSuperlayer(bit,self,-1); + if( bit ) + NSLog(@"%@: xform = \n%@",bit,StringFromTransform3D(bit.aggregateTransform));//TEMP } } diff -r 4585c74d809c -r 73f8c889f053 Source/BoardView.h --- a/Source/BoardView.h Tue Jul 08 20:32:52 2008 -0700 +++ b/Source/BoardView.h Wed Jul 09 17:07:45 2008 -0700 @@ -56,8 +56,6 @@ - (void) createGameBoard; -- (void) reverseBoard; - - (IBAction) enterFullScreen: (id)sender; - (CGRect) gameBoardFrame; diff -r 4585c74d809c -r 73f8c889f053 Source/BoardView.m --- a/Source/BoardView.m Tue Jul 08 20:32:52 2008 -0700 +++ b/Source/BoardView.m Wed Jul 09 17:07:45 2008 -0700 @@ -71,13 +71,6 @@ } -- (void) reverseBoard -{ - [_gameboard setValue: [NSNumber numberWithDouble: M_PI] - forKeyPath: @"transform.rotation"]; -} - - - (Game*) game { return _game; @@ -103,14 +96,6 @@ } -- (BOOL) canMakeMove -{ - return _game != nil - && _game.currentPlayer.local - && _game.currentTurn.status < kTurnComplete; -} - - - (CGRect) gameBoardFrame { return self.layer.bounds; @@ -120,7 +105,7 @@ - (void)resetCursorRects { [super resetCursorRects]; - if( self.canMakeMove ) + if( _game.okToMove ) [self addCursorRect: self.bounds cursor: [NSCursor openHandCursor]]; } @@ -225,7 +210,7 @@ - (void) mouseDown: (NSEvent*)ev { - if( ! self.canMakeMove ) { + if( ! _game.okToMove ) { NSBeep(); return; } diff -r 4585c74d809c -r 73f8c889f053 Source/CheckersGame.m --- a/Source/CheckersGame.m Tue Jul 08 20:32:52 2008 -0700 +++ b/Source/CheckersGame.m Wed Jul 09 17:07:45 2008 -0700 @@ -98,6 +98,7 @@ grid.cellColor = CreateGray(0.0, 0.25); grid.altCellColor = CreateGray(1.0, 0.25); grid.lineColor = nil; + grid.reversed = ! [[self.players objectAtIndex: 0] isLocal]; for( int i=0; i<32; i++ ) { int row = i/4; diff -r 4585c74d809c -r 73f8c889f053 Source/GGBLayer.h --- a/Source/GGBLayer.h Tue Jul 08 20:32:52 2008 -0700 +++ b/Source/GGBLayer.h Wed Jul 09 17:07:45 2008 -0700 @@ -43,6 +43,8 @@ and update every other layer that shares the same style dictionary. */ - (void) setValue: (id)value ofStyleProperty: (NSString*)prop; +- (CATransform3D) aggregateTransform; + @end @@ -58,3 +60,4 @@ CGColorRef GetEffectiveBackground( CALayer *layer ); +NSString* StringFromTransform3D( CATransform3D xform ); diff -r 4585c74d809c -r 73f8c889f053 Source/GGBLayer.m --- a/Source/GGBLayer.m Tue Jul 08 20:32:52 2008 -0700 +++ b/Source/GGBLayer.m Wed Jul 09 17:07:45 2008 -0700 @@ -124,6 +124,30 @@ } +- (CATransform3D) aggregateTransform +{ + CATransform3D xform = CATransform3DIdentity; + for( CALayer *layer=self; layer; layer=layer.superlayer ) { + xform = CATransform3DConcat(layer.transform,xform); + xform = CATransform3DConcat(layer.sublayerTransform,xform); + } + return xform; +} + + +NSString* StringFromTransform3D( CATransform3D xform ) +{ + NSMutableString *str = [NSMutableString string]; + const CGFloat *np = (const CGFloat*)&xform; + for( int i=0; i<16; i++ ) { + if( i>0 && (i%4)==0 ) + [str appendString: @"\n"]; + [str appendFormat: @"%7.2f ", *np++]; + } + return str; +} + + #if TARGET_OS_IPHONE diff -r 4585c74d809c -r 73f8c889f053 Source/Game.h --- a/Source/Game.h Tue Jul 08 20:32:52 2008 -0700 +++ b/Source/Game.h Wed Jul 09 17:07:45 2008 -0700 @@ -77,6 +77,10 @@ @property unsigned currentTurnNo; @property (readonly) BOOL isLatestTurn; +/** Check this before the user begins a move action (mouse-down on a bit, etc.) + It's YES if it's OK to move, or NO if the current move is finished or it's another player's turn. */ +@property (readonly) BOOL okToMove; + @property BOOL requireConfirmation; - (void) cancelCurrentTurn; - (void) confirmCurrentTurn; diff -r 4585c74d809c -r 73f8c889f053 Source/Game.m --- a/Source/Game.m Tue Jul 08 20:32:52 2008 -0700 +++ b/Source/Game.m Wed Jul 09 17:07:45 2008 -0700 @@ -219,6 +219,23 @@ } +- (BOOL) okToMove +{ + Turn *latest = self.latestTurn; + if( latest.player.local && latest.status < kTurnComplete ) { + // Automatically skip from latest finished turn, since board state is the same: + unsigned latestTurnNo = self.maxTurnNo; + if( _currentTurnNo==latestTurnNo-1 ) { + NSLog(@"okToMove: skipping from turn %i to %i",_currentTurnNo,latestTurnNo); + self.currentTurnNo = latestTurnNo; + } + if( _currentTurnNo==latestTurnNo ) + return YES; + } + return NO; +} + + - (void) endTurn { Turn *curTurn = self.currentTurn; diff -r 4585c74d809c -r 73f8c889f053 Source/Grid.h --- a/Source/Grid.h Tue Jul 08 20:32:52 2008 -0700 +++ b/Source/Grid.h Wed Jul 09 17:07:45 2008 -0700 @@ -32,7 +32,7 @@ Class _cellClass; CGColorRef _cellColor, _lineColor; CGImageRef _backgroundImage; - BOOL _usesDiagonals, _allowsMoves, _allowsCaptures; + BOOL _usesDiagonals, _allowsMoves, _allowsCaptures, _reversed; NSMutableArray *_cells; // Really a 2D array, in row-major order. } @@ -55,6 +55,7 @@ @property CGImageRef backgroundImage; // Image drawn in background, behind lines and cells @property BOOL usesDiagonals; // Affects GridCell.neighbors, for rect grids @property BOOL allowsMoves, allowsCaptures; // Can pieces be moved, and can they land on others? +@property BOOL reversed; // Reverses board (rotates 180°) by exchanging cell positions @property (readonly) NSArray *cells; diff -r 4585c74d809c -r 73f8c889f053 Source/Grid.m --- a/Source/Grid.m Tue Jul 08 20:32:52 2008 -0700 +++ b/Source/Grid.m Wed Jul 09 17:07:45 2008 -0700 @@ -112,7 +112,7 @@ } } -@synthesize cellClass=_cellClass, rows=_nRows, columns=_nColumns, spacing=_spacing, +@synthesize cellClass=_cellClass, rows=_nRows, columns=_nColumns, spacing=_spacing, reversed=_reversed, usesDiagonals=_usesDiagonals, allowsMoves=_allowsMoves, allowsCaptures=_allowsCaptures; @@ -136,7 +136,7 @@ suggestedFrame: (CGRect)frame { GridCell *cell = [[_cellClass alloc] initWithGrid: self - row: row column: col + row: row column: col frame: frame]; cell.name = [NSString stringWithFormat: @"%c%u", ('A'+row),(1+col)]; return [cell autorelease]; @@ -150,7 +150,12 @@ unsigned index = row*_nColumns+col; GridCell *cell = [_cells objectAtIndex: index]; if( (id)cell == [NSNull null] ) { - CGRect frame = CGRectMake(col*_spacing.width, row*_spacing.height, + unsigned effectiveRow=row, effectiveCol=col; + if( _reversed ) { + effectiveRow = _nRows-1 - effectiveRow; + effectiveCol = _nColumns-1 - effectiveCol; + } + CGRect frame = CGRectMake(effectiveCol*_spacing.width, effectiveRow*_spacing.height, _spacing.width,_spacing.height); cell = [self createCellAtRow: row column: col suggestedFrame: frame]; if( cell ) { @@ -274,6 +279,21 @@ } } +- (void) drawBackgroundInContext: (CGContextRef)ctx +{ + if( _backgroundImage ) { + CGRect bounds = self.bounds; + if( _reversed ) { + CGContextSaveGState(ctx); + CGContextRotateCTM(ctx, M_PI); + CGContextTranslateCTM(ctx, -bounds.size.width, -bounds.size.height); + } + CGContextDrawImage(ctx, bounds, _backgroundImage); + if( _reversed ) + CGContextRestoreGState(ctx); + } +} + - (void)drawInContext:(CGContextRef)ctx { @@ -281,8 +301,7 @@ // in me; this is more efficient than having each cell have its own drawing. [super drawInContext: ctx]; - if( _backgroundImage ) - CGContextDrawImage(ctx, self.bounds, _backgroundImage); + [self drawBackgroundInContext: ctx]; if( _cellColor ) { CGContextSetFillColorWithColor(ctx, _cellColor); diff -r 4585c74d809c -r 73f8c889f053 Source/HexchequerGame.m --- a/Source/HexchequerGame.m Tue Jul 08 20:32:52 2008 -0700 +++ b/Source/HexchequerGame.m Wed Jul 09 17:07:45 2008 -0700 @@ -42,6 +42,7 @@ grid.allowsCaptures = NO; // no land-on captures, that is grid.cellColor = CreateGray(1.0, 0.25); grid.lineColor = kTranslucentLightGrayColor; + grid.reversed = ! [[self.players objectAtIndex: 0] isLocal]; [grid addCellsInHexagon]; } diff -r 4585c74d809c -r 73f8c889f053 Source/Turn.h --- a/Source/Turn.h Tue Jul 08 20:32:52 2008 -0700 +++ b/Source/Turn.h Wed Jul 09 17:07:45 2008 -0700 @@ -39,14 +39,14 @@ @property (readonly) Game *game; @property (readonly) Player *player, *nextPlayer; -@property (readonly) Turn *previousTurn; +@property (readonly) Turn *previousTurn, *nextTurn; @property (readonly) unsigned turnNumber; @property (readonly) BOOL isLatestTurn; @property TurnStatus status; -@property (readonly,copy) NSString *move; -@property (readonly,copy) NSString *boardState; +@property (readonly,copy) NSString *move; // The player's move (nil for turn 0) +@property (readonly,copy) NSString *boardState; // State of the game AFTER the move @property (readonly,retain)NSDate *date; @property (copy) NSString *comment; diff -r 4585c74d809c -r 73f8c889f053 Source/Turn.m --- a/Source/Turn.m Tue Jul 08 20:32:52 2008 -0700 +++ b/Source/Turn.m Wed Jul 09 17:07:45 2008 -0700 @@ -99,9 +99,7 @@ - (unsigned) turnNumber {return [_game.turns indexOfObjectIdenticalTo: self];} - (BOOL) isLatestTurn {return _game.turns.lastObject == self;} -- (Turn*) previousTurn {return [_game.turns objectAtIndex: self.turnNumber-1];} - (Player*) nextPlayer {return _player ?_player.nextPlayer :[_game.players objectAtIndex: 0];} - - (TurnStatus) status {return _status;} - (void) setStatus: (TurnStatus)status @@ -132,6 +130,25 @@ } +- (Turn*) previousTurn +{ + unsigned n = self.turnNumber; + if( n > 0 ) + return [_game.turns objectAtIndex: n-1]; + else + return nil; +} + +- (Turn*) nextTurn +{ + unsigned n = self.turnNumber; + if( n+1 < _game.turns.count ) + return [_game.turns objectAtIndex: n+1]; + else + return nil; +} + + - (void) addToMove: (NSString*)move { if( ! _replaying ) {