#import #import // own interface #import "Chess.h" // components #import "Board.h" #import "Board3D.h" #import "Clock.h" // not used #import "ResponseMeter.h" #import "ChessListener.h" // portability layer #import "gnuglue.h" #ifdef CHESS_DEBUG static int sCDInit; static const char * sCD; #define chess_debug(x) if (sCD || (!sCDInit++ && (sCD = getenv("CHESS_DEBUG")))) NSLog x; else 0 #else #define chess_debug(x) #endif #define NEW @"newGame:" #define OPEN @"openGame:" #define SAVE @"saveGame:" #define SAVEAS @"saveAsGame:" #define LIST @"listGame:" void PScompositerect(float x, float y, float w, float h, int op); void CL_MakeMove(const char * move) { if (move[0] == (char)-1) { [NSApp undoMove:NSApp]; } else { int r = move[1]-'1'; int c = move[0]-'a'; int r2= move[3]-'1'; int c2= move[2]-'a'; [NSApp makeMoveFrom: r : c to: r2 : c2]; } } // Chess class implementations @implementation Chess + (void)initialize { init_gnuchess(); return; } - (void)finishLaunching { float red, green, blue, alpha; NSScanner * scanner; [super finishLaunching]; defaults = [NSUserDefaults standardUserDefaults]; [defaults registerDefaults: [NSDictionary dictionaryWithObjectsAndKeys: @"0 0 0 1", @"WhiteColor", @"0 0 0 1", @"BlackColor", [levelSlider objectValue], @"Level", @"NO", @"BothSides", @"YES", @"PlayerHasWhite", @"YES", @"SpeechRecognition", NULL]]; gameBoard = board3D; [board2D retain]; [board2D removeFromSuperview]; scanner = [NSScanner scannerWithString:[defaults objectForKey:@"WhiteColor"]]; [scanner scanFloat:&red]; [scanner scanFloat:&green]; [scanner scanFloat:&blue]; [scanner scanFloat:&alpha]; white_color = [[NSColor colorWithCalibratedRed:red green:green blue:blue alpha:1.0] retain]; [whiteColorWell setColor:white_color]; scanner = [NSScanner scannerWithString:[defaults objectForKey:@"BlackColor"]]; [scanner scanFloat:&red]; [scanner scanFloat:&green]; [scanner scanFloat:&blue]; [scanner scanFloat:&alpha]; black_color = [[NSColor colorWithCalibratedRed:red green:green blue:blue alpha:1.0] retain]; [blackColorWell setColor:black_color]; [levelSlider setIntValue:[defaults integerForKey:@"Level"]]; if ([defaults boolForKey:@"BothSides"]) [gamePopup selectItemAtIndex:2]; else if ([defaults boolForKey:@"PlayerHasWhite"]) [gamePopup selectItemAtIndex:0]; else [gamePopup selectItemAtIndex:1]; prefs.useSR = [defaults boolForKey:@"SpeechRecognition"]; [srCheckBox setState:prefs.useSR]; [self setWhiteColor: self]; [self setBlackColor: self]; [self renderColors: self]; // default color pieces [self chooseSide: whiteSideName]; [self setPreferences: self]; // default preferences dirtyGame = NO; menusEnabled = YES; { NSString * path = [[NSBundle mainBundle] pathForResource: @"SpeechHelp" ofType: @"xml"]; NSData * help = [NSData dataWithContentsOfFile:path]; CL_SetHelp([help length], [help bytes]); } [self newGame: self]; return; } /* MainMenu responders */ - (void)info: (id)sender { NSShowSystemInfoPanel ([NSDictionary dictionary]); } - (void)showGnuDisclaimer: (id)sender { id text = [infoScroll documentView]; NSString *string = [text string]; if( ! string || [string isEqual: @""] ) { string = copyright_text(); [text setString: string]; [text sizeToFit]; // [text setFont:[NSFont fontWithName: @"Times" size: (float)14.0]]; [infoScroll display]; } [infoPanel makeKeyAndOrderFront: sender]; return; } /* Start a new game */ - (void)newGame: (id)sender { if (dirtyGame) { if (![self alertPanelForGameChange]) return; } finished = 0; undoCount = hintCount = forceCount = 0; new_game(); [self setTitle]; [self displayResponseMeter: WHITE]; [self displayResponseMeter: BLACK]; if( prefs.bothsides ) [startButton setEnabled: YES]; else { [startButton setEnabled: NO]; if( prefs.computer == WHITE ) [self selectMove: WHITE iop: 1]; else if (prefs.useSR) CL_Listen(WHITE, current_pieces(), current_colors()); } dirtyGame = NO; if (![boardWindow isKeyWindow]) [boardWindow makeKeyAndOrderFront:self]; return; } /* Read a saved game */ - (void)openGame: (id)sender { id op = [NSOpenPanel openPanel]; finished = 0; [op setRequiredFileType: @"chess"]; if( [op runModal] == NSOKButton ) { [filename release]; filename = [[op filename] retain]; get_game( filename ); } dirtyGame = NO; if (![boardWindow isVisible]) [boardWindow makeKeyAndOrderFront:self]; return; } /* Save a game */ - (void)listGame: (id)sender { NSSavePanel *sp = [NSSavePanel savePanel]; [sp setRequiredFileType: nil]; if( [sp runModal] == NSOKButton ) list_game( [sp filename] ); return; } - (void)saveGame: (id)sender { if ( filename && ! [filename isEqual: @""] ) save_game( filename ); else [self saveAsGame: sender]; dirtyGame = NO; return; } - (void)saveAsGame: (id)sender { NSSavePanel *sp = [NSSavePanel savePanel]; [sp setRequiredFileType: @"chess"]; if( [sp runModal] == NSOKButton ) { [filename release]; filename = [[sp filename] retain]; save_game( filename ); } dirtyGame = NO; return; } // Added this because it seems a little more Mac like. If you try to start // a new game or open a game while a game is in progress it asks you if you // would like to save the current game first. - (BOOL)alertPanelForGameChange { int button; button = NSRunAlertPanel( nil, NSLocalizedString(@"Would you like to save your current game first?",nil), NSLocalizedString(@"Save",nil), NSLocalizedString(@"No",nil), NSLocalizedString(@"Cancel",nil), nil ); switch( button ){ case -1: return NO; case 0: return YES; default: [self saveGame:self]; return YES; } } - (void)closeGame: (id)sender { if (dirtyGame) { if (![self alertPanelForGameChange]) return; } dirtyGame = NO; [boardWindow orderOut:self]; } /* Give the player a hint */ - (void)hint: (id)sender { if( give_hint() ){ hintCount++; [self setTitle]; } else (void)NSRunAlertPanel( nil, NSLocalizedString(@"no_hint",nil), nil, nil, nil ); return; } - (void)showPosition: (id)sender { [gameBoard highlightSquareAt: currentRow : currentCol]; [gameBoard flashSquareAt: currentRow : currentCol]; return; } /* Undo last two half moves */ - (void)undoMove: (id)sender { if( game_count() >= 0 ){ undo_move(); undo_move(); undoCount++; [self setTitle]; if (prefs.useSR) CL_Listen(prefs.opponent, current_pieces(), current_colors()); } else (void)NSRunAlertPanel( nil, NSLocalizedString(@"no_undo",nil), nil, nil, nil ); return; } - (void)view2D: (id)sender { [menu2D setState: NSOnState]; [menu3D setState: NSOffState]; if( gameBoard == board3D ) { id v = [gameBoard superview]; // NSRect b = [v bounds]; short *pieces = current_pieces(); short *colors = current_colors(); [gameBoard retain]; [gameBoard removeFromSuperview]; // [v lockFocus]; // PSgsave(); // PSsetgray( NSBlack ); // PSrectfill( (float)0.0, (float)0.0, b.size.width, b.size.height ); // PSgrestore(); // [v unlockFocus]; [v addSubview: board2D]; [board2D release]; gameBoard = board2D; [gameBoard layoutBoard: pieces color: colors]; [self disableClockPanel]; } return; } - (void)view3D: (id)sender { [menu2D setState: NSOffState]; [menu3D setState: NSOnState]; if( gameBoard == board2D ) { id v = [gameBoard superview]; short *pieces = current_pieces(); short *colors = current_colors(); [gameBoard retain]; [gameBoard removeFromSuperview]; [v addSubview: board3D]; [board3D release]; gameBoard = board3D; [gameBoard layoutBoard: pieces color: colors]; [self enableClockPanel]; } return; } - (void)print: (id)sender { [gameBoard print: sender]; return; } /* ClockPanel responders */ - (void)setWhiteColor: (id)sender { NSString *path; NSImage *image1; NSImage *image2; NSRect r; NSPoint pt; path = [[NSBundle mainBundle] pathForImageResource: @"3d_white_sample"]; image1 = [[NSImage alloc] initWithContentsOfFile: path]; image2 = [whiteSample image]; r.origin = NSZeroPoint; r.size = [image2 size]; pt = NSZeroPoint; [image2 lockFocus]; [image1 compositeToPoint: pt fromRect: r operation: NSCompositeCopy]; [image2 unlockFocus]; [image1 lockFocus]; [[whiteColorWell color] set]; PScompositerect( pt.x, pt.y, r.size.width, r.size.height, NSCompositePlusDarker ); [image1 unlockFocus]; [image2 lockFocus]; [image1 compositeToPoint: pt fromRect: r operation: NSCompositeSourceAtop]; [image2 unlockFocus]; [whiteSample display]; [image1 release]; if( ! [white_color isEqual: [whiteColorWell color]] ) [colorSetButton setEnabled: YES]; return; } - (void)setBlackColor: (id)sender { NSString *path; NSImage *image1; NSImage *image2; NSRect r; NSPoint pt; path = [[NSBundle mainBundle] pathForImageResource: @"3d_black_sample"]; image1 = [[NSImage alloc] initWithContentsOfFile: path]; image2 = [blackSample image]; r.origin = NSZeroPoint; r.size = [image2 size]; pt = NSZeroPoint; [image2 lockFocus]; [image1 compositeToPoint: pt fromRect: r operation: NSCompositeCopy]; [image2 unlockFocus]; [image1 lockFocus]; [[blackColorWell color] set]; PScompositerect( pt.x, pt.y, r.size.width, r.size.height, NSCompositePlusDarker ); [image1 unlockFocus]; [image2 lockFocus]; [image1 compositeToPoint: pt fromRect: r operation: NSCompositeSourceAtop]; [image2 unlockFocus]; [blackSample display]; [image1 release]; if( ! [black_color isEqual: [blackColorWell color]] ) [colorSetButton setEnabled: YES]; return; } - (void)renderColors: (id)sender { NSString *path; NSImage *image1; NSImage *image2; NSRect r; NSPoint pt; if( gameBoard != board3D ) return; path = [[NSBundle mainBundle] pathForImageResource: @"3d_pieces"]; image1 = [[NSImage alloc] initWithContentsOfFile: path]; image2 = [gameBoard piecesBitmap]; r.origin = NSZeroPoint; r.size = [image2 size]; pt = NSZeroPoint; if( ! [white_color isEqual: [whiteColorWell color]] ) { float red, green, blue, alpha; [white_color release]; white_color = [[whiteColorWell color] retain]; [white_color getRed:&red green:&green blue:&blue alpha:&alpha]; [defaults setObject:[NSString stringWithFormat:@"%1.3f %1.3f %1.3f %1.3f", red, green, blue, alpha] forKey:@"WhiteColor"]; } if( ! [black_color isEqual: [blackColorWell color]] ) { float red, green, blue, alpha; [black_color release]; black_color = [[blackColorWell color] retain]; [black_color getRed:&red green:&green blue:&blue alpha:&alpha]; [defaults setObject:[NSString stringWithFormat:@"%1.3f %1.3f %1.3f %1.3f", red, green, blue, alpha] forKey:@"BlackColor"]; } [image2 lockFocus]; [image1 compositeToPoint: pt fromRect: r operation: NSCompositeCopy]; [image2 unlockFocus]; [image1 lockFocus]; [white_color set]; PScompositerect( pt.x, pt.y, (float)336.0, r.size.height, NSCompositePlusDarker ); [black_color set]; PScompositerect( (float)336.0, pt.y, (float)336.0, r.size.height, NSCompositePlusDarker ); [image1 unlockFocus]; [image2 lockFocus]; [image1 compositeToPoint: pt fromRect: r operation: NSCompositeSourceAtop]; [image2 unlockFocus]; [gameBoard display]; [image1 release]; [colorSetButton setEnabled: NO]; return; } - (void)startGame: (id)sender { if( [sender state] == 1 ) { // This is the loop that makes the computer play. It can be terminated // by several conditions. The "Stop" button may be clicked, cmd-. may // be pressed, or the game may end. [self setMainMenuEnabled: NO]; [self disablePrefPanel]; [self disableClockPanel]; run_computer_game(); [sender setState: 0]; } else { stop_computer_game(); [self enableClockPanel]; [self enablePrefPanel]; [self setMainMenuEnabled: YES]; } return; } - (void)forceMove: (id)sender { set_timeout( YES ); return; } /* PrefPanel responders */ /* Change the text displayed below the level slider to indicate what the level means */ - (void)levelSliding: (id)sender { NSString *format, *string; int moves, minutes; int level = [sender intValue]; interpret_level( level, &moves, &minutes ); if( moves > 1 ) format = NSLocalizedString( @"%d moves in %d minutes", nil ); else format = NSLocalizedString( @"%d move in %d minutes", nil ); string = [NSString stringWithFormat: format, moves, minutes]; [levelText setStringValue: string]; if( level != game_level() ) [prefSetButton setEnabled: YES]; return; } /* Set the text fields next to the side matrices */ - (void)chooseSide: (id)sender { switch ([gamePopup indexOfSelectedItem]) { case 0: /* Human vs. Computer */ [whiteSideName setStringValue: user_fullname()]; [blackSideName setStringValue: NSLocalizedString(@"Computer",nil)]; if ( !( !prefs.bothsides && prefs.computer == BLACK)) [prefSetButton setEnabled: YES]; break; case 1: /* Computer vs. Human */ [whiteSideName setStringValue: NSLocalizedString(@"Computer",nil)]; [blackSideName setStringValue: user_fullname()]; if ( !( !prefs.bothsides && prefs.computer == WHITE)) [prefSetButton setEnabled: YES]; break; case 2: /* Computer vs. Computer */ [whiteSideName setStringValue: NSLocalizedString(@"Computer",nil)]; [blackSideName setStringValue: NSLocalizedString(@"Computer",nil)]; if ( !prefs.bothsides ) [prefSetButton setEnabled: YES]; break; } if (prefs.useSR != [srCheckBox state]) [prefSetButton setEnabled: YES]; if( ! [prefs.white_name isEqual: [whiteSideName stringValue]] ) [prefSetButton setEnabled: YES]; if( ! [prefs.black_name isEqual: [blackSideName stringValue]] ) [prefSetButton setEnabled: YES]; return; } /* TextField delegate */ - (void)controlTextDidBeginEditing: (NSNotification *)notification { id txField = [notification object]; if( txField == whiteSideName || txField == blackSideName ) { [prefSetButton setEnabled: YES]; } return; } /* Actually set the preferences */ - (void)setPreferences: (id)sender { int button; int level = [levelSlider intValue]; set_game_level ( level ); interpret_level( level, &prefs.time_cntl_moves, &prefs.time_cntl_minutes ); switch ([gamePopup indexOfSelectedItem]) { case 0: prefs.bothsides = NO; prefs.opponent = WHITE; prefs.computer = BLACK; break; case 1: prefs.bothsides = NO; prefs.opponent = BLACK; prefs.computer = WHITE; break; case 2: prefs.bothsides = YES; prefs.opponent = WHITE; prefs.computer = BLACK; break; } if (prefs.useSR && ![srCheckBox state]) CL_DontListen(); prefs.useSR = [srCheckBox state]; prefs.cheat = YES; // always YES? if( ! [prefs.white_name isEqual: [whiteSideName stringValue]] ) { [prefs.white_name release]; prefs.white_name = [[whiteSideName stringValue] retain]; [whiteClockText setStringValue: prefs.white_name]; } if( ! [prefs.black_name isEqual: [blackSideName stringValue]] ) { [prefs.black_name release]; prefs.black_name = [[blackSideName stringValue] retain]; [blackClockText setStringValue: prefs.black_name]; } set_preferences( &prefs ); [prefSetButton setEnabled: NO]; if( sender == self ) return; // default setting [defaults setInteger:[levelSlider intValue] forKey:@"Level"]; [defaults setBool:prefs.bothsides forKey:@"BothSides"]; [defaults setBool:prefs.computer forKey:@"PlayerHasWhite"]; [defaults setBool:prefs.useSR forKey:@"SpeechRecognition"]; reset_response_time(); [self displayResponseMeter: WHITE]; [self displayResponseMeter: BLACK]; button = NSRunAlertPanel( nil, NSLocalizedString(@"new_game",nil), NSLocalizedString(@"Yes",nil), NSLocalizedString(@"No",nil), nil ); if ( button == NSAlertDefaultReturn ) { dirtyGame = NO; [self newGame: self]; } else { if( prefs.bothsides ) [startButton setEnabled: YES]; else { [startButton setEnabled: NO]; if( current_player() == WHITE && prefs.computer == WHITE ) [self selectMove: WHITE iop: 1]; else if( current_player() == BLACK && prefs.computer == BLACK ) [self selectMove: BLACK iop: 1]; } } return; } /* invoked by Board.m & Board3D.m */ - (BOOL)bothsides { return prefs.bothsides; } - (int)finished { return finished; } - (void)finishedAlert { NSString *msg; chess_debug(( @"finished %d", finished )); switch( finished ){ case DRAW_GAME : msg = @"draw_game"; break; case WHITE_MATE : msg = @"black_win"; break; case BLACK_MATE : msg = @"white_win"; break; case OPPONENT_MATE : msg = @"you_win"; break; default : return; } (void)NSRunAlertPanel( nil, NSLocalizedString(msg,nil), nil, nil, nil ); return; } - (BOOL)makeMoveFrom: (int)row1 : (int)col1 to: (int)row2 : (int)col2 { NSString *move; short oldguy, newguy; BOOL verified; short *pieces, *colors; dirtyGame = YES; oldguy = [gameBoard pieceAt: row1 : col1]; move = convert_rowcol( row1, col1, row2, col2, oldguy ); verified = verify_move( move ); if( ! verified ) { [self setTitleMessage: @"Illegal move"]; NSBeep(); return( NO ); } newguy = [gameBoard pieceAt: row2 : col2]; if ( (newguy == QUEEN) && (oldguy == PAWN) ) { chess_debug (( @"pawn becomes queen..." )); set_game_queen( PAWN ); } else set_game_queen( NO_PIECE ); chess_debug(( @"<<< opponent move time %d move %@", move_time(), move )); [self updateClocks: prefs.opponent]; in_check(); PSWait(); pieces = current_pieces(); colors = current_colors(); [gameBoard layoutBoard: pieces color: colors]; // [gameBoard display]; PSWait(); select_computer_move(); return( YES ); } /* invoked by gnuglue.m */ - (void)peekAndGetLeftMouseDownEvent { NSEvent *event; if( event = [NSApp nextEventMatchingMask: NSLeftMouseDownMask untilDate: [NSDate date] inMode: NSEventTrackingRunLoopMode dequeue: NO] ) { event = [NSApp nextEventMatchingMask: NSLeftMouseDownMask untilDate: [NSDate date] inMode: NSEventTrackingRunLoopMode dequeue: YES]; [NSApp sendEvent: event]; } return; } - (void)selectMove: (int)side iop: (int)iop { if( side == WHITE ) [self setTitleMessage: @"White's move"]; else [self setTitleMessage: @"Black's move"]; [self setMainMenuEnabled: NO]; [self disablePrefPanel]; [self disableClockPanel]; [gameBoard setEnabled: NO]; [forceButton setEnabled: YES]; if (prefs.useSR) CL_DontListen(); PSWait(); select_move_start( side, iop ); while( ! select_loop_end() ) select_loop(); select_move_end(); [self setTitle]; [self updateClocks: prefs.computer]; in_check(); PSWait(); [forceButton setEnabled: NO]; [gameBoard setEnabled: YES]; [self enableClockPanel]; [self enablePrefPanel]; [self setMainMenuEnabled: YES]; if (prefs.useSR) CL_Listen(!side, current_pieces(), current_colors()); return; } - (void)setFinished: (int)flag { finished = flag; [self finishedAlert]; return; } - (void)movePieceFrom: (int)row1 : (int)col1 to: (int)row2 : (int)col2 { NSString *move; short oldguy; short *pieces = current_pieces(); short *colors = current_colors(); oldguy = [gameBoard pieceAt: row1 : col1]; move = convert_rowcol( row1, col1, row2, col2, oldguy ); chess_debug( (@">>> computer move time %d move %@", move_time(), move) ); dirtyGame = YES; [gameBoard highlightSquareAt: row1 : col1]; [gameBoard slidePieceFrom: row1 : col1 to: row2 : col2]; [self storePosition: row2 : col2]; [gameBoard layoutBoard: pieces color: colors]; // [gameBoard display]; PSWait(); [gameBoard highlightSquareAt: row2 : col2]; return; } - (void)updateBoard { short *pieces = current_pieces(); short *colors = current_colors(); [gameBoard layoutBoard: pieces color: colors]; [gameBoard display]; return; } - (int)pieceTypeAt: (int)row : (int)col { return [gameBoard pieceAt: row : col]; } - (void)highlightSquareAt: (int)row : (int)col { [gameBoard highlightSquareAt: row : col]; return; } - (void)displayResponseMeter: (int)side { if( [clockPanel isVisible] ) { if( side == WHITE ) [whiteMeter display]; else [blackMeter display]; PSWait(); } return; } - (void)fillResponseMeter: (int)side { if( [clockPanel isVisible] ) { if( side == WHITE ) [whiteMeter displayFilled]; else [blackMeter displayFilled]; PSWait(); } return; } - (void)setTitleMessage: (NSString *)msg { NSMutableString *buf; [self setTitle]; buf = [NSMutableString stringWithCapacity: (unsigned)0]; [buf appendString: [boardWindow title]]; [buf appendString: NSLocalizedString(@" : ", nil)]; [buf appendString: NSLocalizedString(msg, nil)]; [boardWindow setTitle: buf]; return; } - (BOOL)canFinishGame { int sts = NSRunAlertPanel( nil, NSLocalizedString(@"exit_chess",nil), NSLocalizedString(@"Yes",nil), NSLocalizedString(@"No",nil), nil ); return ( sts == NSAlertDefaultReturn ) ? YES : NO; } /* Support methods */ - (void)setTitle /* Change the board windows title to display the number of cheat commands issued. */ { NSMutableString *str = [NSMutableString stringWithCapacity: 0]; if( undoCount || hintCount ) { [str appendString: NSLocalizedString(@"Chess: ", nil)]; if( undoCount == 1 ) [str appendString: NSLocalizedString(@"1 Undo ", nil)]; else if( undoCount ) [str appendFormat: NSLocalizedString(@"%d Undos ",nil),undoCount]; if( hintCount == 1 ) [str appendString: NSLocalizedString(@"1 Hint", nil)]; else if( hintCount ) [str appendFormat: NSLocalizedString(@"%d Hints",nil),hintCount]; } else [str appendString: NSLocalizedString(@"Chess", nil)]; [boardWindow setTitle: str]; return; } - (void)storePosition: (int) row : (int) col { currentRow = row; currentCol = col; return; } - (BOOL)validateMenuItem:(NSMenuItem *)item { //[item action] if (!menusEnabled) { NSString *selector = NSStringFromSelector([item action]); if ([selector isEqual:NEW]) return NO; else if ([selector isEqual:OPEN]) return NO; else if ([selector isEqual:SAVE]) return NO; else if ([selector isEqual:SAVEAS]) return NO; else if ([selector isEqual:LIST]) return NO; else return YES; } return YES; } - (void)setMainMenuEnabled: (BOOL)flag { menusEnabled = flag; return; } - (void)enablePrefPanel { [levelSlider setEnabled: YES]; [levelText setTextColor: [NSColor blackColor]]; [gamePopup setEnabled: YES]; [whiteSideName setEnabled: YES]; [blackSideName setEnabled: YES]; if( [levelSlider intValue] != game_level() || ! [prefs.white_name isEqual: [whiteSideName stringValue]] || ! [prefs.black_name isEqual: [blackSideName stringValue]] ) { [prefSetButton setEnabled: YES]; } return; } - (void)disablePrefPanel { [levelSlider setEnabled: NO]; [levelText setTextColor: [NSColor darkGrayColor]]; [gamePopup setEnabled: NO]; [whiteSideName setEnabled: NO]; [blackSideName setEnabled: NO]; [prefSetButton setEnabled: NO]; return; } - (void)enableClockPanel { if( gameBoard == board3D ) { [whiteColorWell setEnabled: YES]; [blackColorWell setEnabled: YES]; if( ! [white_color isEqual: [whiteColorWell color]] || ! [black_color isEqual: [blackColorWell color]] ) { [colorSetButton setEnabled: YES]; } } return; } - (void)disableClockPanel { [whiteColorWell setEnabled: NO]; [blackColorWell setEnabled: NO]; [colorSetButton setEnabled: NO]; return; } - (int)whiteTime { return whiteTime; } - (int)blackTime { return blackTime; } - (void)updateClocks: (int)side { if( ! blackClock || ! whiteClock ) return; if( side == WHITE ) { whiteTime += move_time(); if( [clockPanel isVisible] ) { [whiteClock setSeconds: whiteTime]; [whiteClock display]; } } else { blackTime += move_time(); if( [clockPanel isVisible] ) { [blackClock setSeconds: blackTime]; [blackClock display]; } } return; } /* Application delegate */ - (int)application: (NSApplication *)sender openFile: (NSString *)path withType: (NSString *)type { chess_debug( (@"Open file: %@ type: %@", path, type) ); if( type && [type isEqual: @"chess"] ) { [filename release]; filename = [path retain]; get_game( filename ); return (int)YES; } return (int)NO; } @end