home *** CD-ROM | disk | FTP | other *** search
- /*
- * Player name and board size dialogs
- */
-
-
- # include "TransSkel.h"
- # include "Message.h"
-
- # include "Concentration.h"
-
-
- typedef enum /* Player dialog item numbers */
- {
- pOK = 1,
- pCancel,
- pNameText, /* first editText name item */
- pNameText2,
- pNameText3,
- pNameText4,
- pNameTitle,
- pOutlineUser
- };
-
-
- typedef enum /* Board Size dialog item numbers */
- {
- bOK = 1,
- bCancel,
- bBoardUser, /* board sizing item */
- bTitleStatText,
- bOutlineUser
- };
-
-
- static BlobSetHandle board;
- static short curRows, curCols;
-
-
- /*
- * Run Player name dialog. Make a copy of the scoreboard, and modify the
- * copy when checking whether there are actually any names given after OK
- * is clicked. If so, copy the new scoreboard back into the real scoreboard
- * to update it.
- */
-
- void
- PlayerDialog (void)
- {
- ModalFilterProcPtr filter;
- DialogPtr dlog;
- GrafPtr savePort;
- ScoreBoard newScoreBoard;
- ScoreBoard *nsb = &newScoreBoard;
- short item;
- short i;
- Str255 s;
-
- dlog = GetNewDialog (playerDlogNum, nil, (WindowPtr) -1L);
- if (dlog == (DialogPtr) nil)
- {
- SysBeep (1);
- return;
- }
-
- SkelPositionWindow (dlog, skelPositionOnParentDevice, horizRatio, vertRatio);
-
- SkelSetDlogButtonOutliner (dlog, pOutlineUser);
-
- *nsb = *sb; /* make copy of current scoreboard */
-
- /*
- * Put current names into dialog and select first one
- */
-
- for (i = 0; i < nsb->nPlayers; i++)
- SkelSetDlogStr (dlog, pNameText + i, nsb->name[i]);
- for (i = nsb->nPlayers; i < maxPlayers; i++)
- SkelSetDlogStr (dlog, pNameText + i, "\p");
- SelIText (dlog, pNameText, 0, 32767);
-
- GetPort (&savePort);
- SetPort (dlog);
- ShowWindow (dlog);
-
- for (;;)
- {
- filter = SkelDlogFilter (nil, true);
- SkelDlogCancelItem (pCancel);
- ModalDialog (filter, &item);
- SkelRmveDlogFilter ();
- if (item == pCancel)
- break;
- if (item == pOK)
- {
- /*
- * If OK is hit, determine number of names actually specified.
- * There must be at least one player.
- */
- nsb->nPlayers = 0;
- for (i = pNameText; i < pNameText + maxPlayers; ++i)
- {
- SkelGetDlogStr (dlog, i, nsb->name[nsb->nPlayers]);
- if (nsb->name[nsb->nPlayers][0] > 0)
- ++nsb->nPlayers;
- }
- if (nsb->nPlayers > 0)
- break;
- Message1 ("\pYou must have at least one player");
- }
- }
-
- DisposeDialog (dlog);
- SetPort (savePort);
- SkelDoUpdates ();
-
- /*
- * If the number of players is the same, just update the scoreboard
- * for the current game. Otherwise update the scoreboard and start
- * new round game.
- */
-
- if (item == pOK)
- {
- if (nsb->nPlayers == sb->nPlayers)
- {
- *sb = *nsb;
- DrawScoreBoard ();
- }
- else
- {
- *sb = *nsb;
- NewGameRound ();
- }
- }
- }
-
-
- /* -------------------------------------------------------------------- */
- /* Filter proc stuff for board size dialog */
- /* -------------------------------------------------------------------- */
-
-
- /*
- * Draw a board blob. If the blob has a glob, paint it, otherwise
- * just a frame. Painted blobs indicate selected parts of the board.
- *
- * bDst blob to draw in
- * bSrc blob to be drawn in bDst
- */
-
- static pascal void
- DrawBoardBlob (BlobHandle bDst, BlobHandle bSrc, short partCode)
- {
- Rect r;
-
- switch (partCode)
- {
-
- case inStatBlob: /* ignore */
- break;
-
- case inDragBlob:
- r = BDragBox (bDst);
- InsetRect (&r, 1, 1);
- if (BGlob (bDst) != nil) /* selected */
- PaintRect (&r);
- else
- {
- FrameRect (&r);
- InsetRect (&r, 1, 1);
- EraseRect (&r);
- }
- break;
- }
- }
-
-
- /*
- * Draw the board properly, showing as dark all the squares that are
- * currently selected. Note that globs can be glued and unglued with
- * impunity, as the Blob Manager redraws only on a state *change*.
- */
-
- static void
- HiliteBoard (void)
- {
- BlobHandle b;
- short row, col;
- long refCon;
-
- for (b = FirstBlob (board); b != nil; b = NextBlob (b))
- {
- refCon = GetBRefCon (b);
- col = HiWord (refCon);
- row = LoWord (refCon);
- if (col < curCols && row < curRows)
- GlueGlob (b, b); /* select */
- else
- UnglueGlob (b); /* deselect */
- }
- }
-
-
- /*
- * Filter function for board dialog. Checks for hits in the blobs
- * used to represent the board and selects all blobs in the rectangle
- * defined by the upper left blob to the one clicked in. Then follow
- * the mouse as long as it's held down. This is not done especially
- * intelligently - there's no check even whether the mouse has changed
- * blobs before rehiliting the board. Still, it's not unacceptably
- * slow.
- *
- * The filter only changes the selected squares when the mouse sweeps
- * to a square that results in a non-empty board with an even number
- * of pieces.
- */
-
- static pascal Boolean
- BoardFilter (DialogPtr dlog, EventRecord *evt, short *item)
- {
- Point pt;
- BlobHandle b;
- long refCon;
- short rows, cols;
-
- if (evt->what == mouseDown)
- {
- pt = evt->where;
- GlobalToLocal (&pt);
- if (FindBlob (pt, board, &b) != 0)
- {
- for (;;)
- {
- if (b != nil)
- {
- refCon = GetBRefCon (b);
- cols = HiWord (refCon) + 1;
- rows = LoWord (refCon) + 1;
- if ((cols * rows) % 2 == 0) /* must have even */
- { /* number of squares */
- curCols = cols;
- curRows = rows;
- HiliteBoard ();
- }
- }
- if (!StillDown ())
- break;
- GetMouse (&pt);
- if (FindBlob (pt, board, &b) == 0)
- b = nil;
- }
- }
- }
- return (false);
- }
-
-
- static pascal void
- DoFrame (DialogPtr dlog, short item)
- {
- Rect r;
-
- SkelGetDlogRect (dlog, item, &r);
- if (gb->sizeType == smallPiece)
- {
- r.bottom -= 3; /* account for slight differences */
- r.right -= 4; /* in size for different pieces */
- }
- FrameRect (&r);
- DrawBlobSet (board);
- }
-
-
- void
- BoardDialog (void)
- {
- ModalFilterProcPtr filter;
- DialogPtr dlog;
- GrafPtr savePort;
- short item;
- short i, j, rows, cols, h, v, size;
- Rect boardRect, pieceRect;
- BlobHandle b;
-
- dlog = GetNewDialog (boardDlogNum, nil, (WindowPtr) -1L);
- if (dlog == (DialogPtr) nil)
- {
- SysBeep (1);
- return;
- }
-
- SkelPositionWindow (dlog, skelPositionOnParentDevice, horizRatio, vertRatio);
-
- GetPort (&savePort);
- SetPort (dlog);
-
- SkelSetDlogButtonOutliner (dlog, bOutlineUser);
- SkelSetDlogProc (dlog, bBoardUser, DoFrame);
-
- curRows = gb->nRows;
- curCols = gb->nCols;
- rows = gb->maxRows;
- cols = gb->maxCols;
- if (gb->sizeType == largePiece)
- size = 23;
- else
- size = 15;
-
- SkelGetDlogRect (dlog, bBoardUser, &boardRect);
- board = NewBlobSet ();
- for (i = 0; i < rows; ++i)
- {
- for (j = 0; j < cols; ++j)
- {
- b = NewBlob (board, true, infiniteGlue, false,
- (long) (((long) j << 16) | i));
- h = boardRect.left + 1 + (j * size);
- v = boardRect.top + 1 + (i * size);
- SetRect (&pieceRect, h, v, h + size, v + size);
- SetProcRectBlob (b, DrawBoardBlob, &pieceRect, &pieceRect);
- }
- }
- HiliteBoard ();
- ShowWindow (dlog);
-
- for (;;)
- {
- filter = SkelDlogFilter (BoardFilter, true);
- SkelDlogCancelItem (bCancel);
- ModalDialog (filter, &item);
- SkelRmveDlogFilter ();
- if (item == bOK || item == bCancel)
- break;
- }
-
- DisposeBlobSet (board);
- SetPort (savePort);
- DisposeDialog (dlog);
- SkelDoUpdates ();
-
- /*
- * If board size changed, reinitialize board using same sizeType
- * but new dimensions, then start new round of game
- */
-
- if (item == bOK)
- {
- if (gb->nRows != curRows || gb->nCols != curCols)
- {
- gb->nRows = curRows;
- gb->nCols = curCols;
- InitBoard (gb->sizeType);
- NewGameRound ();
- }
- }
- }
-