home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 November: Tool Chest / Dev.CD Nov 00 TC Disk 1.toast / Sample Code / Games / SprocketInvaders / Source / NetSprocketSupport.c < prev    next >
Encoding:
Text File  |  2000-09-28  |  19.4 KB  |  885 lines  |  [TEXT/CWIE]

  1. /*
  2.     File:        NetSprocketSupport.c
  3.  
  4.     Contains:    xxx put contents here xxx
  5.  
  6.     Version:    xxx put version here xxx
  7.  
  8.     Copyright:    © 1999 by Apple Computer, Inc., all rights reserved.
  9.  
  10.     File Ownership:
  11.  
  12.         DRI:                xxx put dri here xxx
  13.  
  14.         Other Contact:        xxx put other contact here xxx
  15.  
  16.         Technology:            xxx put technology here xxx
  17.  
  18.     Writers:
  19.  
  20.         (cjd)    Chris De Salvo
  21.  
  22.     Change History (most recent first):
  23.  
  24.        <SP7>      3/3/99    cjd        Updated chat window UI code
  25. */
  26.  
  27. //•    ------------------------------------------------------------------------------------------    •
  28. //•
  29. //•    Copyright © 1996 Apple Computer, Inc., All Rights Reserved
  30. //•
  31. //•
  32. //•        You may incorporate this sample code into your applications without
  33. //•        restriction, though the sample code has been provided "AS IS" and the
  34. //•        responsibility for its operation is 100% yours.  However, what you are
  35. //•        not permitted to do is to redistribute the source as "DSC Sample Code"
  36. //•        after having made changes. If you're going to re-distribute the source,
  37. //•        we require that you make it clear in the source that the code was
  38. //•        descended from Apple Sample Code, but that you've made changes.
  39. //•
  40. //•        Authors:
  41. //•            Jamie Osborne
  42. //•
  43. //•    ------------------------------------------------------------------------------------------    •
  44.  
  45. //•    ------------------------------    Includes
  46.  
  47. #include <ControlDefinitions.h>
  48. #include <Dialogs.h>
  49. #include <Fonts.h>
  50. #include <Lists.h>
  51. #include <QDOffScreen.h>
  52. #include <Resources.h>
  53. #include <Sound.h>
  54. #include <TextEdit.h>
  55. #include <TextUtils.h>
  56.  
  57. #include "CommonStuff.h"
  58. #include "EventHandler.h"
  59. #include "NetSprocketSupport.h"
  60.  
  61. //•    ------------------------------    Private Definitions
  62. //•    ------------------------------    Private Types
  63.  
  64. enum
  65. {
  66.     kWaitForPlayersDialogID = 1000
  67. };
  68.  
  69. enum
  70. {
  71.     kOKButton = 1, 
  72.     kCancelButton,
  73.     kPlayerListLabel,
  74.     kPlayerList,
  75.     kChatWindow,
  76.     kChatTextEntry,
  77.     kStatus
  78. };
  79.         
  80. typedef struct DialogInfo
  81. {
  82.     ListHandle    playerList;
  83.     TEHandle    teHandle;
  84.     Str32        nameListBuffer[kMaxPlayers];
  85. } DialogInfo;
  86.  
  87. //•    ------------------------------    Private Variables
  88. //•    ------------------------------    Private Functions
  89.  
  90. static void GetChooserName(Str255 name);
  91. static void SendChatText(StringPtr inText, NSpPlayerID inTo);
  92. static void DoHandleMessage(NSpMessageHeader *inMessage);
  93. static pascal void PlayerListProc(WindowPtr dialog, SInt16 itemNo);
  94. static pascal void ChatViewProc(WindowPtr dialog, SInt16 itemNo);
  95. static void SetDialogtemUserProc(DialogPtr dialog, SInt16 item, UserItemUPP theProc);
  96. static void WatchForPlayers(DialogPtr dialog);
  97. static OSStatus SendWelcomeMessage(NSpPlayerID inID);
  98. static void MakePlayerList(DialogPtr dialog);
  99. static void SendText(DialogPtr dialog);
  100.  
  101. static pascal Boolean DialogEventFilter(DialogPtr dialog, EventRecord *event, SInt16 *itemHit);
  102.  
  103. static void DoHandleChatTextMessage(ChatTextMessage *inMessage, DialogPtr dialog);
  104. static void PrintPlayerText(StringPtr inText, NSpPlayerID inPlayer, TEHandle inTEHandle);
  105.  
  106. static void DoHandlePlayerInput(PlayerInputMessage *inMessage);
  107. static void DoHandleEndGameMessage(void);
  108. static void DoHandleStartGame(StartGameMessage *inMessage);
  109. static void DisableDialogItem(DialogPtr theDialog, SInt16 theItem);
  110.  
  111. //•    ------------------------------    Public Variables
  112.  
  113. NSpGameReference    gNetGame = NULL;
  114. Boolean                gIAmHost = false;
  115. Str31                kNetworkGameName = "\pNetSprocket Game";
  116. Str31                kJoinDialogLabel = "\pChoose a Game:";
  117. Str31                 kNBPType = "\pInvd";        // This should be the same as kGameID
  118. NetworkState        gNetState;
  119. Str31                kSeparatorString = "\p: ";
  120. SInt8                kReturn = '\r';
  121. Boolean                gGotEndGameMessage = false;
  122. Boolean                gReceivedInput;
  123. Boolean                gNetSprocketPresent;
  124.  
  125. #pragma mark === Utility functions ===
  126.  
  127. //•    --------------------    NetSprocketPresent
  128. //•
  129. //•    returns TRUE if networking is present, FALSE otherwise
  130.  
  131. Boolean
  132. NetSprocketPresent(void)
  133. {
  134.     return (NSpInitialize != nil);
  135. }
  136.  
  137. //•    --------------------    GetChooserName
  138.  
  139. static void
  140. GetChooserName(Str255 name)
  141. {
  142. StringHandle    userName;
  143.     
  144.     userName = GetString(-16096);
  145.     FAIL_NIL(userName, "GetString for Chooser Name failed");
  146.     
  147.     CopyPStr(*userName, name);
  148.     ReleaseResource ((Handle) userName);
  149.  
  150. error:
  151.     return;
  152. }
  153.  
  154. #pragma mark === Networking stuff ===
  155.  
  156. //•    --------------------    InitNetworking
  157.  
  158. Boolean
  159. InitNetworking(void)
  160. {
  161. OSStatus    status;
  162.     
  163.     if (! NetSprocketPresent())
  164.         return (false);
  165.         
  166.     //•    Initialize NetSprocket
  167.     status = NSpInitialize(kStandardMessageSize, kBufferSize, kQElements, kGameID, kTimeout);
  168.     FAIL_OSSTATUS(status, "NSpInitialize failed");
  169.     if (status != noErr)
  170.         return (false);
  171.  
  172.     gNetState = kSlacking;
  173.     
  174.     return (true);
  175.     
  176. error:
  177.     return (false);
  178. }
  179.  
  180. //•    --------------------    ShutdownNetworking
  181.  
  182. void
  183. ShutdownNetworking(void)
  184. {
  185. OSStatus    status;
  186.     
  187.     if (gNetGame)
  188.         status = NSpGame_Dispose( gNetGame, kNSpGameFlag_ForceTerminateGame );
  189.  
  190.     gNetState = kSlacking;
  191.     gNetGame = NULL;
  192. }
  193.  
  194.  
  195. //•    --------------------    DoHostGame
  196. //•
  197. //•    Returns TRUE if the user says OK (and NetSprocket doesn't return an error), false otherwise
  198.  
  199. Boolean
  200. DoHostGame(void)
  201. {
  202. OSStatus                    status = noErr;
  203. NSpProtocolListReference    theList = NULL;
  204. Str31                        playerName, gameName, password;
  205. Boolean                     OKHit;
  206.     
  207.     status = NSpProtocolList_New(NULL, &theList);
  208.     FAIL_OSSTATUS(status, "Couldn't create a protocol list");
  209.         
  210.     //    Do the host dialog
  211.     GetChooserName(playerName);
  212.     CopyPStr(kNetworkGameName, gameName);
  213.     password[0] = 0;
  214.  
  215.     OKHit = NSpDoModalHostDialog(theList, gameName, playerName, password, NULL);
  216.     if (!OKHit)
  217.         return (false);
  218.         
  219.     //    Now host the game
  220.     status = NSpGame_Host(&gNetGame, theList, kMaxPlayers, gameName,
  221.                 password, playerName, 0, kNSpClientServer, 0);
  222.  
  223.     FAIL_OSSTATUS(status, "NSpGame_Host returned an error");
  224.     
  225.     NSpProtocolList_Dispose(theList);
  226.     gIAmHost = true;
  227.     gNetState = kHosting;
  228.     
  229.     // let all the players join
  230.     OKHit = WaitForAllPlayers();
  231.  
  232.     if (OKHit == false)
  233.     {
  234.         ShutdownNetworking();
  235.         return (false);        
  236.     }
  237.     else
  238.     {
  239.         gNetState = kStarting;
  240.         SendStartGame();
  241.     }
  242.     
  243.     return (true);
  244.     
  245. error:
  246.  
  247.     if (theList)
  248.         NSpProtocolList_Dispose(theList);
  249.         
  250.     return (false);
  251. }
  252.  
  253. //•    --------------------    DoJoinGame
  254. //•
  255. //•    Returns TRUE if the user says OK (and NetSprocket doesn't return an error), false otherwise
  256.  
  257. Boolean
  258. DoJoinGame(void)
  259. {
  260. NSpAddressReference    theAddress;
  261. Str31                name;
  262. Str31                password;
  263. OSStatus            status;
  264. Boolean             OKHit = true;
  265.     
  266.     GetChooserName(name);
  267.     password[0] = 0;
  268.     
  269.     gIAmHost = false;
  270.     
  271.     theAddress = NSpDoModalJoinDialog(kNBPType, kJoinDialogLabel, name, password, NULL);
  272.     if (theAddress == NULL)        // The user cancelled
  273.         return (false);
  274.         
  275.     status = NSpGame_Join(&gNetGame, theAddress, name, password, 0, NULL, 0, 0);
  276.     FAIL_OSSTATUS(status, "NSpGame_Join returned an error");
  277.     
  278.     gNetState = kJoining;
  279.  
  280.     OKHit = WaitForAllPlayers();
  281.     if (OKHit == false)
  282.     {
  283.         gNetState = kSlacking;
  284.         ShutdownNetworking();
  285.     }
  286.     
  287.     return OKHit;
  288.     
  289. error:
  290.     return (false);
  291. }
  292.  
  293. //•    --------------------    HandleNetworking
  294.  
  295. void
  296. HandleNetworking(void)
  297. {
  298. NSpMessageHeader    *theMessage;
  299.     
  300.     if (gNetGame == NULL)
  301.         return;
  302.  
  303.     theMessage = NSpMessage_Get(gNetGame);
  304.     if (theMessage != NULL)
  305.     {
  306.         DoHandleMessage(theMessage);
  307.         NSpMessage_Release(gNetGame, theMessage);
  308.     }
  309. }
  310.  
  311. //•    --------------------    DoHandleMessage
  312.  
  313. static void
  314. DoHandleMessage(NSpMessageHeader *inMessage)
  315. {
  316.     switch (inMessage->what)
  317.     {
  318.         case kNSpPlayerJoined:
  319.             break;
  320.             
  321.         case kNSpPlayerLeft:
  322.             break;
  323.             
  324.         case kChatTextMessage:
  325.             DoHandleChatTextMessage((ChatTextMessage *)inMessage, nil);
  326.             break;
  327.             
  328.         case kStartGameMessage:
  329.             DoHandleStartGame((StartGameMessage *) inMessage);
  330.             break;
  331.             
  332.         case kInputMessage:
  333.             DoHandlePlayerInput((PlayerInputMessage *) inMessage);
  334.             break;
  335.             
  336.         case kEndGameMessage:
  337.             DoHandleEndGameMessage();
  338.             break;
  339.             
  340.         default:
  341.             break;
  342.     }
  343. }
  344.  
  345. //•    --------------------    WatchForPlayers
  346.  
  347. static void
  348. WatchForPlayers(DialogPtr dialog)
  349. {
  350. NSpMessageHeader    *theMessage;
  351.     
  352.     if (gNetGame == NULL)
  353.         return;
  354.  
  355.     while ((theMessage = NSpMessage_Get(gNetGame)) != NULL)
  356.     {
  357.         if (theMessage->what == kNSpPlayerJoined)
  358.         {
  359.             if (gNetState == kHosting)
  360.                 SendWelcomeMessage(((NSpPlayerJoinedMessage *) theMessage)->playerInfo.id);
  361.             
  362.             MakePlayerList(dialog);    
  363.         }
  364.         else if (theMessage->what == kNSpPlayerLeft) 
  365.         {
  366.             MakePlayerList(dialog);    
  367.         }
  368.         else if (theMessage->what == kChatTextMessage)
  369.         {
  370.             DoHandleChatTextMessage((ChatTextMessage *)theMessage, dialog);
  371.         }
  372.         else
  373.         {
  374.             DoHandleMessage(theMessage);
  375.         }
  376.             
  377.         NSpMessage_Release(gNetGame, theMessage);
  378.     }
  379. }
  380.  
  381. //•    --------------------    SendWelcomeMessage
  382.  
  383. static OSStatus
  384. SendWelcomeMessage(NSpPlayerID inID)
  385. {
  386. #pragma unused (inID)
  387. OSStatus    status = noErr;
  388.     
  389.     return (status);
  390. }
  391.  
  392. #pragma mark === Dialog Manager Cruft
  393.  
  394. //•    --------------------    SetDialogtemUserProc
  395.  
  396. static void
  397. SetDialogtemUserProc(DialogPtr dialog, SInt16 item, UserItemUPP theProc)
  398. {
  399. Rect     r;
  400. SInt16    itemType;
  401. Handle    itemH;
  402.  
  403.     GetDialogItem(dialog, item, &itemType, &itemH, &r);
  404.     itemH = (Handle) theProc;
  405.     SetDialogItem(dialog, item, itemType, itemH, &r);
  406. }
  407.  
  408. //•    --------------------    MakePlayerList
  409.  
  410. static void
  411. MakePlayerList(DialogPtr dialog)
  412. {
  413. SInt16                    i;
  414. Cell                    theCell;
  415. NSpPlayerEnumerationPtr    players;
  416. OSStatus                status;
  417. DialogInfo                *theInfo = (DialogInfo *) GetWRefCon(dialog);
  418. ListHandle                theList = theInfo->playerList;
  419.  
  420.     LSetDrawingMode(true, theList);                            // turn on updating
  421.  
  422.     status = NSpPlayer_GetEnumeration(gNetGame, &players);
  423.     FAIL_OSSTATUS(status, "NSpPlayer_GetEnumeration returned an error");
  424.         
  425.     for (i = 0; i < players->count; i++)
  426.         CopyPStr(players->playerInfo[i]->name, theInfo->nameListBuffer[i]);
  427.  
  428.     /* DELETE ALL EXISTING ROWS IN LIST */
  429.     LDelRow(0, 0, theList);
  430.  
  431.     /* ADD NAMES TO LIST */
  432.     if (players->count > 0)
  433.         LAddRow(players->count, 0, theList);        // create rows
  434.  
  435.     for (i = 0; i < players->count; i++)
  436.     {
  437.         theCell.h = 0;
  438.         theCell.v = i;
  439.         LSetCell(&theInfo->nameListBuffer[i][1], theInfo->nameListBuffer[i][0], theCell, theList);
  440.     }
  441.  
  442.     NSpPlayer_ReleaseEnumeration(gNetGame, players);
  443.     
  444. error:
  445.     return;
  446. }
  447.  
  448. //•    --------------------    WaitForAllPlayers
  449.  
  450. Boolean
  451. WaitForAllPlayers(void)
  452. {
  453. DialogPtr        theDialog = GetNewDialog(kWaitForPlayersDialogID, NULL, (WindowPtr) -1);
  454. ListHandle        playerList;
  455. SInt16             itemHit;
  456. Boolean         okHit = false;
  457. Rect             r, dataBounds = {0,0,0,1};
  458. Point            cellSize = {0,0};
  459. SInt16            itemType;
  460. Handle            itemH;
  461. DialogInfo        info;
  462. TextStyle        theStyle;
  463. ControlHandle    theControl;
  464.     
  465.     ModalFilterUPP theFilter = NewModalFilterProc(DialogEventFilter);
  466.     UserItemUPP playerListProc = NewUserItemProc(PlayerListProc);
  467.     UserItemUPP chatViewProc = NewUserItemProc(ChatViewProc);
  468.     
  469.     // NOTE: check okUserItemProcUPP != NULL
  470.     
  471.     if (theDialog == NULL)
  472.         return (false);
  473.     
  474.     SetPort(theDialog);
  475.     SetDialogDefaultItem(theDialog, kOKButton);
  476.     SetDialogCancelItem(theDialog, kCancelButton);
  477.  
  478.     SetDialogtemUserProc(theDialog, kPlayerList, playerListProc);
  479.     SetDialogtemUserProc(theDialog, kChatWindow, chatViewProc);
  480.  
  481.     (void) GetDialogItemAsControl(theDialog, kChatTextEntry, &theControl);
  482.     (void) SetKeyboardFocus(theDialog, theControl, kControlLabelPart);
  483.  
  484.  
  485.     //    Now create the list of players
  486.     GetDialogItem(theDialog, kPlayerList, &itemType, &itemH, &r);
  487.     r.right -= 15;
  488.     
  489.     playerList = LNew(&r, &dataBounds, cellSize, 0, theDialog, true,
  490.                     false, false, true);
  491.     
  492.     info.playerList = playerList;
  493.  
  494.     //    Set up the text edut stuff
  495.     GetDialogItem(theDialog, kChatWindow, &itemType, &itemH, &r);
  496.     InsetRect(&r, 2, 2);
  497.     
  498.     info.teHandle = TEStyleNew(&r, &r);
  499.     TEAutoView(true, info.teHandle);
  500.  
  501.     //    Set up the default drawing info
  502.     theStyle.tsFont = kFontIDMonaco;
  503.     theStyle.tsSize = 9;
  504.     theStyle.tsColor.red = 0;
  505.     theStyle.tsColor.green = 0;
  506.     theStyle.tsColor.blue = 0;
  507.     theStyle.tsFace = normal;
  508.     TESetStyle(doAll, &theStyle, true, info.teHandle);
  509.     
  510.     //    If we're the joiner, disable the OK button
  511.     if (gNetState == kJoining)
  512.         DisableDialogItem(theDialog, kOKButton);
  513.     
  514.     //    Save our custom stuff in the refcon
  515.     SetWRefCon(theDialog, (SInt32) &info);
  516.     
  517.     ShowWindow(theDialog);
  518.     DrawControls(theDialog);
  519.         
  520.     do
  521.     {
  522.         ModalDialog(theFilter, &itemHit);
  523.     } while (itemHit != kOKButton && itemHit != kCancelButton);
  524.     
  525.     LDispose(playerList);
  526.     DisposeDialog(theDialog);
  527.     
  528.     DisposeRoutineDescriptor(theFilter);
  529.     DisposeRoutineDescriptor(playerListProc);
  530.     DisposeRoutineDescriptor(chatViewProc);
  531.     
  532.     okHit = (itemHit == kOKButton || gNetState == kRunning);
  533.  
  534.     return (okHit);
  535. }
  536.  
  537. //•    --------------------    DisableDialogItem
  538.  
  539. static void
  540. DisableDialogItem(DialogPtr theDialog, SInt16 theItem)
  541. {
  542. SInt16    theType;
  543. Rect    theRect;
  544. Handle    theHandle;
  545.  
  546.     if (! theDialog)
  547.         return;
  548.  
  549.     GetDialogItem(theDialog, theItem, &theType, &theHandle, &theRect);
  550.  
  551.     if (! theHandle)
  552.         return;
  553.  
  554.     HiliteControl((ControlHandle) theHandle, 255);
  555.     theType |= kItemDisableBit;
  556.     SetDialogItem(theDialog, theItem, theType, theHandle, &theRect);
  557. }
  558.  
  559. #pragma mark === Callback Procs ===
  560.  
  561. //•    --------------------    PlayerListProc
  562.  
  563. static pascal void
  564. PlayerListProc(WindowPtr dialog, SInt16 itemNo)
  565. {
  566. Rect         r;
  567. SInt16        itemType;
  568. Handle        item;
  569. GrafPtr        theWindow = (GrafPtr) dialog;
  570. DialogInfo    *theInfo = (DialogInfo *)GetWRefCon(dialog);
  571. ListHandle    list = theInfo->playerList;
  572.  
  573.     if (itemNo == kPlayerList)
  574.     {    
  575.         GetDialogItem(dialog, itemNo, &itemType, &item, &r);
  576.         InsetRect(&r, -1, -1);
  577.         FrameRect(&r);
  578.         LUpdate(theWindow->visRgn, list);
  579.     }
  580. }
  581.  
  582. //•    --------------------    ChatViewProc
  583.  
  584. static pascal void
  585. ChatViewProc(WindowPtr dialog, SInt16 itemNo)
  586. {
  587. Rect         r;
  588. SInt16        itemType;
  589. Handle        item;
  590. DialogInfo *theInfo;
  591.     
  592.     GetDialogItem(dialog, itemNo, &itemType, &item, &r);
  593.     theInfo = (DialogInfo *)GetWRefCon(dialog);
  594.  
  595.     FrameRect(&r);
  596.     InsetRect(&r, 2, 2);
  597.     TEUpdate(&r, theInfo->teHandle);
  598.     
  599. }
  600.  
  601. //•    --------------------    DialogEventFilter
  602.  
  603. static pascal Boolean
  604. DialogEventFilter(DialogPtr dialog, EventRecord *event, SInt16 *itemHit)
  605. {
  606. OSErr                err;
  607. CGrafPtr            oldPort;
  608. GDHandle            oldGD;
  609. WindowRef            window;
  610. ModalFilterUPP        modalProc;
  611. Rect                itemRect;
  612. SInt16                key;
  613. SInt16                thePart;
  614. Boolean                accepted = false;
  615. Point theP;
  616. Boolean                hit;
  617. DialogInfo            *theInfo;
  618.     
  619.     GetGWorld(&oldPort, &oldGD);
  620.     SetGWorld((CGrafPtr)dialog, nil);
  621.  
  622.     IdleControls(dialog);
  623.  
  624.     WatchForPlayers(dialog);
  625.     if (gNetState == kRunning)
  626.     {
  627.         *itemHit = kOKButton;
  628.         return (true);
  629.     }
  630.  
  631.     switch(event->what) 
  632.     {
  633.         case keyDown:
  634.         case autoKey:
  635.             key = event->message & charCodeMask;
  636.             if (key == 0x0D)
  637.             {
  638.                 SendText(dialog);
  639.                 accepted = true;
  640.             }
  641.             else if (key == '\t')
  642.             {
  643.                 if (event->modifiers & shiftKey)
  644.                     ReverseKeyboardFocus(dialog);
  645.                 else
  646.                     AdvanceKeyboardFocus(dialog);
  647.             }
  648.             else
  649.             {
  650.                 accepted = false;
  651.             }
  652.                 
  653.             break;
  654.     
  655.         case updateEvt:
  656.             if (event->message == (SInt32)dialog) 
  657.             {
  658.                 // in case a screen saver activates.
  659.                 UpdateDialog(dialog, dialog->visRgn);
  660.  
  661.                 SetCursor(&qd.arrow);
  662.             }    
  663.             break;
  664.  
  665.         case activateEvt:
  666.             accepted = true;
  667.             break;
  668.             
  669.         case mouseDown:    
  670.             thePart = FindWindow(event->where,&window);
  671.     
  672.             switch (thePart) 
  673.             {
  674.                 case inContent:
  675.                     theP = event->where;
  676.                     GlobalToLocal(&theP);
  677.  
  678.                     theInfo = (DialogInfo *)GetWRefCon(dialog);
  679.                     itemRect = (*theInfo->playerList)->rView;
  680.                     
  681.                     // add the scroll bar back in for hit testing (remember we took it out earlier)
  682.                     itemRect.right += 16;
  683.                     
  684.                     // See if they clicked in our list!
  685.                     if (PtInRect(theP, &itemRect))
  686.                     {
  687.                         hit = LClick(theP, nil, theInfo->playerList);
  688.                         // if they double-clicked the list, return 1, as if the OK button had been pressed
  689.                         if (hit)
  690.                             *itemHit = kOKButton;
  691.                         else
  692.                             *itemHit = kPlayerList;
  693.                         
  694.                         // tell the Dialog Manager that we handled this click, it can stop searching for a click-owner
  695.                         accepted = true;
  696.                     }
  697.                     break;
  698.     
  699.                 case inSysWindow:
  700.                     SysBeep(30);
  701.                     break;
  702.     
  703.                 case inDrag:
  704.                     if (window == dialog) 
  705.                     {
  706.                         DragWindow(dialog, event->where,&qd.screenBits.bounds);
  707.                         accepted = true;
  708.                     }
  709.                     break;
  710.             }
  711.             break;        
  712.     }
  713.     
  714.     if (false == accepted) 
  715.     {
  716.         err = GetStdFilterProc(&modalProc);
  717.         if (err == noErr)
  718.             accepted = CallModalFilterProc(modalProc, dialog, event, itemHit);
  719.     }
  720.     
  721.     SetGWorld(oldPort, oldGD);
  722.  
  723.     return (accepted);
  724. }
  725.  
  726. //•    --------------------    SendText
  727.  
  728. static void
  729. SendText(DialogPtr dialog)
  730. {
  731. ControlHandle    item;
  732. Str255            theText;
  733.     
  734.     (void) GetDialogItemAsControl(dialog, kChatTextEntry, &item);
  735.     GetDialogItemText((Handle) item, theText);
  736.     SetDialogItemText((Handle) item, "\p");
  737.     DrawOneControl(item);
  738.     
  739.     if (theText[0] > 0)
  740.         SendChatText(theText, kNSpAllPlayers);
  741.  
  742. }
  743.  
  744. #pragma mark =====
  745.  
  746. //•    --------------------    SendChatText
  747.  
  748. static void
  749. SendChatText(StringPtr inText, NSpPlayerID inTo)
  750. {
  751. ChatTextMessage    theMessage;
  752. OSStatus         status;
  753.     
  754.     theMessage.h.to = inTo;
  755.     theMessage.h.what = kChatTextMessage;
  756.     theMessage.h.messageLen = sizeof(ChatTextMessage);
  757.     CopyPStr(inText, theMessage.text);
  758.     
  759.     status = NSpMessage_Send(gNetGame, &theMessage.h, kNSpSendFlag_Junk | kNSpSendFlag_SelfSend);
  760. }
  761.  
  762. //•    --------------------    SendStartGame
  763.  
  764. void
  765. SendStartGame(void)
  766. {
  767. StartGameMessage    theMessage;
  768. OSStatus            status;
  769.     
  770.     NSpClearMessageHeader(&theMessage.h);
  771.     theMessage.h.to = kNSpAllPlayers;
  772.     theMessage.h.what = kStartGameMessage;
  773.     theMessage.h.messageLen = sizeof(StartGameMessage);
  774.     theMessage.seed = qd.randSeed;
  775.     
  776.     status = NSpMessage_Send(gNetGame, &theMessage.h, kNSpSendFlag_Registered | kNSpSendFlag_SelfSend);
  777. }
  778.  
  779. //•    --------------------    SendInputState
  780.  
  781. void
  782. SendInputState(Boolean left, Boolean right, Boolean fire)
  783. {
  784. PlayerInputMessage    theMessage;
  785. OSStatus    status;
  786.     
  787.     NSpClearMessageHeader(&theMessage.h);
  788.     theMessage.h.to = kNSpAllPlayers;
  789.     theMessage.h.what = kInputMessage;
  790.     theMessage.h.messageLen = sizeof(PlayerInputMessage);
  791.     theMessage.left = left;
  792.     theMessage.right = right;
  793.     theMessage.fire = fire;
  794.  
  795.     status = NSpMessage_Send(gNetGame, &theMessage.h, kNSpSendFlag_Registered);
  796. }
  797.  
  798. //•    --------------------    SendEndGame
  799.  
  800. void
  801. SendEndGame(void)
  802. {
  803. OSStatus    status;
  804. NSpMessageHeader theMessage;
  805.     
  806.     NSpClearMessageHeader(&theMessage);
  807.     theMessage.to = kNSpAllPlayers;
  808.     theMessage.what = kEndGameMessage;
  809.     theMessage.messageLen = sizeof(NSpMessageHeader);
  810.     
  811.     status = NSpMessage_Send(gNetGame, &theMessage, kNSpSendFlag_Registered);
  812. }
  813.  
  814. //•    --------------------    DoHandleChatTextMessage
  815.  
  816. static void
  817. DoHandleChatTextMessage(ChatTextMessage *inMessage, DialogPtr dialog)
  818. {
  819. DialogInfo    *theInfo;
  820.     
  821.     if (! dialog)
  822.         return;
  823.         
  824.     theInfo = (DialogInfo *)GetWRefCon(dialog);
  825.     PrintPlayerText(inMessage->text, inMessage->h.from, theInfo->teHandle);
  826. }
  827.  
  828. //•    --------------------    DoHandleStartGame
  829.  
  830. static void
  831. DoHandleStartGame(StartGameMessage *inMessage)
  832. {
  833.     gNetState = kRunning;
  834.     qd.randSeed = inMessage->seed;
  835. }
  836.  
  837. //•    --------------------    DoHandlePlayerInput
  838.  
  839. static void
  840. DoHandlePlayerInput(PlayerInputMessage *inMessage)
  841. {
  842.     if (gIAmHost)
  843.     {
  844.         gGameKeys.redLeft = inMessage->left;
  845.         gGameKeys.redRight = inMessage->right;
  846.         gGameKeys.redFire = inMessage->fire;
  847.     }
  848.     else
  849.     {
  850.         gGameKeys.greenLeft = inMessage->left;
  851.         gGameKeys.greenRight = inMessage->right;
  852.         gGameKeys.greenFire = inMessage->fire;
  853.     }    
  854.     gReceivedInput = true;
  855. }
  856.  
  857. //•    --------------------    DoHandleEndGameMessage
  858.  
  859. static void
  860. DoHandleEndGameMessage(void)
  861. {
  862.     gGotEndGameMessage = true;
  863. }
  864.  
  865. //•    --------------------    PrintPlayerText
  866.  
  867. static void
  868. PrintPlayerText(StringPtr inText, NSpPlayerID inPlayer, TEHandle inTEHandle)
  869. {
  870. NSpPlayerInfoPtr    info;
  871.     
  872.     NSpPlayer_GetInfo(gNetGame, inPlayer, &info);
  873.     
  874.     TEInsert(&info->name[1], info->name[0], inTEHandle);
  875.     TEInsert(&kSeparatorString[1], kSeparatorString[0], inTEHandle);
  876.     TEInsert(&inText[1], inText[0], inTEHandle);
  877.     TEInsert(&kReturn, 1, inTEHandle);
  878.  
  879.     //•    Select end of the TE text
  880.     TESetSelect(32767L, 32767L, inTEHandle);
  881.  
  882.     //•    Scroll it into view if necessary
  883.     TESelView(inTEHandle);
  884. }
  885.