/*============================================================*/ /*============================================================*/ /*== ==*/ /*== Net Opponent Handling Routines ==*/ /*== ==*/ /*============================================================*/ /*============================================================*/ /*======================================================== Includes */ #include "Globals.h" #include "UnivUtilities.h" #include "AppleTalkDDP.h" #include "NetOpponent.h" #include "AnimCursor.h" #include "SoundUtils.h" #include "PlayUtils.h" #include "Replay.h" #include "Render.h" /*======================================================== Functions */ /*======================================================== SendSynchPulse */ OSErr SendSynchPulse (void) { OSErr netErr; short helloMessage; helloMessage = kHelloIndicator; netErr = SendOutgoingDDP((long)&helloMessage, 2); return (netErr); } /*======================================================== SendThisEnvironment */ OSErr SendThisEnvironment (void) { environMessage thisMessage; OSErr theErr; thisMessage.speed = speedFlag; thisMessage.version = kNetworkVersion; thisMessage.arena = arenaSize; thisMessage.goal = thePlayer.whichGoal; thisMessage.spotPts = spotPoints; thisMessage.league = isLeague; thisMessage.scoredLast = leftScoredLast; thisMessage.limited = netOnly; theErr = SendOutgoingDDP((long)&thisMessage, kEnviroMessageSize); return(theErr); } /*======================================================== BegForSomething */ OSErr BegForSomething (short anythingLove) { requestMessage requestor; OSErr theErr; requestor.requested = anythingLove; requestor.firstArgument = 0; requestor.secondArgument = 0; theErr = SendOutgoingDDP((long)&requestor, kRequestSize); return (theErr); } /*======================================================== WaitForSynch */ Boolean WaitForSynch (short timeOut) { long imVeryBored, dummyLong; OSErr theErr; short helloMessage, replyMessage; Boolean iHearYou; replyMessage = 0; dummyLong = 0; iHearYou = FALSE; imVeryBored = Ticks + timeOut; theErr = RequestReceiveDDP(); while ((Ticks < imVeryBored) && (!iHearYou)) { IncrementCursor(); theErr = PollSpecificDDP((long)&replyMessage, 2, 3); if (CommandPeriodDown()) break; if ((theErr == noErr) && (replyMessage == kHelloIndicator)) { iHearYou = TRUE; Delay(4, &dummyLong); } else if (theErr == kNetErrWrongSize) { if (lastByteCount == kRequestSize) { if (firstPackageShort == kRequestEnvironment) theErr = SendThisEnvironment(); else theErr = BegForSomething(kGotYourEnvironment); } else if (lastByteCount == kEnviroMessageSize) { theErr = BegForSomething(kGotYourEnvironment); } } SendSynchPulse(); } InitCursor(); return (iHearYou); } /*======================================================== ConfirmEnvironmentMatch */ Boolean ConfirmEnvironmentMatch (void) { environMessage theirMessage; long timeToBail; OSErr theErr; Boolean confirmed, needEnviron, sheSaysOkay, sheWants; theirMessage.speed = 0L; theirMessage.version = 0; theirMessage.arena = -1; theirMessage.goal = -1; theirMessage.spotPts = 0; theirMessage.league = 0; theirMessage.scoredLast = !leftScoredLast; theirMessage.limited = TRUE; theErr = RequestReceiveDDP(); timeToBail = Ticks + 3600; confirmed = FALSE; sheSaysOkay = FALSE; sheWants = FALSE; needEnviron = TRUE; theErr = BegForSomething(kRequestEnvironment); while ((!confirmed) && (Ticks < timeToBail)) { IncrementCursor(); if (CommandPeriodDown()) timeToBail = Ticks; theErr = PollSpecificDDP((long)&theirMessage, kEnviroMessageSize, 2); if (theErr == noErr) { needEnviron = FALSE; } else if ((theErr == kNetErrWrongSize) && (lastByteCount == kRequestSize)) { if (firstPackageShort == kRequestEnvironment) { sheWants = TRUE; } else if (firstPackageShort == kGotYourEnvironment) { sheWants = FALSE; sheSaysOkay = TRUE; if (!needEnviron) { confirmed = TRUE; } } } if (sheWants) { theErr = SendThisEnvironment(); sheWants = FALSE; } else if (needEnviron) theErr = BegForSomething(kRequestEnvironment); else theErr = BegForSomething(kGotYourEnvironment); } if (!confirmed) /* why did we leave the loop */ MinorError(kMinorNoNetConfirm); /* inform user of error */ else { if (theirMessage.version != kNetworkVersion) { MinorError(kMinorWrongNetVersion); confirmed = FALSE; } else if (theirMessage.arena != arenaSize) { if (theirMessage.arena > arenaSize) MinorError(kMinorArenaTooBig); else MinorError(kMinorArenaTooSmall); confirmed = FALSE; } else if (theirMessage.limited && netOnly) { MinorError(kMinorNeedOneValidCopy); confirmed = FALSE; } else { theirSpeed = theirMessage.speed; confirmed = DetermineMasterSlave(); if (confirmed) { netMirroring = (theirMessage.goal == thePlayer.whichGoal); spottedPoints = theirMessage.spotPts; theirLeague = theirMessage.league; if (!imTheMaster) leftScoredLast = theirMessage.scoredLast; } else { MinorError(kMinorNoMasterPossible); } } } InitCursor(); return (confirmed); } /*======================================================== WhatsTheGamesOutcome */ Boolean WhatsTheGamesOutcome (void) { typedef struct { short playerTotGoals; short opponentTotGoals; short playerTotFouls; short opponentTotFouls; short playerTotCrits; short opponentTotCrits; Boolean playerWon; } outcomeMessage; outcomeMessage thisMessage, theirMessage; long timeToBail, dummyLong; OSErr theErr; short outcomeMessageSize; Boolean confirmed; thisMessage.playerTotGoals = opponentTotalGoals; thisMessage.opponentTotGoals = playerTotalGoals; thisMessage.playerTotFouls = opponentTotalFouls; thisMessage.opponentTotFouls = playerTotalFouls; thisMessage.playerTotCrits = opponentTotalCrits; thisMessage.opponentTotCrits = playerTotalCrits; if (playerWonTheGame == kPlayerWon) thisMessage.playerWon = kOpponentWon; else thisMessage.playerWon = kPlayerWon; theirMessage.playerTotGoals = 0; theirMessage.opponentTotGoals = 0; theirMessage.playerTotFouls = 0; theirMessage.opponentTotFouls = 0; theirMessage.playerTotCrits = 0; theirMessage.opponentTotCrits = 0; theirMessage.playerWon = 0; outcomeMessageSize = (short)sizeof(theirMessage); timeToBail = Ticks + 300; confirmed = FALSE; theErr = RequestReceiveDDP(); while ((!confirmed) && (Ticks < timeToBail)) { theErr = PollSpecificDDP((long)&theirMessage, outcomeMessageSize, 2); if (theErr == noErr) { confirmed = TRUE; Delay(4, &dummyLong); } theErr = SendOutgoingDDP((long)&thisMessage, outcomeMessageSize); } theErr = SendOutgoingDDP((long)&thisMessage, outcomeMessageSize); if ((confirmed) && (!imTheMaster)) { playerTotalGoals = theirMessage.playerTotGoals; opponentTotalGoals = theirMessage.opponentTotGoals; playerTotalFouls = theirMessage.playerTotFouls; opponentTotalFouls = theirMessage.opponentTotFouls; playerTotalCrits = theirMessage.playerTotCrits; opponentTotalCrits = theirMessage.opponentTotCrits; playerWonTheGame = theirMessage.playerWon; } return (confirmed); } /*======================================================== PrepareStandardMessage */ void PrepareStandardMessage (void) { if (imTheMaster) { masterMessage.messageType = frameCounter; masterMessage.ballIsPoint = ((long)theBall.isRect.top << 16) | (long)theBall.isRect.left; masterMessage.eraserPoint = ((long)theBall.eraser.top << 16) | (long)theBall.eraser.left; masterMessage.playerIsPoint = ((long)thePlayer.isRect.top << 16) | (long)thePlayer.isRect.left; masterMessage.opponentIsPoint = ((long)theOpponent.isRect.top << 16) | (long)theOpponent.isRect.left; masterMessage.opponentXPos = theOpponent.xPos; masterMessage.opponentZPos = theOpponent.zPos; masterMessage.playerArrayDirSrc = (char)thePlayer.dirFlagSrc; masterMessage.playerPostArray = ((char)thePlayer.postFlagSrc << 4) | (char)thePlayer.arrayFlagMask; masterMessage.playerDirPostMask = ((char)thePlayer.dirFlagMask << 4) | (char)thePlayer.postFlagMask; masterMessage.opponentArrayDirSrc = (char)theOpponent.dirFlagSrc; masterMessage.opponentPostArray = ((char)theOpponent.postFlagSrc << 4) | (char)theOpponent.arrayFlagMask; masterMessage.opponentDirPostMask = ((char)theOpponent.dirFlagMask << 4) | (char)theOpponent.postFlagMask; masterMessage.ballWhosMode = ((char)theBall.mode << 4) | (char)antiWhosBall[whosGotBall]; masterMessage.playerOpponentMode = ((char)thePlayer.mode << 4) | (char)theOpponent.mode; masterMessage.bitFlags = ((char)theBall.dontDraw << 4) | ((char)theBall.eraseTheBall << 3) | ((char)theDoor.doorOpen << 2) | ((char)theDoor.doorState << 1) | (char)playerInBack; masterMessage.packedFoulsRead = ((char)opponentFouls << 4) | (char)playerFouls; masterMessage.playerScoreReads = playerScore; masterMessage.opponentScoreReads = opponentScore; masterMessage.soundPlayed = (unsigned char)wasLastSound; } else { slaveMessage.messageType = frameCounter; if (netMirroring) slaveMessage.mouseH = -thePlayer.hMouse; else slaveMessage.mouseH = thePlayer.hMouse; slaveMessage.mouseV = thePlayer.vMouse; slaveMessage.bits = ((char)thePlayer.bashApplied << 2) | ((char)thePlayer.buttonIs << 1) | (char)thePlayer.brakeApplied; } } /*======================================================== SendMessage */ void SendMessage (void) { OSErr theErr; if (imTheMaster) theErr = SendOutgoingDDP((long)&masterMessage, masterSendSize); else theErr = SendOutgoingDDP((long)&slaveMessage, slaveSendSize); } /*======================================================== SendModalMessage */ Boolean SendModalMessage (short theMessage) { long timeOut; OSErr theErr; Boolean modeConfirmed; if (imTheMaster) masterMessage.messageType = theMessage; else slaveMessage.messageType = theMessage; timeOut = Ticks + 240L; modeConfirmed = FALSE; while ((Ticks < timeOut) && (!modeConfirmed)) { if (imTheMaster) { theErr = SendOutgoingDDP((long)&masterMessage, masterSendSize); theErr = PollSpecificDDP ((long)&slaveMessage, slaveSendSize, 3); if ((theErr == noErr) && (slaveMessage.messageType == kConfirmMessage)) { modeConfirmed = TRUE; } } else { theErr = SendOutgoingDDP((long)&slaveMessage, slaveSendSize); theErr = PollSpecificDDP ((long)&masterMessage, masterSendSize, 3); if ((theErr == noErr) && (masterMessage.messageType == kConfirmMessage)) { modeConfirmed = TRUE; } } } if (modeConfirmed) return(TRUE); else return(FALSE); } /*======================================================== ConfirmModalMessage */ void ConfirmModalMessage (void) { OSErr theErr; if (imTheMaster) { masterMessage.messageType = kConfirmMessage; theErr = SendOutgoingDDP((long)&masterMessage, masterSendSize); } else { slaveMessage.messageType = kConfirmMessage; theErr = SendOutgoingDDP((long)&slaveMessage, slaveSendSize); } } /*======================================================== ReceiveMessage */ void ReceiveMessage (void) { OSErr theErr; Boolean itWorked; #if kDemoVersion return; #else if (imTheMaster) theErr = PollSpecificDDP ((long)&slaveMessage, slaveSendSize, loopDelay); else theErr = PollSpecificDDP ((long)&masterMessage, masterSendSize, loopDelay); madeThePickUp = FALSE; if (theErr == noErr) { if (imTheMaster) newFrameCount = slaveMessage.messageType; else newFrameCount = masterMessage.messageType; switch (newFrameCount) { case kGameIsOverMessage: ConfirmModalMessage(); itWorked = WhatsTheGamesOutcome(); if (playerScore > opponentScore) { lengthOfApplause = 1500; StartApplauseSound(); } else { lengthOfMob = 1500; StartMobSound(); } DoSlaveGameOver(); break; case kInstantReplayMessage: ConfirmModalMessage(); DoInstantReplay(); break; case kAbortGameMessage: ConfirmModalMessage(); if (!gameIsOver) { TurnSMSOff(); FlushEvents(everyEvent, kRemoveAllEvents); MinorError(kMinorOpponentAborted); } primaryMode = kIdleMode; break; case kEndGameMessage: ConfirmModalMessage(); gameIsOver = TRUE; primaryMode = kIdleMode; break; case kConfirmMessage: break; default: if ((newFrameCount < frameCounter) && (loopDelay < 3)) loopDelay++; else if ((newFrameCount > frameCounter) && (loopDelay > 1)) loopDelay--; TranslateStandardMessage(); if (imTheMaster) frameCounter = newFrameCount; lastFrameCount = newFrameCount; madeThePickUp = TRUE; if (frameCounter < 32000) { frameCounter++; } else { frameCounter = 0; newFrameCount = 0; lastFrameCount = 0; } break; } } #endif } /*======================================================== TranslateStandardMessage */ void TranslateStandardMessage (void) { short wasGotBall, wasPlayerFouls, wasOpponentFouls; short rawPlayerDirSrc, rawPlayerDirMask; short rawOpponentDirSrc, rawOpponentDirMask; Boolean tempDoorState; #if kDemoVersion return; #else if (imTheMaster) { theOpponent.hMouse = slaveMessage.mouseH; theOpponent.vMouse = slaveMessage.mouseV; theOpponent.bashApplied = (Boolean)((slaveMessage.bits >> 2) & 0x01); theOpponent.buttonIs = (Boolean)((slaveMessage.bits >> 1) & 0x01); theOpponent.brakeApplied = (Boolean)(slaveMessage.bits & 0x01); } else { if (netMirroring) { theBall.isRect.left = screenWide - LoWrd(masterMessage.ballIsPoint) - 16; theBall.eraser.left = screenWide - LoWrd(masterMessage.eraserPoint) - 16; theOpponent.isRect.left = screenWide - LoWrd(masterMessage.playerIsPoint) - 32; thePlayer.isRect.left = screenWide - LoWrd(masterMessage.opponentIsPoint) - 32; theDoor.doorOpen = !(Boolean)((masterMessage.bitFlags >> 2) & 0x01); thePlayer.xPos = -masterMessage.opponentXPos; thePlayer.zPos = masterMessage.opponentZPos; } else { theBall.isRect.left = LoWrd(masterMessage.ballIsPoint); theBall.eraser.left = LoWrd(masterMessage.eraserPoint); theOpponent.isRect.left = LoWrd(masterMessage.playerIsPoint); thePlayer.isRect.left = LoWrd(masterMessage.opponentIsPoint); theDoor.doorOpen = (Boolean)((masterMessage.bitFlags >> 2) & 0x01); thePlayer.xPos = masterMessage.opponentXPos; thePlayer.zPos = masterMessage.opponentZPos; } theBall.isRect.top = HiWrd(masterMessage.ballIsPoint); theBall.isRect.right = theBall.isRect.left + 16; theBall.isRect.bottom = theBall.isRect.top + 12; theBall.eraser.top = HiWrd(masterMessage.eraserPoint); theBall.eraser.right = theBall.eraser.left + 16; theBall.eraser.bottom = theBall.eraser.top + 12; theOpponent.isRect.top = HiWrd(masterMessage.playerIsPoint); theOpponent.isRect.right = theOpponent.isRect.left + 32; theOpponent.isRect.bottom = theOpponent.isRect.top + 44; thePlayer.isRect.top = HiWrd(masterMessage.opponentIsPoint); thePlayer.isRect.right = thePlayer.isRect.left + 32; thePlayer.isRect.bottom = thePlayer.isRect.top + 44; theOpponent.arrayFlagMask = (short)(masterMessage.playerPostArray & 0x0F); thePlayer.arrayFlagMask = (short)(masterMessage.opponentPostArray & 0x0F); rawPlayerDirSrc = (short)(masterMessage.playerArrayDirSrc & 0x0F); rawPlayerDirMask = (short)((masterMessage.playerDirPostMask >> 4) & 0x0F); rawOpponentDirSrc = (short)(masterMessage.opponentArrayDirSrc & 0x0F); rawOpponentDirMask = (short)((masterMessage.opponentDirPostMask >> 4) & 0x0F); if (netMirroring) { if (theOpponent.arrayFlagMask == kFadeMask) { theOpponent.dirFlagSrc = rawPlayerDirSrc; theOpponent.dirFlagMask = rawPlayerDirMask; } else { theOpponent.dirFlagSrc = antiFacing[rawPlayerDirSrc]; theOpponent.dirFlagMask = antiFacing[rawPlayerDirMask]; } if (thePlayer.arrayFlagMask == kFadeMask) { thePlayer.dirFlagSrc = rawOpponentDirSrc; thePlayer.dirFlagMask = rawOpponentDirMask; } else { thePlayer.dirFlagSrc = antiFacing[rawOpponentDirSrc]; thePlayer.dirFlagMask = antiFacing[rawOpponentDirMask]; } } else { theOpponent.dirFlagSrc = rawPlayerDirSrc; theOpponent.dirFlagMask = rawPlayerDirMask; thePlayer.dirFlagSrc = rawOpponentDirSrc; thePlayer.dirFlagMask = rawOpponentDirMask; } theOpponent.postFlagSrc = (short)((masterMessage.playerPostArray >> 4) & 0x0F); theOpponent.postFlagMask = (short)(masterMessage.playerDirPostMask & 0x0F); thePlayer.postFlagSrc = (short)((masterMessage.opponentPostArray >> 4) & 0x0F); thePlayer.postFlagMask = (short)(masterMessage.opponentDirPostMask & 0x0F); theBall.mode = (masterMessage.ballWhosMode >> 4) & 0x0F; wasGotBall = whosGotBall; whosGotBall = (short)(masterMessage.ballWhosMode & 0x0F); if (whosGotBall != wasGotBall) { switch (whosGotBall) { case kPlayerHasBall: theOpponent.loopsBallHeld = 0; if (thePlayer.loopsBallHeld == 0) thePlayer.loopsBallHeld = kLoopLimitOnHeldBall; break; case kOpponentHasBall: thePlayer.loopsBallHeld = 0; if (theOpponent.loopsBallHeld == 0) theOpponent.loopsBallHeld = kLoopLimitOnHeldBall; break; case kBallIsNotHere: thePlayer.loopsBallHeld = 0; theOpponent.loopsBallHeld = 0; break; default: break; } UpdateBallTimers(&thePlayer); UpdateBallTimers(&theOpponent); UpdateArrows(); } thePlayer.mode = masterMessage.playerOpponentMode & 0x0F; theOpponent.mode = (masterMessage.playerOpponentMode >> 4) & 0x0F; theBall.dontDraw = (Boolean)((masterMessage.bitFlags >> 4) & 0x01); theBall.eraseTheBall = (Boolean)((masterMessage.bitFlags >> 3) & 0x01); tempDoorState = (Boolean)((masterMessage.bitFlags >> 1) & 0x01); if (tempDoorState != theDoor.doorState) theDoor.stateChanged = TRUE; theDoor.doorState = tempDoorState; playerInBack = !((Boolean)(masterMessage.bitFlags & 0x01)); wasPlayerFouls = playerFouls; playerFouls = (masterMessage.packedFoulsRead >> 4) & 0x0F; if (wasPlayerFouls != playerFouls) { lengthOfMob = 90; StartMobSound(); DisplayPlayerFouls(playerFouls); } wasOpponentFouls = opponentFouls; opponentFouls = masterMessage.packedFoulsRead & 0x0F; if (wasOpponentFouls != opponentFouls) { lengthOfApplause = 90; StartApplauseSound(); DisplayOpponentFouls(opponentFouls); } if (masterMessage.playerScoreReads > opponentScore) { opponentScore = masterMessage.playerScoreReads; lengthOfMob = 120; StartMobSound(); UpdateOpponentScore(); } if (masterMessage.opponentScoreReads > playerScore) { playerScore = masterMessage.opponentScoreReads; lengthOfApplause = 120; StartApplauseSound(); UpdatePlayerScore(); } wasLastSound = (short)masterMessage.soundPlayed; } #endif } /*======================================================== InitializeMessages */ void InitializeMessages (void) { if (!imTheMaster) { masterMessage.messageType = 0; masterMessage.ballIsPoint = ((long)theBall.isRect.top << 16) | (long)theBall.isRect.left; masterMessage.eraserPoint = ((long)theBall.eraser.top << 16) | (long)theBall.eraser.left; masterMessage.playerIsPoint = ((long)theOpponent.isRect.top << 16) | (long)theOpponent.isRect.left; masterMessage.opponentIsPoint = ((long)thePlayer.isRect.top << 16) | (long)thePlayer.isRect.left; masterMessage.playerArrayDirSrc = (char)theOpponent.dirFlagSrc; masterMessage.playerPostArray = ((char)theOpponent.postFlagSrc << 4) | (char)theOpponent.arrayFlagMask; masterMessage.playerDirPostMask = ((char)theOpponent.dirFlagMask << 4) | (char)theOpponent.postFlagMask; masterMessage.opponentArrayDirSrc = (char)thePlayer.dirFlagSrc; masterMessage.opponentPostArray = ((char)thePlayer.postFlagSrc << 4) | (char)thePlayer.arrayFlagMask; masterMessage.opponentDirPostMask = ((char)thePlayer.dirFlagMask << 4) | (char)thePlayer.postFlagMask; masterMessage.ballWhosMode = ((char)theBall.mode << 4) | (char)antiWhosBall[whosGotBall]; masterMessage.playerOpponentMode = ((char)theOpponent.mode << 4) | (char)thePlayer.mode; masterMessage.bitFlags = ((char)theBall.dontDraw << 4) | ((char)theBall.eraseTheBall << 3) | ((char)theDoor.doorOpen << 2) | ((char)theDoor.doorState << 1) | (char)playerInBack; masterMessage.packedFoulsRead = ((char)playerFouls << 4) | (char)opponentFouls; masterMessage.playerScoreReads = playerScore; masterMessage.opponentScoreReads = opponentScore; masterMessage.soundPlayed = (unsigned char)wasLastSound; } else { slaveMessage.messageType = 0; if (netMirroring) slaveMessage.mouseH = -theOpponent.hMouse; else slaveMessage.mouseH = theOpponent.hMouse; slaveMessage.mouseV = theOpponent.vMouse; slaveMessage.bits = 0x00; } } /*======================================================== SpotPoints */ Boolean SpotPoints (void) { #define rSpotDialogID 191 #define kButtSpotOkay 1 #define kEditSpotPoints 2 #define kUserBalloonNames 4 #define kNamesTitleLeft 6 #define kNamesTitleTop 16 DialogPtr spotDialog; PicHandle thePict; Handle iHandle; Rect iRect; Str255 tempStr; long tempLong; short itemHit, iType; Boolean leaveDialog, userOkayed; CenterDialog(rSpotDialogID); if (doZooms) ZoomOutDialogRect(rSpotDialogID); NumToString(speedFlag, tempStr); spotPoints = 0; ParamText("\p4", tempStr, "\p", "\p"); spotDialog = GetNewDialog(rSpotDialogID, kNilPointer, kPutInFront); SetPort((GrafPtr)spotDialog); ShowWindow((GrafPtr)spotDialog); GetDItem(spotDialog, kUserBalloonNames, &iType, &iHandle, &iRect); if (isColor) thePict = GetPicture(kBalloon4PictID); else thePict = GetPicture(kBalloon1PictID); if (thePict != kNilPointer) { DrawPicture(thePict, &iRect); ReleaseResource((Handle)thePict); } GetIndString(tempStr, rMiscStrings, 11); if (tempStr[0] == 0) PasStringCopy((StringPtr)"\pSpot PointsÉ", (StringPtr)tempStr); MoveTo(kNamesTitleLeft, kNamesTitleTop); DrawString(tempStr); DrawDefaultButton(spotDialog, kButtSpotOkay); SelIText(spotDialog, kEditSpotPoints, 0, 32767); leaveDialog = FALSE; while (!leaveDialog) { ModalDialog(kNilPointer, &itemHit); switch (itemHit) { case kButtSpotOkay: GetDItem(spotDialog, kEditSpotPoints, &iType, &iHandle, &iRect); GetIText(iHandle, tempStr); StringToNum(tempStr, &tempLong); spotPoints = (short)tempLong; if ((spotPoints > 4) || (spotPoints < 0)) { SysBeep(20); SelIText(spotDialog, kEditSpotPoints, 0, 32767); } else { userOkayed = TRUE; leaveDialog = TRUE; } break; default: break; } } DisposDialog(spotDialog); return (userOkayed); }