dubois@uwmacc.UUCP (Paul DuBois) (02/01/87)
#!/bin/sh # shar: Shell Archiver # Run the following text with /bin/sh to create: # BlobDemo/DemoStates.c # BlobDemo/DemoSwap.c # BlobDemo/DemoToh.c # BlobDemo/DemoTtt.c # BlobDemo/DemoWind.c mkdir BlobDemo sed 's/^X//' << 'SHAR_EOF' > BlobDemo/DemoStates.c X/* X Blob Manager Demonstration: States and Capitals module X X This module is an example of an extremely simple interrogative X scenario. The original thirteen colonies of the United States must X be matched with their capital cities. There is a single button that X says "Give Up?" If the user clicks the button, the answer is shown, X the button's title changes to "Resume", and the scenario is frozen X until the button is clicked. Then the answer is cleared, the capitals X are shuffled, and the user may start over. X X If the correct answers are all gotten, the button again changes to X "Resume" and the scenario is frozen until the button is clicked. X X The module is unexciting; it's meant as a basic illustration, rather X than anything useful. There are lots of bells and whistles that X could be added. X X 26 July 1986 Paul DuBois X*/ X X X# include "BlobDemo.h" X# include <ControlMgr.h> X X X# define nStates 13 X X# define hState1 220 X# define hState2 110 X# define vState 16 X# define stateXOff 10 X# define stateYOff 5 X# define hCapital 85 X# define vCapital 16 X# define capXOff 225 X# define capYOff 5 X X Xstruct info X{ X char *stateName; X char *capName; X}; X X X Xstatic GrafPtr statesPort; Xstatic BlobSetHandle donors; /* donor blobs */ Xstatic BlobSetHandle receptors; /* receptor blobs */ Xstatic ControlHandle giveUp; Xstatic Boolean paused = false; X Xstatic struct info scPair[nStates] = X{ X { "\pConnecticut", "\pHartford" }, X { "\pDelaware", "\pDover" }, X { "\pGeorgia", "\pAtlanta" }, X { "\pMaryland", "\pAnnapolis" }, X { "\pMassachusetts", "\pBoston" }, X { "\pNew Hampshire", "\pConcord" }, X { "\pNew Jersey", "\pTrenton" }, X { "\pNorth Carolina", "\pRaleigh" }, X { "\pNew York", "\pAlbany" }, X { "\pPennsylvania", "\pHarrisburg" }, X { "\pRhode Island", "\pProvidence" }, X { "\pSouth Carolina", "\pColumbia" }, X { "\pVirginia", "\pRichmond" } X}; X X Xstatic Activate (active) XBoolean active; X{ X if (active) X { X SetDragRects (statesPort); X SetBCPermissions (true, true, false, true, true); X } X} X X Xstatic Update () X{ X DrawControls (statesPort); X DrawBlobSet (receptors); X DrawBlobSet (donors); X} X X Xstatic Mouse (pt, t, mods) XPoint pt; Xlong t; Xint mods; X{ XBlobHandle b, d; XControlHandle ctl; X X if (FindControl (pt, statesPort, &ctl)) X { X if (TrackControl (ctl, pt, nil)) X { X if (paused) /* either all answers are correct, or we're */ X { /* showing the answer. Either way, restore */ X ThawBlobSet (receptors); /* to start state */ X ThawBlobSet (donors); X ZUnglueGlobSet (receptors); X ShuffleBlobSet (receptors); X ShuffleBlobSet (donors); X SetCTitle (giveUp, "\pGive Up?"); X ValidRect (&statesPort->portRect); X paused = false; X } X else /* user gives up - show answer */ X { X for (b = FirstBlob (receptors); b != nil; b = NextBlob (b)) X ZGlueGlob (FirstBMatch (b), b); X FreezeBlobSet (receptors); X FreezeBlobSet (donors); X SetCTitle (giveUp, "\pResume"); X paused = true; X } X } X } X else X { X BlobClick (pt, t, donors, receptors); X if (!paused && BlobSetQuiet (receptors)) /* answers correct? */ X { X FreezeBlobSet (receptors); X FreezeBlobSet (donors); X SetCTitle (giveUp, "\pResume"); X paused = true; X } X } X} X X X/* X Make blobs X*/ X X XMakeBlobs () X{ Xint i; XRect r, r2; XBlobHandle b1, b2; X X donors = NewBlobSet (); X receptors = NewBlobSet (); X for (i = 0; i < nStates; ++i) X { X b1 = NewBlob (donors, false, 1, false, 0L); X b2 = NewBlob (receptors, false, 0, true, 0L); X NewBlobMatch (b1, b2); /* attach the answer */ X X OpenBlob (); /* draw donor blob */ X SetRect (&r, 0, 0, hCapital, vCapital); X TextBox (&scPair[i].capName[1], (long) scPair[i].capName[0], &r, 1); X CloseRectBlob (b1, &r, &r); X MoveBlob (b1, inFullBlob, capXOff, capYOff + (vCapital + 1) * i); X X OpenBlob (); X SetRect (&r, 0, 0, hState1, vState); X SetRect (&r2, 0, 0, hState2, vState); X TextBox (&scPair[i].stateName[1], (long) scPair[i].stateName[0], &r2, 1); X SetRect (&r2, 0, 0, hCapital, vCapital); X OffsetRect (&r2, hState2 + 5, 0); X EraseRect (&r2); X FrameRect (&r2); X CloseRectBlob (b2, &r2, &r); X MoveBlob (b2, inFullBlob, stateXOff, stateYOff + (vState + 2) * i); X } X ShuffleBlobSet (donors); X EnableBlobSet (receptors); X EnableBlobSet (donors); X} X X XStatesInit () X{ XRect r; X X SkelWindow (statesPort = GetDemoWind (statesWindRes), X Mouse, /* mouse clicks */ X nil, /* key clicks */ X Update, /* updates */ X Activate, /* activate/deactivate events */ X nil, /* close window */ X DoWClobber, /* dispose of window */ X nil, /* idle proc */ X false); /* irrelevant, since no idle proc */ X X/* X Make blobs. Generally have to make donors before receptors. X*/ X MakeBlobs (); X X r = statesPort->portRect; X SetRect (&r, r.left + 5, r.bottom - 25, r.left + 75, r.bottom - 5); X giveUp = NewControl (statesPort, &r, "\pGive Up?", true, 0, 0, 0, X pushButProc, nil); X X Update (); X ValidRect (&statesPort->portRect); X} SHAR_EOF sed 's/^X//' << 'SHAR_EOF' > BlobDemo/DemoSwap.c X/* X Blob Manager Demonstration: Coin Swap module X X This has a linear board with either 5, 7 or 9 pieces. The middle X piece is always empty, the pieces on one end are filled with black X coins, the pieces on the other end are filled with white coins. X The object is to swap the coins. A coin can slide into an empty X piece next to it, or jump over a single coin to land on an empty X piece. X X A menu allows the number of coins to be chosen. To win, the coins X have to be swapped in a specific number of moves. X X 26 July 1986 Paul DuBois X*/ X X X# include "BlobDemo.h" X# include <MenuMgr.h> X X# define vMessage 10 X# define vPiece 30 X# define maxPieces 9 X# define pieceSize 24 X# define pieceGap 1 X X Xstatic GrafPtr swapPort; Xstatic MenuHandle cnfgMenu; Xstatic BlobSetHandle donors = nil; Xstatic BlobSetHandle receptors = nil; Xstatic int hMid; Xstatic Str255 statusStr = "\p"; X Xstatic int nPieces = 5; Xstatic int nMoves = 8; Xstatic BlobHandle piece[maxPieces]; Xstatic int moves; Xstatic Boolean pause; X X Xstatic StatusMesg (s) XStr255 s; X{ XRect r; X X SetRect (&r, hMid - 60, vMessage, hMid + 60, vMessage+16); X TextBox (s+1, (long) s[0], &r, 1); X StrCpy (statusStr, s); X} X X X/* X Reset to start state. This recreates the board each time. All the X blobs in the board require explicit matches except the middle one. X*/ X Xstatic Reset () X{ XBlobHandle b; XRect r; Xint i, h; XStr255 s; X X InvalRect (&swapPort->portRect); /* force update when done resetting */ X pause = false; X moves = nMoves; X MovesLeft (moves, s); X StatusMesg (s); X X if (receptors != nil) /* clobber any existing receptor set */ X { X HideBlobSet (receptors); X DisposeBlobSet (receptors); X } X receptors = NewBlobSet (); X X h = hMid - (nPieces * (pieceSize + pieceGap) - pieceGap) / 2; X for (i = 0; i < nPieces; ++i) X { X b = NewBlob (receptors, false, 0, i != (nPieces - 1) / 2, 0L); X piece[i] = b; X OpenBlob (); X SetRect (&r, h, vPiece, h + pieceSize, vPiece + pieceSize); X EraseRect (&r); X FrameRect (&r); X CloseRectBlob (b, &r, &r); X h += pieceSize + pieceGap; X if (i < (nPieces - 1) / 2) X { X GlueGlob (GetBlobHandle (donors, 0), b); X NewBlobMatch (GetBlobHandle (donors, 1), b); X } X else if (i > (nPieces - 1) / 2) X { X GlueGlob (GetBlobHandle (donors, 1), b); X NewBlobMatch (GetBlobHandle (donors, 0), b); X } X } X EnableBlobSet (receptors); X} X X Xstatic SwapPause (msg) XStringPtr msg; X{ X StatusMesg (msg); X pause = true; X} X X Xstatic Mouse (pt, t, mods) XPoint pt; Xlong t; Xint mods; X{ XStr255 s; Xregister int i; X X/* X Freeze all the pieces that can't be moved, then call BlobClick. X*/ X for (i = 0; i < nPieces; ++i) X { X ThawBlob (piece[i]); X if (BGlob (piece[i]) == nil) continue; X if (i > 0 && BGlob (piece[i-1]) == nil) continue; X if (i > 1 && BGlob (piece[i-2]) == nil) continue; X if (i < nPieces - 1 && BGlob (piece[i+1]) == nil) continue; X if (i < nPieces - 2 && BGlob (piece[i+2]) == nil) continue; X FreezeBlob (piece[i]); X } X if (!pause) X { X BlobClick (pt, t, donors, receptors); X if (BClickResult () == bcXfer) X { X if (--moves == 0) X { X if (BlobSetQuiet (receptors)) X SwapPause ("\pYou Win"); X else X SwapPause ("\pYou Lose"); X } X else X { X MovesLeft (moves, s); X StatusMesg (s); X } X } X } X} X X X/* X Select configuration: 4, 6, or 8 coins (2, 3, or 4 on each side). X If the number of coins on each side is n, the number of moves X to solve is (n+1)^2 - 1. X*/ XDoConfiguration (item) Xint item; X{ X nPieces = 2 * item + 3; /* 1->5, 2->7, 3->9 pieces */ X nMoves = (item + 2) * (item + 2) - 1; X Reset (); X} X X Xstatic Activate (active) XBoolean active; X{ X if (active) X { X SetDragRects (swapPort); X SetBCPermissions (false, true, false, false, false); /* xfer only */ X cnfgMenu = GetMenu (swapCnfgMenuRes); X SkelMenu (cnfgMenu, DoConfiguration, DoMClobber); X } X else X SkelRmveMenu (cnfgMenu); X} X X Xstatic Update (resized) XBoolean resized; X{ X DrawBlobSet (receptors); X StatusMesg (statusStr); X} X X X/* X Make donor blobs. X*/ X Xstatic MakeDonors () X{ XBlobHandle b; XRect r; X X donors = NewBlobSet (); X b = NewBlob (donors, false, infiniteGlue, false, 0L); X OpenBlob (); X SetRect (&r, 0, 0, pieceSize, pieceSize); X EraseRect (&r); X FrameRect (&r); X InsetRect (&r, 2, 2); X PaintOval (&r); X InsetRect (&r, -2, -2); X CloseRectBlob (b, &r, &r); X b = NewBlob (donors, false, infiniteGlue, false, 0L); X OpenBlob (); X PaintRect (&r); X InsetRect (&r, 2, 2); X EraseOval (&r); X InsetRect (&r, -2, -2); X CloseRectBlob (b, &r, &r); X} X X XSwapInit () X{ X SkelWindow (swapPort = GetDemoWind (swapWindRes), X Mouse, /* mouse clicks */ X nil, /* key clicks */ X Update, /* updates */ X Activate, /* activate/deactivate events */ X nil, /* close window */ X DoWClobber, /* dispose of window */ X nil, /* idle proc */ X false); /* irrelevant, since no idle proc */ X X hMid = swapPort->portRect.right / 2; X X MakeDonors (); X Reset (); X Update (); X ValidRect (&swapPort->portRect); X} SHAR_EOF sed 's/^X//' << 'SHAR_EOF' > BlobDemo/DemoToh.c X/* X Blob Manager Demonstration: Tower of Hanoi X X 26 July 1986 Paul DuBois X*/ X X# include "BlobDemo.h" X X X# define xBase 17 /* upper left corner of apparatus base */ X# define yBase 130 X# define baseHeight 12 /* length is computed */ X# define slotHeight 18 /* size of disk slots */ X# define slotWidth 100 X# define slotHGap 20 /* horiz. gap between slots */ X# define slotVGap 0 /* vert. gap between slots */ X# define hExtra 20 /* extra space at ends of base */ X# define nDisks 6 /* number of disks */ X# define postWidth 12 /* height is computed */ X X Xstatic GrafPtr tohPort; Xstatic BlobSetHandle donors; Xstatic BlobSetHandle receptors; Xstatic BlobHandle tower[3][nDisks]; /* induced data structure */ X X X Xstatic DrawApparatus () X{ Xint postHeight, baseWidth, h, v, i; XRect r; X X postHeight = nDisks * (slotHeight + slotVGap) + postWidth/2; X h = xBase + hExtra + slotWidth/2 - postWidth/2; X SetRect (&r, h, yBase - postHeight, h + postWidth, yBase+postWidth/2); X X for (i = 0; i < 3; ++i) X { X FillRoundRect (&r, postWidth, postWidth, gray); X FrameRoundRect (&r, postWidth, postWidth); X OffsetRect (&r, slotWidth + slotHGap, 0); X } X X baseWidth = 3 * slotWidth + 2 * slotHGap + 2 * hExtra; X SetRect (&r, xBase, yBase, xBase + baseWidth, yBase + baseHeight); X FillRect (&r, dkGray); X FrameRect (&r); X} X X X/* X If a disk was moved onto a pile, but has empty slots under it, X drop it until it can't go any farther. X*/ X Xstatic DropDisk () X{ Xregister int i, j; X X for (i = 0; i < 3; ++i) X { X for (j = nDisks - 1; j > 0; --j) /* don't check bottom pos */ X { X if (BGlob (tower[i][j]) != nil) X { X if (BGlob (tower[i][j-1]) == nil) X TransferGlob (tower[i][j], tower[i][j-1]); X } X } X } X} X X Xstatic Mouse (pt, t, mods) XPoint pt; Xlong t; Xint mods; X{ X X BlobClick (pt, t, nil, receptors); X DropDisk (); X} X X X/* X The advisory functions as follows: receptor clicks are checked X and if the click isn't in the top disk of a pile, the click is X ignored (message advRClick). When a receptor is dragged somewhere X else, it must be to a pile in which the disk under it is larger - X can't drag onto a smaller disk (message advXfer). X*/ X Xstatic Boolean Advisory (mesg, b) Xint mesg; XBlobHandle b; X{ XBlobHandle g; Xint index, pile, piece, i; Xstatic int srcRank; X X index = GetBlobIndex (b, receptors); X pile = index / nDisks; /* 0 .. 2 */ X piece = index % nDisks; /* 0 .. nDisks-1 */ X X switch (mesg) X { X case advRClick: X { X if (piece < nDisks - 1 && BGlob (NextBlob (b)) != nil) X return (false); X srcRank = GetBRefCon (BGlob (b)); /* rank of dragged piece */ X break; X } X case advXfer: X { X for (i = 0; i < piece; ++i) X { X if ((g = BGlob (tower[pile][i])) != nil) X { X if (GetBRefCon (g) > srcRank) X return (false); X } X } X break; X } X } X return (true); X} X X Xstatic Update (resized) XBoolean resized; X{ X DrawControls (tohPort); X DrawApparatus (); X DrawBlobSet (receptors); X} X X Xstatic Activate (active) XBoolean active; X{ X if (active) X { X SetDragRects (tohPort); X SetBCPermissions (false, true, false, false, false); X SetBCAdvisory (Advisory); X } X else X SetBCAdvisory (nil); X} X X/* X Call this before static MakeDonors X*/ X Xstatic MakeReceptors () X{ Xint i, j, h, v; XBlobHandle b; XRect r, r2, r3; X X receptors = NewBlobSet (); X for (i = 0; i < 3; ++i) X { X for (j = 0; j < nDisks; ++j) X { X b = NewBlob (receptors, false, 0, false, 0L); X tower[i][j] = b; X OpenBlob (); X SetRect (&r, 0, 0, slotWidth, slotHeight); X h = slotWidth/2 - postWidth/2; X SetRect (&r2, h, -1, h + postWidth, slotHeight+1); X FillRect (&r2, gray); /* fill in post area */ X SetRect (&r3, 0, 0, h, slotHeight); /* erase on sides of post */ X EraseRect (&r3); X SetRect (&r3, h + postWidth, 0, slotWidth, slotHeight); X EraseRect (&r3); X FrameRect (&r2); X r2 = r; X InsetRect (&r2, 0, 1); X CloseRectBlob (b, &r2, &r); X h = xBase + hExtra + i * (slotWidth + slotHGap); X v = yBase - (j+1) * (slotHeight + slotVGap); X MoveBlob (b, inFullBlob, h, v); X } X } X} X X X/* X Make donors. These are the pieces that get moved. They're always X attached to some receptor, and just float from one receptor to X another. The rank of each piece is stored in the reference constant X field. The bottom piece is 0, the top is nDisks-1. X*/ X Xstatic MakeDonors () X{ Xint i, j; XBlobHandle b; XRect r, r2; X X donors = NewBlobSet (); X for (i = 0; i < nDisks; ++i) X { X b = NewBlob (donors, false, 1, false, X (long) i); /* refCon is disk rank */ X OpenBlob (); X SetRect (&r, 0, 0, slotWidth, slotHeight); X j = 20 + (nDisks-i-1) * 4; X SetRect (&r2, slotWidth/2 - j, 1, slotWidth/2 + j, slotHeight-1); X EraseRect (&r); X FrameRoundRect (&r2, slotHeight, slotHeight); X CloseRectBlob (b, &r, &r); X GlueGlob (b, tower[0][i]); /* glue to first column */ X } X X} X X XTohInit () X{ X SkelWindow (tohPort = GetDemoWind (tohWindRes), X Mouse, /* mouse clicks */ X nil, /* key clicks */ X Update, /* updates */ X Activate, /* activate/deactivate events */ X nil, /* close window */ X DoWClobber, /* dispose of window */ X nil, /* idle proc */ X false); /* irrelevant, since no idle proc */ X X MakeReceptors (); X MakeDonors (); X EnableBlobSet (receptors); X Update (); X ValidRect (&tohPort->portRect); X} SHAR_EOF sed 's/^X//' << 'SHAR_EOF' > BlobDemo/DemoTtt.c X/* X Blob Manager Demonstration: Tic-Tac-Toe X X 25 July 1986 Paul DuBois X*/ X X# include "BlobDemo.h" X# include <ControlMgr.h> X X X# define barWidth 3 /* board line size */ X# define bSqSize 30 /* board square size */ X# define pSqSize 28 /* playing piece square size */ X# define yOffMesg 4 X# define yOffPiece 24 /* offset of top of pieces */ X# define xOffBoard 25 X# define yOffBoard 59 X# define xMid 73 /* xOffBoard + 1.5(bSqSize) + barWidth */ X# define yOffBut 165 X X Xstatic GrafPtr tttPort; Xstatic BlobSetHandle tttReceptors; /* receptor blobs (board) */ Xstatic BlobSetHandle tttDonors; /* donor blobs (pieces) */ Xstatic BlobHandle xBlob; /* handles to each piece */ Xstatic BlobHandle oBlob; X Xstatic Boolean haveWin; Xstatic Boolean wait = false; Xstatic ControlHandle restartCtl; Xstatic int moves; Xstatic int firstPlayer = 0; Xstatic Str255 statusStr; X X XTttStatusMesg (s) XStr255 s; X{ XRect r; X X SetRect (&r, xMid-40, yOffMesg, xMid+40, yOffMesg+20); X TextBox (s+1, (long) s[0], &r, 1); X StrCpy (statusStr, s); X} X X XTttGameOver (mesg) XStr255 mesg; X{ X HiliteControl (restartCtl, 0); X TttStatusMesg (mesg); X wait = true; X} X X X XTttSelectPlayer () X{ XBlobHandle b; Xint i; X X i = (moves + firstPlayer) % 2; /* 0 = X, 1 = O */ X HiliteBlob (GetBlobHandle (tttDonors, i), inFullBlob, normalDraw); X HiliteBlob (GetBlobHandle (tttDonors, 1 - i), inFullBlob, dimDraw); X if (i) X TttStatusMesg ("\pO's Move"); X else X TttStatusMesg ("\pX's Move"); X/* X Freeze board except for positions occupied by current player and X empty positions. X This allows pieces to be played either by playing the piece at X the top, or by duplicating them on the board. (Can't drag onto X another of own pieces, since replace transactions are disallowed.) X*/ X ThawBlobSet (tttReceptors); X for (b = FirstBlob (tttReceptors); b != nil; b = NextBlob (b)) X { X if (BGlob (b) != nil && BGlob (b) != GetBlobHandle (tttDonors, i)) X FreezeBlob (b); X } X} X X XTttRestart () X{ X HiliteControl (restartCtl, 255); X ZUnglueGlobSet (tttReceptors); X HiliteBlobSet (tttReceptors, inFullBlob, normalDraw); X moves = 0; X TttSelectPlayer (); X wait = false; X} X X X/* X Dim the board positions that are not part of the win. Dim them all X on "cat's game." X*/ X XTttShowWinner (pos) Xint pos; X{ Xint i; XBlobHandle b; X X for (i = 0; i < 9; ++i) X { X b = GetBlobHandle (tttReceptors, i); X if ((pos % 2) == 0) /* this pos not part of win */ X HiliteBlob (b, inFullBlob, dimDraw); /* so dim it */ X pos >>= 1; X } X} X XTttTestConfig (pos, testPos) Xint pos, testPos; X{ Xint i; XBlobHandle b; X X if ((pos & testPos) == testPos) /* have a win */ X { X haveWin = true; X TttShowWinner (testPos); X } X} X X XTttTestWin (b, boardPos) XBlobHandle b; Xint boardPos; X{ X if (!haveWin) /* don't bother if other player already won */ X { X TttTestConfig (boardPos, 0x007); /* top row */ X TttTestConfig (boardPos, 0x038); /* middle row */ X TttTestConfig (boardPos, 0x1c0); /* bottom row */ X TttTestConfig (boardPos, 0x049); /* left column */ X TttTestConfig (boardPos, 0x092); /* middle column */ X TttTestConfig (boardPos, 0x124); /* right column */ X TttTestConfig (boardPos, 0x111); /* diagonal */ X TttTestConfig (boardPos, 0x054); /* diagonal */ X if (haveWin) X { X if (b == xBlob) X { X TttGameOver ("\pX Wins"); /* loser goes first next time */ X firstPlayer = 1; X } X else X { X TttGameOver ("\pO Wins"); X firstPlayer = 0; X } X } X } X} X X XTttBoardPos (b) XBlobHandle b; X{ Xint i, mask, result; XBlobHandle b2; X X result = 0; X mask = 1; X for (i = 0; i < 9; ++i) X { X b2 = GetBlobHandle (tttReceptors, i); X if ((**b2).glob == b) /* board occupied by desired piece */ X result |= mask; X mask <<= 1; X } X return (result); X} X X XTttCheckStatus () X{ Xint xbPos, obPos; X X haveWin = false; X xbPos = TttBoardPos (xBlob); X obPos = TttBoardPos (oBlob); X TttTestWin (xBlob, xbPos); X TttTestWin (oBlob, obPos); X if (!haveWin) /* no win, but board might be full now */ X { X if ((xbPos | obPos) == 0x1ff) X { X TttShowWinner (0); X TttGameOver ("\pCat's Game"); X firstPlayer = 1 - firstPlayer; /* alternate on a draw */ X } X } X} X X XTttMouse (pt, t, mods) XPoint pt; Xlong t; Xint mods; X{ Xint result; XControlHandle ctl; X X if (FindControl (pt, tttPort, &ctl)) X { X if (TrackControl (ctl, pt, nil)) X { X TttRestart (); X } X } X else if (!wait) X { X BlobClick (pt, t, tttDonors, tttReceptors); X result = BClickResult (); X if (result == bcGlue || result == bcDup) X { X ++moves; X TttCheckStatus (); X if (!wait) /* no win yet */ X { X TttSelectPlayer (); X } X } X } X} X XTttUpdate (resized) XBoolean resized; X{ X DrawControls (tttPort); X TttStatusMesg (statusStr); X DrawGrid (3, 3, xOffBoard, yOffBoard, bSqSize, bSqSize, barWidth, barWidth); X DrawBlobSet (tttDonors); X DrawBlobSet (tttReceptors); X} X X XTttActivate (active) XBoolean active; X{ X if (active) X { X SetDragRects (tttPort); X SetBCPermissions (false, false, true, false, false); X } X} X X X/* X Make receptor blobs X*/ X XTttMakeRBlob (r) XRect *r; X{ XBlobHandle b; X X b = NewBlob (tttReceptors, false, 0, false, 0L); X OpenBlob (); X EraseRect (r); X InsetRect (r, 1, 1); X FrameRect (r); X InsetRect (r, 2, 2); X FrameRect (r); X InsetRect (r, -2, -2); X CloseRectBlob (b, r, r); X} X X XTttMakeReceptors () X{ X tttReceptors = NewBlobSet (); X MakeBlobGrid (3, 3, xOffBoard, yOffBoard, bSqSize, bSqSize, X barWidth, barWidth, &TttMakeRBlob); X} X X X/* X Make donor blobs X*/ X XTttMakeDBlob (b, ch, x, y) XBlobHandle *b; Xint ch, x, y; X{ XRect r; X X *b = NewBlob (tttDonors, false, 9, false, 0L); X OpenBlob (); X SetRect (&r, 0, 0, pSqSize, pSqSize); X OffsetRect (&r, x, y); X EraseRect (&r); X PenSize (2, 2); X FrameRect (&r); X PenNormal (); X MoveTo (r.left+pSqSize/2-4, r.bottom-pSqSize/2+5); X DrawChar ((char) ch); X CloseRectBlob (*b, &r, &r); X} X X XTttMakeDonors () X{ X tttDonors = NewBlobSet (); X TttMakeDBlob (&xBlob, 'X', xMid-pSqSize-5, yOffPiece); X TttMakeDBlob (&oBlob, 'O', xMid+5, yOffPiece); X} X X XTttInit () X{ XRect r; X X tttPort = GetDemoWind (tttWindRes); X SkelWindow (tttPort, X TttMouse, /* mouse clicks */ X nil, /* key clicks */ X TttUpdate, /* updates */ X TttActivate, /* activate/deactivate events */ X nil, /* close window */ X DoWClobber, /* dispose of window */ X nil, /* idle proc */ X false); /* irrelevant, since no idle proc */ X X TttMakeReceptors (); X TttMakeDonors (); X EnableBlobSet (tttReceptors); X EnableBlobSet (tttDonors); X SetRect (&r, xMid-45, yOffBut, xMid+45, yOffBut+20); X restartCtl = NewControl (tttPort, &r, "\pRestart", true, 0, 0, 0, X pushButProc, nil); X TttRestart (); X TttUpdate (); X ValidRect (&tttPort->portRect); X} SHAR_EOF sed 's/^X//' << 'SHAR_EOF' > BlobDemo/DemoWind.c X/* X Blob Manager Demonstration: Window routines X*/ X X# include "BlobDemo.h" X# include <WindowMgr.h> X X X X X/* X Get a window for a demo module. Pass the resource number of the X window. Set the font to Chicago 12-point, and add the window's X title to the Windows menu. X*/ X XGrafPtr GetDemoWind (resNum) Xint resNum; X{ XGrafPtr thePort; X X thePort = (GrafPtr) GetNewWindow (resNum, nil, -1L); X SetPort (thePort); X TextFont (0); X TextSize (0); X return (thePort); X} X X X/* X Generic window handler clobber proc for TransSkel stuff X*/ X XDoWClobber () X{ XWindowPtr theWind; X X GetPort ((GrafPtr *) &theWind); X CloseWindow (theWind); /* should be DisposeWindow? */ X} X X X/* X Set window's default blob dragging rects: limit rect is portRect X of window's grafPort, slop rect is wide open rectangle. X*/ X XSetDragRects (thePort) XGrafPtr thePort; X{ XRect rSlop; X X SetRect (&rSlop, -30000, -30000, 30000, 30000); X SetBDragRects (&thePort->portRect, &rSlop); X}SHAR_EOF exit