This is Board.m in view mode; [Download] [Up]
/* Generated by Interface Builder */ #import "Board.h" #import <appkit/obsoleteBitmap.h> #import <appkit/Application.h> #import <dpsclient/dpsclient.h> #import <dpsclient/psops.h> #import <dpsclient/wraps.h> #import <libc.h> #import "ics_filter.h" #import "spawn.h" id myself; char *pieceNames[] = {" ", "WP", "WR", "WN", "WB", "WQ", "WK", "BP", "BR", "BN", "BB", "BQ", "BK" }; #define SQUARESIZE 64.0 #define PIECESIZE 64.0 #define WHITE 'W' #define BLACK 'B' @interface BoardDelegate:Object { } - pieceMoved:(int)x1 :(int)y1 :(int)x2 :(int)y2; @end void GotABoard( char *line ) { [myself parseBoard:line]; } @implementation Board - initFrame:(NXRect *)tF { [super initFrame:tF]; [self initBoard]; delegate = NULL; myself = self; who = WHITE; clockEntry = NULL; setBoardLineFunc( GotABoard ); isFlipped = NO; lastX = -1; lastY = -1; return self; } - (BOOL)acceptsFirstResponder { return YES; } - keyDown:(NXEvent *)theEvent { char c; c = theEvent->data.key.charCode; WriteChars( &c, 1 ); return self; } - (BOOL)acceptsFirstMouse { return YES; } - mouseDown:(NXEvent *)theEvent { int oldMask; int si, sj, ei, ej; NXPoint offset, zerozero = {0.0,0.0}, newoffset; id pieceBitmap; NXRect wFrame, myWindowFrame; int thePiece; /* There are two no-retained windows to try and make the dragging less flashy, it doesn't work. I don't know how to appropriately drag a piece */ id theWindow[2]; int onWindow, offWindow, i; char moveString[20]; if (theEvent->data.mouse.click == 2) { return self; } offset = theEvent->location; [self convertPoint:&offset fromView:nil]; si = offset.x / SQUARESIZE; sj = offset.y / SQUARESIZE; pieceBitmap = NULL; wFrame.origin.x = si * SQUARESIZE; wFrame.origin.y = sj * SQUARESIZE; if (isFlipped) { si = 7 - si; sj = 7 - sj; } if (squares[si][sj] != EMPTY) pieceBitmap = [Bitmap findBitmapFor:pieceNames[squares[si][sj]]]; thePiece = squares[si][sj]; squares[si][sj] = EMPTY; [self display]; [window getFrame:&myWindowFrame]; wFrame.size.width = wFrame.size.height = SQUARESIZE; [self convertRect:&wFrame toView:nil]; wFrame.origin.x += myWindowFrame.origin.x; wFrame.origin.y += myWindowFrame.origin.y; for (i=0;i<2;i++) { theWindow[i] = [Window newContent:&wFrame style:NX_PLAINSTYLE backing:NX_NONRETAINED buttonMask:0 defer: NO]; [theWindow[i] _setWindowLevel:9]; [theWindow[i] setFreeWhenClosed:NO]; [[theWindow[i] contentView] setFlip:YES]; [[theWindow[i] contentView] lockFocus]; PSsetautofill(NO, [theWindow[i] windowNum]); [[theWindow[i] contentView] unlockFocus]; } [theWindow[0] orderFront:self]; [[theWindow[0] contentView] lockFocus]; [pieceBitmap composite:NX_SOVER toPoint:&zerozero]; [[theWindow[0] contentView] unlockFocus]; onWindow = 0; offWindow = 1; oldMask = [window addToEventMask:NX_MOUSEUPMASK | NX_MOUSEDRAGGEDMASK]; while (1) { theEvent = [NXApp getNextEvent:NX_MOUSEUPMASK | NX_MOUSEDRAGGEDMASK]; newoffset = theEvent->location; [self convertPoint:&newoffset fromView:nil]; [theWindow[offWindow] moveTo:wFrame.origin.x + (newoffset.x - offset.x) :wFrame.origin.y + (newoffset.y - offset.y)]; PSorderwindow(NX_OUT, 0, [theWindow[onWindow] windowNum]); PSorderwindow(NX_ABOVE, 0, [theWindow[offWindow] windowNum]); [[theWindow[offWindow] contentView] lockFocus]; [pieceBitmap composite:NX_SOVER toPoint:&zerozero]; [[theWindow[offWindow] contentView] unlockFocus]; i = onWindow; onWindow = offWindow; offWindow = i; if (theEvent->type == NX_MOUSEUP) break; } for (i=0;i<2;i++) { [theWindow[i] orderOut:self]; [theWindow[i] free]; } [window setEventMask:oldMask]; offset = theEvent->location; [self convertPoint:&offset fromView:nil]; ei = offset.x / SQUARESIZE; ej = offset.y / SQUARESIZE; if (isFlipped) { ei = 7 - ei; ej = 7 - ej; } squares[ei][ej] = thePiece; [self display]; if ((ei == si) && (ej == sj)) return self; /* Same square! */ if ((ei < 0) || (ei > 7) || (ej < 0) || (ej > 7)) return self; /* Off the board */ if ((si == 4) && (ei == 2) && ((squares[si][sj] == WHITE_KING) || (squares[si][sj] == BLACK_KING))) { /* Castle queen side */ strcpy( moveString, "o-o-o\n" ); } else if ((si == 4) && (ei == 6) && ((squares[si][sj] == WHITE_KING) || (squares[si][sj] == BLACK_KING))) { /* Castle king side */ strcpy( moveString, "o-o\n" ); } else sprintf( moveString, "%c%0d-%c%0d\n", si+'a', sj+1, ei+'a', ej+1 ); WriteChars( moveString, strlen(moveString) ); lastX = ei; lastY = ej; return self; } - blinkLast:sender { int piece; if (lastX < 0) return self; piece = squares[lastX][lastY]; squares[lastX][lastY] = EMPTY; [self display]; NXPing(); [window flushWindow]; squares[lastX][lastY] = piece; [self display]; NXPing(); [window flushWindow]; return self; } - stopClock { if (clockEntry) DPSRemoveTimedEntry(clockEntry); clockEntry = NULL; return self; } - clockTick { int min, sec; char tstring[20]; if (who == WHITE) strcpy( tstring, [whiteTime stringValue] ); else strcpy( tstring, [blackTime stringValue] ); sscanf( tstring, "%d:%d", &min, &sec ); if (sec == 0) { min--; sec = 59; } else sec--; sprintf(tstring, "%d:%02d", min, sec); if ((min == 0) && (sec == 0)) [self stopClock]; if (who == WHITE) [whiteTime setStringValue:tstring]; else [blackTime setStringValue:tstring]; return self; } void clockTick( DPSTimedEntry teNumber, double now, id self ) { [self clockTick]; } - startClock { [self stopClock]; clockEntry = DPSAddTimedEntry(1.0, (DPSTimedEntryProc)clockTick, self, NX_MODALRESPTHRESHOLD); return self; } - maybeDisplay { if ([self isAutodisplay]) [self display]; else [self setNeedsDisplay:YES]; return self; } void SwitchPosition(id view1, id view2) { NXRect f1, f2; [view1 getFrame:&f1]; [view2 getFrame:&f2]; [view1 setFrame:&f2]; [view2 setFrame:&f1]; [view1 display]; [view2 display]; } - flipBoard:sender { [window disableFlushWindow]; isFlipped = !isFlipped; [self maybeDisplay]; SwitchPosition( whiteName, blackName ); SwitchPosition( whiteTime, blackTime ); SwitchPosition( whiteStrength, blackStrength ); [[window reenableFlushWindow] flushWindow]; return self; } - (BOOL)isFlipped { return isFlipped; } - parseBoard:(char *)line { int i,j; int k; int piece; char templine[1024]; int tmpint; [window disableFlushWindow]; k = 40; for (j=0;j<8;j++) for (i=0;i<8;i++) { switch(line[k]) { case 'p': piece = BLACK_PAWN; break; case 'r': piece = BLACK_ROOK; break; case 'n': piece = BLACK_KNIGHT; break; case 'b': piece = BLACK_BISHOP; break; case 'q': piece = BLACK_QUEEN; break; case 'k': piece = BLACK_KING; break; case 'P': piece = WHITE_PAWN; break; case 'R': piece = WHITE_ROOK; break; case 'N': piece = WHITE_KNIGHT; break; case 'B': piece = WHITE_BISHOP; break; case 'Q': piece = WHITE_QUEEN; break; case 'K': piece = WHITE_KING; break; case ' ': piece = EMPTY; break; default: fprintf( stderr, "Problem parsing board string\n" ); return self; } squares[i][j] = piece; k++; } strncpy(templine, &line[104], 3); templine[3] = '\0'; sscanf(templine, "%d", &tmpint); sprintf( templine, "%d", tmpint ); [moveNumber setStringValue:templine]; if (line[107] == WHITE) { who = WHITE; [toMove setStringValue:"White To Move"]; } else { who = BLACK; [toMove setStringValue:"Black To Move"]; } strncpy(templine, &line[112], 5); templine[5] = '\0'; sscanf(templine, "%d", &tmpint); sprintf(templine, "%d:%02d", tmpint/60, tmpint % 60); [whiteTime setStringValue:templine]; if ((who == WHITE) && (tmpint != 0)) [self startClock]; strncpy(templine, &line[117], 5); templine[5] = '\0'; sscanf(templine, "%d", &tmpint); sprintf(templine, "%d:%02d", tmpint/60, tmpint % 60); [blackTime setStringValue:templine]; if ((who == BLACK) && (tmpint != 0)) [self startClock]; for (i=0;line[6+i] != ' ';i++) templine[i] = line[6+i]; templine[i] = '\0'; [whiteName setStringValue:templine]; for (i=0;line[23+i] != ' ';i++) templine[i] = line[23+i]; templine[i] = '\0'; [blackName setStringValue:templine]; strncpy(templine, &line[108], 2); templine[2] = '\0'; sscanf(templine, "%d", &tmpint); sprintf( templine, "%d", tmpint ); [whiteStrength setStringValue:templine]; strncpy(templine, &line[110], 2); templine[2] = '\0'; sscanf(templine, "%d", &tmpint); sprintf( templine, "%d", tmpint ); [blackStrength setStringValue:templine]; for (i=0;line[122+i] != '@';i++) templine[i] = line[122+i]; templine[i] = '\0'; [lastMove setStringValue:templine]; if (!strcmp(templine, "o-o" ) ) { lastX = 6; if (who == BLACK) lastY = 0; else lastY = 7; } else if (!strcmp(templine, "o-o-o" ) ) { lastX = 2; if (who == BLACK) lastY = 0; else lastY = 7; } else { lastX = templine[5]-'a'; lastY = templine[6]-'1'; } strncpy(templine, &line[3], 3); templine[3] = '\0'; sscanf(templine, "%d", &tmpint); sprintf( templine, "%d", tmpint ); [gameNumber setStringValue:templine]; [self maybeDisplay]; [[window reenableFlushWindow] flushWindow]; return self; } - drawSelf:(NXRect *)rects : (int)count { int i,j; NXPoint ll; for (i=0;i<8;i++) for (j=0;j<8;j++) { ll.x = i * SQUARESIZE; ll.y = j * SQUARESIZE; if ((j+i) & 0x1) PSsetgray(NX_WHITE); else PSsetgray(NX_DKGRAY); PSrectfill(ll.x, ll.y, SQUARESIZE, SQUARESIZE); } for (i=0;i<8;i++) for (j=0;j<8;j++) { if (isFlipped) { ll.x = (7-i) * SQUARESIZE; ll.y = (6-j) * SQUARESIZE; } else { ll.x = i * SQUARESIZE; ll.y = j * SQUARESIZE; } if (squares[i][j] != EMPTY) { [[Bitmap findBitmapFor:pieceNames[squares[i][j]]] composite:NX_SOVER toPoint:&ll]; } } return self; } - initBoard { int i,j; for (i=0;i<8;i++) for (j=0;j<8;j++) squares[i][j] = EMPTY; for (i=0;i<8;i++) squares[i][1] = WHITE_PAWN; squares[0][0] = squares[7][0] = WHITE_ROOK; squares[1][0] = squares[6][0] = WHITE_KNIGHT; squares[2][0] = squares[5][0] = WHITE_BISHOP; squares[3][0] = WHITE_QUEEN; squares[4][0] = WHITE_KING; for (i=0;i<8;i++) squares[i][6] = BLACK_PAWN; squares[0][7] = squares[7][7] = BLACK_ROOK; squares[1][7] = squares[6][7] = BLACK_KNIGHT; squares[2][7] = squares[5][7] = BLACK_BISHOP; squares[3][7] = BLACK_QUEEN; squares[4][7] = BLACK_KING; [self maybeDisplay]; return self; } - setBoard:(int **)newb { int i,j; for (i=0;i<8;i++) for (j=0;j<8;j++) squares[i][j] = newb[i][j]; [self maybeDisplay]; return self; } - setDelegate:anObject { delegate = anObject; return self; } - appDidInit:sender { [window makeKeyAndOrderFront:self]; [window makeFirstResponder:self]; return self; } @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.