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.