home *** CD-ROM | disk | FTP | other *** search
Text File | 1996-04-11 | 40.8 KB | 1,720 lines | [TEXT/MMCC] |
- // game.c
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
-
- #include "mytypes.h"
- #include "error.h"
-
- #include "globals.h"
- #include "menus.h"
- #include "window.h"
- #include "main.h"
- #include "util.h"
- #include "preffile.h"
- #include "connexions.h"
- #include "fastmap.h"
- #include "graphics.h"
- #include "game.h"
- #include "incoming.h"
-
- #include "outgoing.h"
-
- #define optionkey 0x3A
-
- unsigned char km[16];
- Game *gGames = nil;
-
-
- enum {
- kNoMove = 0,
- kMove,
- kBugMove,
- kSetupMove
- };
-
- Game *gDragGame = nil;
- short gClickType = kNoMove, gOldPiece;
- Point gOrigPoint, gDestPoint;
-
- static Rect dirty = {0,0,0,0};
- static short offx, offy;
-
-
- Board initialPosition = { // this is actually wrong, but it never really gets used . . .
- { WhiteRook, WhiteKnight, WhiteBishop, WhiteQueen,
- WhiteKing, WhiteBishop, WhiteKnight, WhiteRook },
- { WhitePawn, WhitePawn, WhitePawn, WhitePawn,
- WhitePawn, WhitePawn, WhitePawn, WhitePawn },
- { empty, empty, empty, empty,
- empty, empty, empty, empty },
- { empty, empty, empty, empty,
- empty, empty, empty, empty },
- { empty, empty, empty, empty,
- empty, empty, empty, empty },
- { empty, empty, empty, empty,
- empty, empty, empty, empty },
- { BlackPawn, BlackPawn, BlackPawn, BlackPawn,
- BlackPawn, BlackPawn, BlackPawn, BlackPawn },
- { BlackRook, BlackKnight, BlackBishop, BlackQueen,
- BlackKing, BlackBishop, BlackKnight, BlackRook }
- };
-
- static short
- Piece2Player(short pc)
- {
- if (!pc)
- return -1;
- else if (pc <= WhiteKing)
- return kWhite;
- else
- return kBlack;
- }
-
- void
- InitGame(void)
- {
- gPlaying = false;
- curTime = TickCount();
- LoadAllGraphics();
- }
-
- void
- DrawGameWindow(void)
- {
- // SetGWorld(gameWindow, maindev);
- // CopyBits ((BitMap *) *(boff->portPixMap), (BitMap *) *(gameWindow->portPixMap),
- // &screenRect, &screenRect, srcCopy, nil);
- }
-
- void
- DisposeGame(Game *game)
- {
- if (game->isFirst)
- gPrefs.gameWindPos1 = GetWindowRect((WindowPtr) game->wind);
- if (game->isSecond)
- gPrefs.gameWindPos2 = GetWindowRect((WindowPtr) game->wind);
- DisposeWindow((WindowPtr) game->wind);
- DisposPtr((Ptr) game);
- }
-
-
- #if TIMESTAMP
- void init_encrypt();
- void init_process_chars_from_server(void);
- void send_alarm(void);
-
- #include "timeseal.h"
-
- #endif
-
- void
- StartPlaying(void)
- {
-
- #if TIMESTAMP
- if (gPrefs.serverType == kIcc && gPrefs.timeseal) {
- init_encrypt();
- init_process_chars_from_server();
- }
- if (gPrefs.serverType == kFics && gPrefs.timeseal) {
- InitTimeseal();
- }
- gSentAlarm = false;
- #endif
-
- gPlaying = true;
- gSetStyle = false;
- gNeedPassword = true;
- gCaughtPrompt = false;
- gWillSetup = false;
- gLookinAtStorage = false;
- gCheckingVersion = 0;
- strcpy(gPrompt, "fics% ");
- if (gPrefs.serverType == kIcc) {
- gPrompt[0] = 'a';
- gCaughtPrompt = true;
- }
- }
-
- void
- StopPlaying(void)
- {
- if (gPlaying) {
- gPlaying = false;
-
- // clean up all games
- Game *game = gGames, *nx;
- while (game) {
- nx = game->next;
- DisposeGame(game);
- game = nx;
- }
- gGames = nil;
- }
- }
-
- Game *
- FindGameFromWindow(WindowPtr win)
- {
- Game *game = gGames;
- while (game) {
- if (game->wind == (CWindowPtr) win)
- return game;
- game = game->next;
- }
- return nil;
- }
-
- void
- DoFlip(void)
- {
- Game *game = FindGameFromWindow(FrontWindow());
-
- if (!game)
- return;
-
- game->flip = !game->flip;
- DrawGame(game);
- }
-
- void
- DoEscapeKey(void)
- {
- if (gClickType == kNoMove)
- return;
- if (gClickType == kMove || gClickType == kSetupMove)
- gDragGame->board[gOrigPoint.h][gOrigPoint.v] = gOldPiece;
- gDragGame->tempDest.h = -1;
- DrawGameBoard(gDragGame);
- gClickType = kNoMove;
- ShowCursor();
- }
-
- void
- CloseGameWindow(WindowPtr win)
- {
- Game *game = FindGameFromWindow(win);
- if (game) {
- // check to see if we're dragging here
- if (game == gDragGame && gClickType != kNoMove) {
- gClickType = kNoMove;
- ShowCursor();
- }
-
- if (gGames == game)
- gGames = game->next;
- if (game->next)
- game->next->prev = game->prev;
- if (game->prev)
- game->prev->next = game->next;
- // let's tell the server if we're meant to
- if (gPrefs.smartClose && game->jexiste && game->number > 0) {
- if (game->relation == RELATION_OBSERVING_PLAYED)
- bprintf("unobserve %d\n", game->number);
- else if (game->relation == RELATION_EXAMINING)
- bprintf("unexamine\n");
- }
- DisposeGame(game);
- }
- }
-
- void
- SetGameWindowSize(Game *game, short delta)
- {
- short newh, newv;
- CWindowPtr win = game->wind;
- SetGWorld(win, maindev);
-
- newh = win->portRect.right + delta;
- newv = win->portRect.bottom + delta;
- SizeWindow((WindowPtr) win, newh, newv, false);
-
- InvalRect(&win->portRect);
-
- game->p2OffsetY += delta;
- game->boardRect.right += delta;
- game->boardRect.bottom += delta;
-
- game->sqsize = game->boardRect.right / 8;
-
- if (game->isFirst)
- gPrefs.boardSize1 = game->boardRect.right;
- if (game->isSecond)
- gPrefs.boardSize2 = game->boardRect.right;
-
- // move buttons
- short nnn;
- for (nnn=0; nnn<kNumGameControls; nnn++)
- if (game->ctl[nnn])
- MoveControl(game->ctl[nnn], (**game->ctl[nnn]).contrlRect.left,
- (**game->ctl[nnn]).contrlRect.top + delta);
- }
-
- void
- GrowGameWindow(CWindowPtr win, Point pt)
- {
- Game *game = FindGameFromWindow((WindowPtr) win);
- if (!game)
- return;
-
- Rect sr = { kWinHeight - kSquareSize * 4, kSquareSize * 4, kWinHeight + kSquareSize * 56, kSquareSize * 64 };
- if (game->footer) OffsetRect(&sr, 0, kFooterSize);
- if (game->bug || game->setup) OffsetRect(&sr, kBugspace, 0);
- short oldh, oldv, dh, dv, newh, newv;
-
- SetPort((WindowPtr) win);
-
- // remember current size
- oldh = win->portRect.right; oldv = win->portRect.bottom;
-
- // do the green thumb shit
- long ret = GrowWindow((WindowPtr) win, pt, &sr);
-
- if (!ret) // no grow
- return;
-
- newh = LoWord(ret); newv = HiWord(ret);
- dh = newh - oldh; dv = newv - oldv;
- // must keep square -- pick shortest
- short delta = dh;
- if (dv < dh) delta = dv;
- delta -= delta % 8; // keep aligned
-
- if (delta == 0)
- return;
-
- SetGameWindowSize(game, delta);
- }
-
- static Fastmap *
- Piece2Fastmap(short pc)
- {
- if (!pc)
- return nil;
-
- short offs = gPrefs.pieceSet * 2;
-
- if (pc <= WhiteKing)
- return bpix[Bwhite+offs][pc-1];
- if (pc <= BlackKing)
- return bpix[Bblack+offs][pc-WhiteKing-1];
-
- return nil;
- }
-
- static void
- DrawMyGrow(Game *game)
- {
- /* Rect r = {y - 8, x-8, y, x};
- FrameRect(&r);
- RGBColor col = {0xC000,0xC000,0xC000};
- RGBColor ccol = {0x8000,0x8000,0x8000};
- RGBForeColor(&col);
- PaintRect(&r);
- InsetRect(&r, 3, 3);
- RGBForeColor(&ccol);
- PaintRect(&r);
- RGBForeColor(&rgbBlack);
- */
- // return;
- short x = game->wind->portRect.right;
- short y = game->wind->portRect.bottom;
- Rect gr = {0, 0, y, x};
- gr.left = gr.right - 15;
- gr.top = gr.bottom - 15;
- ClipRect(&gr);
- DrawGrowIcon((WindowPtr) game->wind);
- SetRect(&gr, 0, 0, 32000, 32000);
- ClipRect(&gr);
-
- }
-
- static void
- DrawBoard(Board board, Game *game)
- {
- short x, y;
- Rect r;
- Fastmap *fm;
-
- for (x=0;x<8;x++)
- for (y=0;y<8;y++) {
- if (game->flip)
- r.left = (7-x) * kSquareSize;
- else
- r.left = x * kSquareSize;
- r.right = r.left + kSquareSize;
- if (game->flip)
- r.top = y * kSquareSize;
- else
- r.top = (7-y) * kSquareSize;
- r.bottom = r.top + kSquareSize;
- if (!((x + y) & 1))
- RGBForeColor(&gPrefs.colBlack);
- else
- RGBForeColor(&gPrefs.colWhite);
- PaintRect(&r);
- if (x == game->tempDest.h && y == game->tempDest.v) {
- // draw an X where we're trying to go
- InsetRect(&r, 4, 4);
- RGBColor col = {0xA000, 0, 0};
- RGBForeColor(&col);
- MoveTo(r.left, r.top);
- LineTo(r.right, r.bottom);
- MoveTo(r.right, r.top);
- LineTo(r.left, r.bottom);
- InsetRect(&r, -4, -4);
- }
- RGBForeColor(&rgbBlack);
- fm = Piece2Fastmap(board[x][y]);
- if (fm)
- fm->DrawMask(boff, &r);
- }
- }
-
- void
- DrawGameBoard(Game *game)
- {
- SetGWorld(boff, nil);
- DrawBoard(game->board, game);
- SetGWorld(game->wind, maindev);
- Rect r = //boffrect;
- //OffsetRect(&r, 0, game->bOffsetY);
- game->boardRect;
- CopyBits ((BitMap *) *(boff->portPixMap), (BitMap *) *(game->wind->portPixMap),
- &boffrect, &r, srcCopy, nil);
- }
-
- static void
- DrawStatSet(Game *game, short plr)
- {
- short len;
- char buf[64];
- Rect r = boffrect;
- r.bottom = kStatY;
-
- RGBColor col = {0xC000,0xC000,0xC000};
- RGBColor colW = {0xF000,0xF000,0xF000};
- RGBColor colB = {0x5000,0x5000,0x5000};
- RGBColor ccol = {0xB000,0x1000,0x1000};
- SetGWorld(boff, nil);
- TextSize(12);
- TextFont(0);
- RGBForeColor(&col);
- PaintRect(&r);
- // draw stuff if we're the current player
- if (game->turn == plr && !gPrefs.minimal) {
- RGBForeColor(&ccol);
- r.bottom = 3;
- PaintRect(&r);
- r.top = kStatY - 3; r.bottom = kStatY;
- PaintRect(&r);
- r.top = 0;
- }
- RGBForeColor(&rgbBlack);
-
- // draw strength
- len = sprintf(buf, "%d", game->strength[plr]);
- MoveTo(4, 16);
- DrawText(buf, 0, len);
-
- // draw a circle if we're the current player
- if (game->turn == plr) {
- RGBForeColor(&ccol);
- short rad = 5;
- Rect rec = {kStatY/2 - rad, 27 - rad, kStatY/2 + rad, 27 + rad};
- PaintOval(&rec);
- RGBForeColor(&rgbBlack);
- }
-
- // draw time in a box
- // draw time
- long tm = game->ptime[plr];
- len = sprintf(buf, "%c%d:%02d", tm < 0 ? '-' : ' ',
- abs(tm) / 60, abs(tm) % 60);
- short plen = TextWidth(buf, 0, len);
-
- Rect rr = {4, 37, 20, 37 + plen + 8};
- if (plr == kWhite) {
- RGBForeColor(&colW);
- PaintRoundRect(&rr, 10, 10);
- RGBForeColor(&rgbBlack);
- }
- else {
- RGBForeColor(&colB);
- PaintRoundRect(&rr, 10, 10);
- RGBForeColor(&colW);
- }
- MoveTo(rr.left + 4, 16);
- DrawText(buf, 0, len);
- RGBForeColor(&rgbBlack);
-
- // draw their last move
- MoveTo(rr.right + 4, 16);
- DrawText(game->lmove[plr], 0, strlen(game->lmove[plr]));
-
- TextSize(10);
- TextFont(geneva);
-
- // draw name
- Move(4, 0);
- DrawText(game->name[plr], 0, strlen(game->name[plr]));
- }
-
- /*
- static void
- DrawStatSet(Game *game, short plr)
- {
- short len;
- char buf[64];
- Rect r = boffrect;
- r.bottom = kStatY;
-
- RGBColor col = {0xC000,0xC000,0xC000};
- RGBColor colW = {0xF000,0xF000,0xF000};
- RGBColor colB = {0x5000,0x5000,0x5000};
- RGBColor ccol = {0xB000,0x1000,0x1000};
- SetGWorld(boff, nil);
- RGBForeColor(&col);
- PaintRect(&r);
- // draw stuff if we're the current player
- if (game->turn == plr && !gPrefs.minimal) {
- RGBForeColor(&ccol);
- r.bottom = 3;
- PaintRect(&r);
- r.top = kStatY - 3; r.bottom = kStatY;
- PaintRect(&r);
- r.top = 0;
- }
- RGBForeColor(&rgbBlack);
-
- // draw name
- Rect rr = {4, 37, 20, 37};
- if (plr == kWhite) {
- rr.right += StringWidth("\pWhite: ") + 2;
- RGBForeColor(&colW);
- PaintRoundRect(&rr, 10, 10);
- RGBForeColor(&rgbBlack);
- MoveTo(rr.left + 3, 16);
- DrawString("\pWhite: ");
- }
- else {
- rr.right += StringWidth("\pBlack: ") + 2;
- RGBForeColor(&colB);
- PaintRoundRect(&rr, 10, 10);
- RGBForeColor(&colW);
- MoveTo(rr.left + 3, 16);
- DrawString("\pBlack: ");
- RGBForeColor(&rgbBlack);
- }
- Move(4, 0);
- DrawText(game->name[plr], 0, strlen(game->name[plr]));
-
- // draw a circle if we're the current player
- if (game->turn == plr) {
- RGBForeColor(&ccol);
- short rad = 5;
- Rect rec = {kStatY/2 - rad, 27 - rad, kStatY/2 + rad, 27 + rad};
- PaintOval(&rec);
- RGBForeColor(&rgbBlack);
- }
-
- len = sprintf(buf, "%d", game->strength[plr]);
- MoveTo(4, 16);
- DrawText(buf, 0, len);
-
- // draw their last move
- MoveTo(192, 16);
- DrawText(game->lmove[plr], 0, strlen(game->lmove[plr]));
-
- // draw time
- long tm = game->ptime[plr];
- len = sprintf(buf, "%c%d:%02d", tm < 0 ? '-' : ' ',
- abs(tm) / 60, abs(tm) % 60);
- MoveTo(150, 16);
- DrawText(buf, 0, len);
- }
- */
- void
- DrawGameStats(Game *game)
- {
- Rect r = boffrect;
- r.bottom = kStatY;
- Rect s;
-
- DrawStatSet(game, !game->flip);
- MoveTo(0, kStatY-1);
- Line(kBoardSize, 0);
- MoveTo(0, 0);
- Line(kBoardSize, 0);
- s = r; OffsetRect(&s, 0, game->p1OffsetY);
- SetGWorld(game->wind, maindev);
- CopyBits ((BitMap *) *(boff->portPixMap), (BitMap *) *(game->wind->portPixMap),
- &r, &s, srcCopy, nil);
-
-
- DrawStatSet(game, game->flip);
- MoveTo(0, kStatY-1);
- Line(kBoardSize, 0);
- MoveTo(0, 0);
- Line(kBoardSize, 0);
- SetGWorld(game->wind, maindev);
- // sometimes we have to fit grow box here -- make space for it
- if (!game->bug && !game->setup && !game->footer)
- if (game->boardRect.right < kBoardSize + 16) {
- RGBColor colB = {0x3000,0x3000,0x3000};
- RGBForeColor(&colB);
- Rect s = r; OffsetRect(&s, 0, game->p2OffsetY);
- s.left = kBoardSize - 16; s.right = game->wind->portRect.right;
- s.right -= 15;
- PaintRect(&s);
- s.right += 15;
- s.bottom -= 15;
- PaintRect(&s);
- RGBForeColor(&rgbBlack);
-
- r.right -= 16;
- }
- s = r; OffsetRect(&s, 0, game->p2OffsetY);
- CopyBits ((BitMap *) *(boff->portPixMap), (BitMap *) *(game->wind->portPixMap),
- &r, &s, srcCopy, nil);
- }
-
- void
- DrawGameHeader(Game *game)
- {
- Rect r = boffrect;
- r.bottom = kHeader;
- char buf[32];
- short len;
-
- SetGWorld(boff, nil);
- RGBColor colB = {0x3000,0x3000,0x3000};
- RGBColor colW = {0xE000,0xE000,0xE000};
- RGBForeColor(&colB);
- PaintRect(&r);
- RGBForeColor(&colW);
- // MoveTo(0, plr == kWhite ? 0 : kStatY-1);
- // Line(kBoardSize, 0);
-
- // PenMode(srcBic);
-
- MoveTo(8, 11);
- /* DrawString("\pMove ");
- short len = sprintf(buf, "%d", game->officialMove);
- DrawText(buf, 0, len); */
- len = sprintf(buf, "Mins: %ld Inc: %ld", game->gameMins, game->gameInc);
- DrawText(buf, 0, len);
-
- if (game->elapsed[0]) {
- Move(8, 0);
- DrawText(game->elapsed, 0, strlen(game->elapsed));
- }
-
- Move(8, 0);
- if (!game->endReason[0]) {
- if ((game->relation == RELATION_OBSERVING_PLAYED) ||
- (game->relation == RELATION_PLAYING_MYMOVE) ||
- (game->relation == RELATION_PLAYING_NOTMYMOVE)) {
- len = sprintf(buf, "-> %d:%02d <-", (short) (game->thinking / 60), (short) (game->thinking % 60));
- DrawText(buf, 0, len);
- }
- }
- else
- DrawText(game->endReason, 0, strlen(game->endReason));
-
- // PenNormal();
- RGBForeColor(&rgbBlack);
-
- SetGWorld(game->wind, maindev);
- CopyBits ((BitMap *) *(boff->portPixMap), (BitMap *) *(game->wind->portPixMap),
- &r, &r, srcCopy, nil);
- }
-
- static void
- DrawGameFooter(Game *game)
- {
- Rect r = boffrect;
- r.bottom = kFooterSize;
-
- SetGWorld(boff, nil);
- RGBColor colB = {0x3000,0x3000,0x3000};
- RGBColor colW = {0xE000,0xE000,0xE000};
- RGBForeColor(&colB);
- PaintRect(&r);
- // RGBForeColor(&colW);
-
- RGBForeColor(&rgbBlack);
-
- SetGWorld(game->wind, maindev);
- // sometimes we have to fit grow box here -- make space for it
- Rect dest = r;
- OffsetRect(&dest, 0, game->p2OffsetY + kStatY);
- if (!game->bug && game->boardRect.right < kBoardSize + 16) {
- RGBColor colB = {0x3000,0x3000,0x3000};
- RGBForeColor(&colB);
- Rect s = dest;
- s.left = kBoardSize - 16; s.right = game->wind->portRect.right;
- s.right -= 15;
- PaintRect(&s);
- s.right += 15;
- s.bottom -= 15;
- PaintRect(&s);
-
- RGBForeColor(&rgbBlack);
- r.right -= 16;
- }
- CopyBits ((BitMap *) *(boff->portPixMap), (BitMap *) *(game->wind->portPixMap),
- &r, &dest, srcCopy, nil);
-
- DrawControls((WindowPtr) game->wind);
- }
-
- // just copy the pictures in
- static void
- DrawBugSet(Game *game, short plr)
- {
- Fastmap *fm, **find;
- Rect r = {0, 0, kSquareSize * 5, kSquareSize};
-
- SetGWorld(boff, nil);
- RGBForeColor(&bugcol);
- PaintRect(&r);
- RGBForeColor(&rgbBlack);
-
- // draw pieces
- find = bpix[(plr == kWhite ? Bwhite : Bblack) + gPrefs.pieceSet * 2];
- short i;
- for (i=0;i<5;i++) {
- Rect s = {i*kSquareSize, 0, (i+1) * kSquareSize, kSquareSize};
- fm = find[i];
- fm->DrawMask(boff, &s);
- }
- }
-
- void
- DrawBughouse(Game *game)
- {
- Rect src = {0, 0, kSquareSize * 5, kSquareSize};
- Rect dest = {0, game->boardRect.right + kBugspace - kBugsize,
- kBugY, game->boardRect.right + kBugspace};
-
- DrawBugSet(game, !game->flip);
- SetGWorld(game->wind, maindev);
- CopyBits ((BitMap *) *(boff->portPixMap), (BitMap *) *(game->wind->portPixMap),
- &src, &dest, srcCopy, nil);
-
-
- DrawBugSet(game, game->flip);
- SetGWorld(game->wind, maindev);
- OffsetRect(&dest, 0, kBugY + kBugPadding);
- CopyBits ((BitMap *) *(boff->portPixMap), (BitMap *) *(game->wind->portPixMap),
- &src, &dest, srcCopy, nil);
-
- // extra stuff
- Rect r = {kBugY, game->boardRect.right, kBugY + kBugPadding, game->boardRect.right + kBugspace};
- RGBForeColor(&bugcol);
- PaintRect(&r);
-
- r.top = kBugY * 2 + kBugPadding; r.bottom = game->wind->portRect.bottom;
-
- PaintRect(&r);
-
- RGBForeColor(&rgbBlack);
- MoveTo(game->boardRect.right, 0);
- Line(0, game->wind->portRect.bottom);
-
- DrawMyGrow(game);
- }
-
- static void
- DrawReserveSet(Game *game, short plr)
- {
- Rect r = {0, 0, kBugY, kBugspace - kBugsize};
-
- SetGWorld(boff, nil);
- RGBForeColor(&bugcol);
- PaintRect(&r);
- RGBForeColor(&rgbBlack);
- MoveTo(0, 0);
- Line(0, kBugY);
-
- TextSize(12);
- TextFont(0);
-
- short nnn;
- for (nnn=0;nnn<5;nnn++)
- if (game->reserves[plr][nnn]) {
- MoveTo(4, nnn * kBugsize + kBugsize / 2 + 6);
- DrawChar(game->reserves[plr][nnn] + '0'); // can't be more than 9
- }
-
- TextSize(10);
- TextFont(geneva);
- }
-
- void
- DrawReserves(Game *game) // text for numbers of pieces
- {
- Rect src = {0, 0, kBugY, kBugspace - kBugsize};
- Rect dest = {0, game->boardRect.right, kBugY, game->boardRect.right + kBugspace - kBugsize};
-
- DrawReserveSet(game, !game->flip);
- SetGWorld(game->wind, maindev);
- CopyBits ((BitMap *) *(boff->portPixMap), (BitMap *) *(game->wind->portPixMap),
- &src, &dest, srcCopy, nil);
-
- DrawReserveSet(game, game->flip);
- SetGWorld(game->wind, maindev);
- OffsetRect(&dest, 0, kBugY + kBugPadding);
- CopyBits ((BitMap *) *(boff->portPixMap), (BitMap *) *(game->wind->portPixMap),
- &src, &dest, srcCopy, nil);
- }
-
- void
- DrawGame(Game *game)
- {
- // gworlds should get set automatically
- DrawGameBoard(game);
- DrawGameStats(game);
- DrawGameHeader(game);
- if (game->bug) {
- DrawReserves(game);
- DrawBughouse(game);
- }
- if (game->footer)
- DrawGameFooter(game);
- if (game->footer && game->bug) {
- // fill in the corner
- /* Rect r = game->wind->portRect;
- r.left = kBoardSize;
- r.top = kWinHeight;
- RGBColor colB = {0x3000,0x3000,0x3000};
- RGBForeColor(&colB);
- PaintRect(&r);
- RGBForeColor(&rgbBlack);
- */
- }
- if (game->boardRect.right > kBoardSize) {
- // fill in some grey bits
- RGBColor colB = {0x3000,0x3000,0x3000};
- RGBForeColor(&colB);
- Rect r;
- r.right = game->boardRect.right;
- r.bottom = game->bOffsetY;
- r.top = 0;
- r.left = kBoardSize;
- PaintRect(&r);
- r.bottom = game->wind->portRect.bottom;
- r.top = game->boardRect.bottom;
- PaintRect(&r);
- RGBForeColor(&rgbBlack);
- }
- // draw grow icon
- DrawMyGrow(game);
- }
-
- void
- DrawGameWindow(WindowPtr win)
- {
- Game *game = FindGameFromWindow(win);
- if (game)
- DrawGame(game);
- }
-
- void
- MakeBughouse(Game *game)
- {
- if (game->bug)
- return;
-
- game->bug = true;
-
- // expand window
- short sx = game->boardRect.right + kBugspace, sy = game->wind->portRect.bottom;
- SizeWindow((WindowPtr) game->wind, sx, sy, false);
-
- DrawBughouse(game);
- }
-
- void
- RemoveBughouse(Game *game)
- {
- if (!game->bug)
- return;
-
- game->bug = false;
-
- // shrink window
- short sx = game->boardRect.right, sy = game->wind->portRect.bottom;
- SizeWindow((WindowPtr) game->wind, sx, sy, false);
- SetGWorld(game->wind, maindev);
- DrawMyGrow(game);
- }
-
- void
- MakeFooter(Game *game)
- {
- if (game->footer)
- return;
-
- game->footer = true;
-
- // expand window
- short sx = game->wind->portRect.right, sy = game->boardRect.bottom + kStatY + kFooterSize;
- SizeWindow((WindowPtr) game->wind, sx, sy, false);
- // add controls
- Rect bounds = {game->p2OffsetY + kStatY + 2, 24, game->p2OffsetY + kStatY + kFooterSize - 1, 56};
- game->ctl[ctlStart] = NewControl((WindowPtr) game->wind, &bounds, "\p|<<",
- true, 0, 0, 0, 0, ctlStart); verify(game->ctl[ctlStart]);
- OffsetRect(&bounds, 38, 0);
- game->ctl[ctlBack] = NewControl((WindowPtr) game->wind, &bounds, "\p<",
- true, 0, 0, 0, 0, ctlBack); verify(game->ctl[ctlBack]);
- OffsetRect(&bounds, 38, 0);
- game->ctl[ctlForward] = NewControl((WindowPtr) game->wind, &bounds, "\p>",
- true, 0, 0, 0, 0, ctlForward); verify(game->ctl[ctlForward]);
- OffsetRect(&bounds, 38, 0);
- game->ctl[ctlEnd] = NewControl((WindowPtr) game->wind, &bounds, "\p>>|",
- true, 0, 0, 0, 0, ctlEnd); verify(game->ctl[ctlEnd]);
- OffsetRect(&bounds, 44, 0); bounds.right += 20;
- game->ctl[ctlRevert] = NewControl((WindowPtr) game->wind, &bounds, "\pRevert",
- true, 0, 0, 0, 0, ctlRevert); verify(game->ctl[ctlRevert]);
-
- DrawGameFooter(game);
- DrawMyGrow(game);
- }
-
- Game *
- NewGame(char *p1, char *p2, short gameNum, Boolean flip)
- {
- Game *game = (Game *) NewPtr(sizeof(Game));
- verify(game);
-
- // sticky code to make windows pop up in nice places
- game->isFirst = true; game->isSecond = false;
- Game *gm = gGames;
- while (gm) {
- if (gm->isFirst)
- game->isFirst = false;
- gm = gm->next;
- }
- if (!game->isFirst) { // well, maybe we can be second then
- gm = gGames;
- if (gm) {
- game->isSecond = true;
- while (gm) {
- if (gm->isSecond)
- game->isSecond = false;
- gm = gm->next;
- }
- }
- }
-
- // make window
- // now set up game window
- gScratch[0] = sprintf((char *) &gScratch[1], "%d: %s vs %s", gameNum, p1, p2);
- Rect gameWindowBounds = {40, 4, 40 + kWinHeight, 4 + kBoardSize};
- if (game->isSecond)
- OffsetRect(&gameWindowBounds, kBoardSize + 16 + kBugspace, 0);
- game->wind = (CWindowPtr) NewCWindow(0L, &gameWindowBounds, gScratch, false, documentProc, (WindowPtr) -1L, true, 0);
- verify(game->wind);
- // remember location of window from last time
- if (game->isFirst && !EmptyRect(&gPrefs.gameWindPos1))
- MoveWindow((WindowPtr) game->wind, gPrefs.gameWindPos1.left, gPrefs.gameWindPos1.top, false);
- else if (game->isSecond && !EmptyRect(&gPrefs.gameWindPos2))
- MoveWindow((WindowPtr) game->wind, gPrefs.gameWindPos2.left, gPrefs.gameWindPos2.top, false);
- ShowWindow((WindowPtr) game->wind);
-
- strncpy(game->name[0], p1, 127); game->name[0][127] = 0;
- strncpy(game->name[1], p2, 127); game->name[1][127] = 0;
-
- memcpy(game->board, initialPosition, sizeof(Board));
-
- game->number = gameNum;
- game->origNumber = gameNum;
- game->jexiste = true;
- game->relation = RELATION_OBSERVING_PLAYED;
- game->gameMins = 0;
- game->gameInc = 0;
- game->elapsed[0] = 0;
-
- // bughouse stuff
- game->bug = false;
- short nnn, mmm;
- for (mmm=0;mmm<2;mmm++)
- for (nnn=0;nnn<5;nnn++)
- game->reserves[mmm][nnn] = 0;
-
- // examining stuff
- for (nnn=0;nnn<kNumGameControls;nnn++)
- game->ctl[nnn] = 0;
- game->footer = false;
- game->setup = false;
-
- game->turn = kWhite;
-
- game->ptime[0] = 0;
- game->ptime[1] = 0;
- game->thinking = 0;
-
- game->strength[0] = 0; game->strength[1] = 0;
-
- game->flip = flip;
-
- game->next = gGames;
- if (game->next)
- game->next->prev = game;
- game->prev = nil;
- gGames = game;
-
- game->lastMove[0][0] = -1; game->lastMove[0][1] = 0;
- game->lastMove[1][0] = 0; game->lastMove[1][1] = 0;
- game->tempDest.h = -1;
-
- game->p1OffsetY = kHeader;
- game->bOffsetY = kStatY + game->p1OffsetY;
- game->p2OffsetY = game->bOffsetY + kBoardSize;
- SetRect(&game->boardRect, 0, game->bOffsetY, kBoardSize, game->bOffsetY + kBoardSize);
- game->sqsize = 32;
-
- game->lmove[0][0] = 0;
- game->lmove[1][0] = 0;
- game->officialMove = 1;
-
- game->endReason[0] = 0;
-
- // check for default sizes
- if (game->isFirst && gPrefs.boardSize1 != game->boardRect.right)
- SetGameWindowSize(game, gPrefs.boardSize1 - game->boardRect.right);
- if (game->isSecond && gPrefs.boardSize2 != game->boardRect.right)
- SetGameWindowSize(game, gPrefs.boardSize2 - game->boardRect.right);
-
- return game;
- }
-
- // k = any keyboard scan code, 0-127
- static int isPressed(unsigned short k )
- {
- return ( ( km[k>>3] >> (k & 7) ) & 1);
- }
-
- static void
- ShowLastMove(void)
- {
- // draw a line where the last move occurred
- WindowPtr win = FrontWindow();
- if (!win)
- return;
- Game *game = FindGameFromWindow(win);
- if (!game)
- return;
- if (game->lastMove[0][0] < 0)
- return; // no move yet
-
- SetGWorld(game->wind, maindev);
-
- RGBColor col = {0xFFFF, 0, 0};
- RGBForeColor(&col);
- short siz = game->sqsize;
- PenSize(4, 4);
- if (game->lastMove[0][0] == game->lastMove[1][0] && game->lastMove[0][1] == game->lastMove[1][1])
- PenSize(8, 8); // make more clear in bughouse
- if (!game->flip) {
- MoveTo(game->lastMove[0][0] * siz + (siz >> 1) - 2, (7 - game->lastMove[0][1]) * siz + (siz >> 1) - 2 + game->bOffsetY);
- LineTo(game->lastMove[1][0] * siz + (siz >> 1) - 2, (7 - game->lastMove[1][1]) * siz + (siz >> 1) - 2 + game->bOffsetY);
- }
- else {
- MoveTo(((7-game->lastMove[0][0]) * siz + (siz >> 1) - 2), (game->lastMove[0][1]) * siz + (siz >> 1) - 2 + game->bOffsetY);
- LineTo(((7-game->lastMove[1][0]) * siz + (siz >> 1) - 2), (game->lastMove[1][1]) * siz + (siz >> 1) - 2 + game->bOffsetY);
- }
- while (isPressed(optionkey)) {GetKeys((UInt32 *) km);}
- PenNormal();
- RGBForeColor(&rgbBlack);
- DrawGameBoard(game);
- }
-
- static void
- CheckTimes(void)
- {
- ulong myTime = TickCount();
- Game *game = gGames;
- while (game) {
- if (game->jexiste && game->turn >= 0
- && game->relation != RELATION_EXAMINING
- && game->relation != RELATION_ISOLATED_BOARD
- && game->relation != RELATION_OBSERVING_STATIC) {
- ulong d = myTime - game->lTime;
- short ds = d / 60;
- if (ds > 0) {
- game->lTime += ds * 60;
- short ot = game->ptime[game->turn];
- game->ptime[game->turn] -= ds;
- short nt = game->ptime[game->turn];
- if (game->relation == RELATION_PLAYING_NOTMYMOVE &&
- gPrefs.autoFlag && ot > 0 && nt <= 0) {
- // let's flag their asses
- bprintf("flag\n");
- tprintf("(Flagging opponent.)\r");
- }
- #if TIMESTAMP
- // check time for timestamp
- if (!gSentAlarm && gPrefs.timeseal && gPrefs.serverType == kIcc &&
- game->relation == RELATION_PLAYING_MYMOVE &&
- nt < 0) {
- // let's tell server dudes
- send_alarm();
- gSentAlarm = true;
- }
- #endif
-
- // we also keep track of how long they've been thinking
- game->thinking += ds;
-
- DrawGameStats(game);
- DrawGameHeader(game);
- }
- }
- game = game->next;
- verify(game != gGames);
- }
- }
-
- static void DragPiece2(void);
-
- void
- GameIdle(void)
- {
- if (!gPlaying)
- return; // that would be bad
-
- curTime = TickCount();
- GetKeys((UInt32 *) km);
- if (isPressed(optionkey))
- ShowLastMove();
-
- // adjust time
- CheckTimes();
- DragPiece2();
- }
-
- static void
- Point2Square(Game *game, Point *pt)
- {
- pt->v -= game->bOffsetY;
-
- if (pt->v < 0) {
- pt->h = -2;
- return;
- }
- pt->h /= game->sqsize; pt->v /= game->sqsize;
- if (pt->h < 0 || pt->v < 0 || pt->h > 7 || pt->v > 7) {
- pt->h = -2;
- return; // out of range
- }
- if (!game->flip)
- pt->v = 7 - pt->v;
- else
- pt->h = 7 - pt->h;
- }
-
- static void
- DrawBoardSection(Game *game, Rect *r)
- {
- Rect rr = *r;
- rr.right++; rr.bottom++;
- if (rr.right % kSquareSize) rr.right += kSquareSize - rr.right % kSquareSize;
- if (rr.bottom % kSquareSize) rr.bottom += kSquareSize - rr.bottom % kSquareSize;
- if (rr.right > kBoardSize) rr.right = kBoardSize;
- if (rr.bottom > kBoardSize) rr.bottom = kBoardSize;
- rr.left -= rr.left % kSquareSize;
- rr.top -= rr.top % kSquareSize;
- Rect dest = rr;
- // offset due to scaling
- dest.left = (dest.left * game->sqsize) / kSquareSize;
- dest.top = (dest.top * game->sqsize) / kSquareSize;
- dest.right = (dest.right * game->sqsize) / kSquareSize;
- dest.bottom = (dest.bottom * game->sqsize) / kSquareSize;
- OffsetRect(&dest, game->boardRect.left, game->boardRect.top);
- CopyBits((BitMap *) *(boff->portPixMap), (BitMap *) *(game->wind->portPixMap),
- &rr, &dest, srcCopy, nil);
- }
-
- static Point
- DragPiece(Game *game, short pc, short offx, short offy, Point origin)
- {
- Fastmap *fm = Piece2Fastmap(pc);
- verify(fm);
-
- Point ms, sq;
- Boolean inSquare;
- short siz = game->sqsize;
-
- GetMouse(&ms); ms.v -= game->bOffsetY;
- HideCursor();
- Rect dirty = {0,0,0,0};
- if (origin.h >= 0) {
- if (!game->flip)
- dirty.left = origin.h * kSquareSize;
- else
- dirty.left = (7-origin.h) * kSquareSize;
- dirty.right = dirty.left + kSquareSize;
- if (!game->flip)
- dirty.top = (7 - origin.v) * kSquareSize;
- else
- dirty.top = origin.v * kSquareSize;
- dirty.bottom = dirty.top + kSquareSize;
- }
-
- do {
- CheckTimes();
-
- SetGWorld(boff, nil);
- DrawBoard(game->board, game);
-
- // draw the piece we're dragging
- SetGWorld(game->wind, maindev);
- GetMouse(&ms);
- ms.v -= offy + game->bOffsetY; ms.h -= offx;
- // find square we're in
- inSquare = false;
- sq = ms;
- sq.h += siz / 2;
- sq.v += siz / 2;
- if ((sq.h % siz > 4) && (sq.h % siz < siz - 4)
- && (sq.v % siz > 4) && (sq.v % siz < siz - 4)) {
- sq.v += game->bOffsetY; // ugly, silly, but heck
- Point2Square(game, &sq);
- inSquare = sq.h >= 0;
- }
- else {
- // some extra work to see if they dragged it completely off the board
- // in that case, we return -2 (for setup)
- sq.v += game->bOffsetY; // ugly, silly, but heck
- Point2Square(game, &sq);
- if (sq.h >= 0)
- sq.h = -1;
- }
-
- SetGWorld(boff, nil);
-
- // draw target
- Rect rr = {0,0,0,0};
- if (inSquare && !EqualPt(origin, sq)) {
- if (!game->flip)
- rr.left = sq.h * kSquareSize;
- else
- rr.left = (7-sq.h) * kSquareSize;
- rr.right = rr.left + kSquareSize;
- if (!game->flip)
- rr.top = (7 - sq.v) * kSquareSize;
- else
- rr.top = sq.v * kSquareSize;
- rr.bottom = rr.top + kSquareSize;
- InsetRect(&rr, 4, 4);
- RGBColor col = {0xFFFF, 0, 0};
- RGBForeColor(&col);
- MoveTo(rr.left, rr.top);
- LineTo(rr.right, rr.bottom);
- MoveTo(rr.right, rr.top);
- LineTo(rr.left, rr.bottom);
- RGBForeColor(&rgbBlack);
- rr.right++; rr.bottom++;
- if (dirty.right > 0 && dirty.bottom > 0)
- UnionRect(&rr, &dirty, &dirty);
- else
- dirty = rr; // first time through loop
- }
-
- // draw piece we're sliding around
- Rect rec = {0, 0, 32, 32};
- ms.h = (float) ms.h * 32.0 / (float) siz;
- ms.v = (float) ms.v * 32.0 / (float) siz;
- OffsetRect(&rec, ms.h, ms.v);
- fm->DrawMask(boff, &rec);
- if (dirty.right > 0 && dirty.bottom > 0)
- UnionRect(&rec, &dirty, &dirty);
- else
- dirty = rec;
-
- SetGWorld(game->wind, maindev);
- if (dirty.left < 0) dirty.left = 0;
- if (dirty.top < 0) dirty.top = 0;
- if (dirty.bottom > kBoardSize) dirty.bottom = kBoardSize;
- if (dirty.right > kBoardSize) dirty.right = kBoardSize;
- DrawBoardSection(game, &dirty);
- // Rect dest = dirty;
- // OffsetRect(&dest, game->boardRect.left, game->boardRect.top);
- // CopyBits((BitMap *) *(boff->portPixMap), (BitMap *) *(game->wind->portPixMap),
- // &boffrect, &game->boardRect, srcCopy, nil);
- // CopyBits((BitMap *) *(boff->portPixMap), (BitMap *) *(game->wind->portPixMap),
- // &dirty, &dest, srcCopy, nil);
-
- // prepare dirty for next loop
- dirty = rec;
- if (rr.right > 0)
- UnionRect(&rr, &dirty, &dirty);
- } while (Button());
-
- ShowCursor();
- return sq;
- }
-
- static char
- Piece2Char(short pc)
- {
- // black in capitals
- switch(pc) {
- case WhitePawn: return 'P'; case BlackPawn: return 'p';
- case WhiteKnight: return 'N'; case BlackKnight: return 'n';
- case WhiteBishop: return 'B'; case BlackBishop: return 'b';
- case WhiteRook: return 'R'; case BlackRook: return 'r';
- case WhiteQueen: return 'Q'; case BlackQueen: return 'q';
- case WhiteKing: return 'K'; case BlackKing: return 'k';
- default: return '?';
- }
- }
-
- static void
- HandleBugClick(Game *game, Point p)
- {
- short pc;
-
- short plr;
- if (p.v > kBugY + kBugPadding) {
- if (p.v > kBugY * 2 + kBugPadding)
- return;
- if (!game->flip) {
- pc = WhitePawn + (p.v - (kBugY + kBugPadding)) / kBugsize;
- plr = kWhite;
- }
- else {
- pc = BlackPawn + (p.v - (kBugY + kBugPadding)) / kBugsize;
- plr = kBlack;
- }
- }
- else if (p.v < kBugY) {
- if (!game->flip) {
- pc = BlackPawn + p.v / kBugsize;
- plr = kBlack;
- }
- else {
- pc = WhitePawn + p.v / kBugsize;
- plr = kWhite;
- }
- }
- else
- return;
-
- if (pc < WhitePawn || pc > BlackKing)
- return;
-
- if (Piece2Player(pc) != game->turn && !game->setup)
- return; // wrong color piece
-
- Point pt = {-1, -1};
- short offs;
- if (!game->flip)
- offs = plr == kWhite ? 16 : -16;
- else
- offs = plr == kBlack ? 16 : -16;
- Point dest = DragPiece(game, pc, kBugspace + 8, 16 + offs, pt);
-
- if (dest.h < 0) {
- DrawGameBoard(game);
- return;
- }
-
- game->board[dest.h][dest.v] = pc;
- DrawGameBoard(game);
- game->tempDest = dest;
-
- // now deal with the move
- char ch = '?';
- ch = Piece2Char(pc);
- bprintf("%c@%c%c\n", ch, 'a' + dest.h, '1' + dest.v);
- // tprintf("%c@%c%c\n", ch, 'a' + dest.h, '1' + dest.v);
- }
-
- static void
- DoFooterClick(Game *game, Point *pt)
- {
- ControlHandle ch = nil;
-
- // let's see if they hit a button
- if (FindControl(*pt, (WindowPtr) game->wind, &ch))
- if (TrackControl(ch, *pt, nil)) {
- long id = GetCRefCon(ch);
-
- switch (id) {
- case ctlBack: bprintf("backward\n"); break;
- case ctlForward: bprintf("forward\n"); break;
- case ctlStart: bprintf("backward 999\n"); break;
- case ctlEnd: bprintf("forward 999\n"); break;
- case ctlRevert: bprintf("revert\n"); break;
- default: break;
- }
- }
- }
-
- static void
- EndMove(void)
- {
- if (gClickType != kNoMove) {
- verify(gDragGame);
- Game *game = gDragGame;
- if (gClickType == kMove) {
- if (EqualPt(gDestPoint, gOrigPoint)) // not a move
- gDestPoint.h = -1;
- if (gDestPoint.h < 0)
- game->board[gOrigPoint.h][gOrigPoint.v] = gOldPiece;
- else
- game->board[gDestPoint.h][gDestPoint.v] = gOldPiece;
- if (gDestPoint.h >= 0)
- game->tempDest = gDestPoint;
- else
- game->tempDest.h = -1;
- DrawGameBoard(game);
-
- // now deal with the move
- if (gDestPoint.h >= 0) {
- bprintf("%c%c%c%c\n", 'a' + gOrigPoint.h, '1' + gOrigPoint.v, 'a' + gDestPoint.h, '1' + gDestPoint.v);
- // tprintf("%c%c%c%c\r", 'a' + gOrigPoint.h, '1' + gOrigPoint.v, 'a' + gDestPoint.h, '1' + gDestPoint.v);
- // tprintf("%d %d\r", gDestPoint.h, gDestPoint.v);
- }
- }
- else if (gClickType == kSetupMove) {
- if (EqualPt(gDestPoint, gOrigPoint)) // not a move
- gDestPoint.h = -1;
- if (gDestPoint.h < 0)
- game->board[gOrigPoint.h][gOrigPoint.v] = gOldPiece;
- else
- game->board[gDestPoint.h][gDestPoint.v] = gOldPiece;
- if (gDestPoint.h >= 0)
- game->tempDest = gDestPoint;
- else
- game->tempDest.h = -1;
- DrawGameBoard(game);
-
- // now deal with the move
- if (gDestPoint.h >= 0) {
- // we're in setup mode, and they're moving a piece
- // this isn't supported in server, but why not here? just clear and place
- bprintf("x@%c%c\n", 'a' + gOrigPoint.h, '1' + gOrigPoint.v); // clear old piece
- bprintf("%c@%c%c\n", Piece2Char(gOldPiece), 'a' + gDestPoint.h, '1' + gDestPoint.v);
- }
- else if (gDestPoint.h == -2) {
- // we're in setup mode, and they're clearing a piece off the board
- bprintf("x@%c%c\n", 'a' + gOrigPoint.h, '1' + gOrigPoint.v);
- game->board[gOrigPoint.h][gOrigPoint.v] = empty;
- DrawGameBoard(game);
- }
- }
- else if (gClickType == kBugMove) {
- if (gDestPoint.h < 0)
- DrawGameBoard(game);
- else {
- game->board[gDestPoint.h][gDestPoint.v] = gOldPiece;
- DrawGameBoard(game);
- game->tempDest = gDestPoint;
-
- // now deal with the move
- char ch = '?';
- ch = Piece2Char(gOldPiece);
- bprintf("%c@%c%c\n", ch, 'a' + gDestPoint.h, '1' + gDestPoint.v);
- // tprintf("%c@%c%c\n", ch, 'a' + gDestPoint.h, '1' + gDestPoint.v);
- }
- }
- }
- gClickType = kNoMove;
- ShowCursor();
- }
-
- static void
- StartDrag(void)
- {
- Point origin = gOrigPoint;
-
- HideCursor();
- SetRect(&dirty, 0, 0, 0, 0);
- gDestPoint.h = -2;
- gDestPoint.v = -2;
- if (origin.h >= 0) {
- if (!gDragGame->flip)
- dirty.left = origin.h * kSquareSize;
- else
- dirty.left = (7-origin.h) * kSquareSize;
- dirty.right = dirty.left + kSquareSize;
- if (!gDragGame->flip)
- dirty.top = (7 - origin.v) * kSquareSize;
- else
- dirty.top = origin.v * kSquareSize;
- dirty.bottom = dirty.top + kSquareSize;
- }
- }
-
- // if we're dragging when we get a server update, make sure the source remains empty
- void
- GotBoardFromServer(Game *game)
- {
- if (gClickType == kNoMove || game != gDragGame)
- return;
- if (gOrigPoint.h < 0)
- return; // a place
- game->board[gOrigPoint.h][gOrigPoint.v] = empty;
- }
-
- static void
- HandleBugClick2(Game *game, Point p)
- {
- short pc;
-
- short plr;
- if (p.v > kBugY + kBugPadding) {
- if (p.v > kBugY * 2 + kBugPadding)
- return;
- if (!game->flip) {
- pc = WhitePawn + (p.v - (kBugY + kBugPadding)) / kBugsize;
- plr = kWhite;
- }
- else {
- pc = BlackPawn + (p.v - (kBugY + kBugPadding)) / kBugsize;
- plr = kBlack;
- }
- }
- else if (p.v < kBugY) {
- if (!game->flip) {
- pc = BlackPawn + p.v / kBugsize;
- plr = kBlack;
- }
- else {
- pc = WhitePawn + p.v / kBugsize;
- plr = kWhite;
- }
- }
- else
- return;
-
- if (pc < WhitePawn || pc > BlackKing)
- return;
-
- if ((Piece2Player(pc) != (game->turn ^ (game->relation == RELATION_PLAYING_NOTMYMOVE))) && !game->setup)
- return; // wrong color piece
-
- Point pt = {-1, -1};
- short offs;
- if (!game->flip)
- offs = plr == kWhite ? 16 : -16;
- else
- offs = plr == kBlack ? 16 : -16;
- gOrigPoint = pt;
- gOldPiece = pc;
- gDragGame = game;
- offx = kBugspace + 8;
- offy = 16 + offs;
- gClickType = kBugMove;
- StartDrag();
- DragPiece2();
- }
-
- static void
- DragPiece2(void)
- {
- Game *game = gDragGame;
- if (!game || gClickType == kNoMove)
- return;
-
- Fastmap *fm = Piece2Fastmap(gOldPiece);
- verify(fm);
-
- Point ms, sq;
- Boolean inSquare;
- short siz = game->sqsize;
- Point origin = gOrigPoint;
-
- ulong stTime = TickCount();
- sq = gDestPoint;
- if (Button())
- do {
- SetGWorld(boff, nil);
- DrawBoard(game->board, game);
-
- // draw the piece we're dragging
- SetGWorld(game->wind, maindev);
- GetMouse(&ms);
- ms.v -= offy + game->bOffsetY; ms.h -= offx;
- // find square we're in
- inSquare = false;
- sq = ms;
- sq.h += siz / 2;
- sq.v += siz / 2;
- if ((sq.h % siz > 4) && (sq.h % siz < siz - 4)
- && (sq.v % siz > 4) && (sq.v % siz < siz - 4)) {
- sq.v += game->bOffsetY; // ugly, silly, but heck
- Point2Square(game, &sq);
- inSquare = sq.h >= 0;
- }
- else {
- // some extra work to see if they dragged it completely off the board
- // in that case, we return -2 (for setup)
- sq.v += game->bOffsetY; // ugly, silly, but heck
- Point2Square(game, &sq);
- if (sq.h >= 0)
- sq.h = -1;
- }
-
- SetGWorld(boff, nil);
-
- // draw target
- Rect rr = {0,0,0,0};
- if (inSquare && !EqualPt(origin, sq)) {
- if (!game->flip)
- rr.left = sq.h * kSquareSize;
- else
- rr.left = (7-sq.h) * kSquareSize;
- rr.right = rr.left + kSquareSize;
- if (!game->flip)
- rr.top = (7 - sq.v) * kSquareSize;
- else
- rr.top = sq.v * kSquareSize;
- rr.bottom = rr.top + kSquareSize;
- InsetRect(&rr, 4, 4);
- RGBColor col = {0xFFFF, 0, 0};
- RGBForeColor(&col);
- MoveTo(rr.left, rr.top);
- LineTo(rr.right, rr.bottom);
- MoveTo(rr.right, rr.top);
- LineTo(rr.left, rr.bottom);
- RGBForeColor(&rgbBlack);
- rr.right++; rr.bottom++;
- if (dirty.right > 0 && dirty.bottom > 0)
- UnionRect(&rr, &dirty, &dirty);
- else
- dirty = rr; // first time through loop
- }
-
- // draw piece we're sliding around
- Rect rec = {0, 0, 32, 32};
- ms.h = (float) ms.h * 32.0 / (float) siz;
- ms.v = (float) ms.v * 32.0 / (float) siz;
- OffsetRect(&rec, ms.h, ms.v);
- fm->DrawMask(boff, &rec);
- if (dirty.right > 0 && dirty.bottom > 0)
- UnionRect(&rec, &dirty, &dirty);
- else
- dirty = rec;
-
- SetGWorld(game->wind, maindev);
- if (dirty.left < 0) dirty.left = 0;
- if (dirty.top < 0) dirty.top = 0;
- if (dirty.bottom > kBoardSize) dirty.bottom = kBoardSize;
- if (dirty.right > kBoardSize) dirty.right = kBoardSize;
- DrawBoardSection(game, &dirty);
-
- // prepare dirty for next loop
- dirty = rec;
- if (rr.right > 0)
- UnionRect(&rr, &dirty, &dirty);
- } while (Button() && (TickCount() - stTime < 20));
-
- gDestPoint = sq;
- if (!Button()) {
- EndMove();
- }
- }
-
- // pick up a piece and move it
- void
- HandleGameClick(Point *pt)
- {
- Point p = *pt;
-
- Game *game = FindGameFromWindow(FrontWindow());
- if (!game) return;
-
- // check for growth
- // short mx = game->wind->portRect.
-
- if (gClickType != kNoMove)
- EndMove(); // shouldn't happen much, but . . .
-
- if (game->footer && pt->v >= kWinHeight)
- DoFooterClick(game, pt);
-
- // check to see if dragging pieces is valid for this board
- if (game->relation <= 0 && game->relation != RELATION_PLAYING_NOTMYMOVE)
- return; // nope
-
- if (p.h > game->boardRect.right) {
- HandleBugClick2(game, p);
- return;
- }
-
- // find board coords
- Point2Square(game, &p);
- if (p.h < 0)
- return; // out of range
-
- short oldPiece = game->board[p.h][p.v];
- if (oldPiece == empty)
- return;
- // if (Piece2Player(oldPiece) != game->turn && !game->setup)
- // return; // wrong color piece
- if (game->relation == RELATION_PLAYING_MYMOVE) {
- if (game->turn == kWhite && oldPiece >= BlackPawn)
- return; // wrong kind of piece
- if (game->turn == kBlack && oldPiece <= WhiteKing)
- return; // wrong kind of piece
- }
- else if (game->relation == RELATION_PLAYING_NOTMYMOVE) {
- if (game->turn == kWhite && oldPiece <= WhiteKing)
- return; // wrong kind of piece
- if (game->turn == kBlack && oldPiece >= BlackPawn)
- return; // wrong kind of piece
- }
-
- game->board[p.h][p.v] = empty;
- // DrawGameBoard(game);
- gOrigPoint = p;
- gOldPiece = oldPiece;
- gDragGame = game;
- offx = pt->h % game->sqsize;
- offy = (pt->v - game->bOffsetY) % game->sqsize;
- gClickType = kMove;
- if (game->setup)
- gClickType = kSetupMove;
- StartDrag();
- DragPiece2();
-
- /*
- if (EqualPt(dest, p)) // not a move
- dest.h = -1;
- if (dest.h < 0)
- game->board[p.h][p.v] = oldPiece;
- else
- game->board[dest.h][dest.v] = oldPiece;
- game->tempDest = dest;
- if (!(dest.h == -2 && game->setup))
- DrawGameBoard(game);
-
- // now deal with the move
- if (dest.h < 0) {
- if (dest.h == -2 && game->setup) {
- // we're in setup mode, and they're clearing a piece off the board
- bprintf("x@%c%c\n", 'a' + p.h, '1' + p.v);
- game->board[p.h][p.v] = empty;
- DrawGameBoard(game);
- }
- return;
- }
-
- if (game->setup) {
- // we're in setup mode, and they're moving a piece
- // this isn't supported in server, but why not here? just clear and place
- bprintf("x@%c%c\n", 'a' + p.h, '1' + p.v); // clear old piece
- bprintf("%c@%c%c\n", Piece2Char(oldPiece), 'a' + dest.h, '1' + dest.v);
- }
- else
- bprintf("%c%c%c%c\n", 'a' + p.h, '1' + p.v, 'a' + dest.h, '1' + dest.v);
- */
- }