home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 4 / Apprentice-Release4.iso / Source Code / C / Snippets / AsynchSnd 1.0.2 / AsynchSnd.c < prev    next >
Encoding:
Text File  |  1995-12-31  |  8.2 KB  |  413 lines  |  [TEXT/CWIE]

  1. // AsynchSnd
  2. // by Ken Long
  3. // updated 951201 for CW7
  4.  
  5. #include <Sound.h>        //• Added by K.A.L for addition of sounds.
  6.  
  7. MenuHandle    appleMenu, fileMenu, editMenu, widthMenu;
  8.  
  9. enum {
  10.     appleID = 1,
  11.     fileID,
  12.     editID,
  13.     widthID
  14. };
  15.  
  16. enum {
  17.     openItem = 1,
  18.     closeItem,
  19.     quitItem = 4
  20. };
  21.  
  22. #define over qd.screenBits.bounds.right
  23. #define down qd.screenBits.bounds.bottom
  24.  
  25. WindowPtr    shellWindow;
  26. Rect        dragRect;
  27. Rect        windowBounds;
  28. Rect        circleStart = {2, 2, 296, 296};
  29. int            theWidth = 2;
  30.  
  31. SndChannelPtr channelPtr;
  32.  
  33. //• Prototypes:
  34. void SetUpWindow (void);
  35. void Center (char *str);
  36. void SetText (short font, short size, short style);
  37. void DoAbout (void);
  38. void DrawBullseye (short active);
  39. void DoTheSound (short whichID, Boolean asynch);
  40. void HandleKeyHits (EventRecord *theEvent);
  41. void SetUpMenus (void);
  42. void AdjustMenus (void);
  43. int enable (MenuHandle menu, short item, short ok);
  44. void HandleMenu (long mSelect);
  45. void InitMacintosh (void);
  46. void HandleMouseDown (EventRecord *theEvent);
  47. void HandleEvent (void);
  48. void main (void);
  49.  
  50. //• Routines:
  51.  
  52. void SetUpWindow(void)
  53. {
  54.     dragRect = qd.screenBits.bounds;
  55.     
  56.     SetRect (&windowBounds, over / 2 - 150,
  57.                             down / 2 - 150,
  58.                             over / 2 + 150,
  59.                             down / 2 + 150);
  60.                             
  61.     shellWindow = NewWindow(0L, &windowBounds, "\pKen's Shell", true, noGrowDocProc, (WindowPtr) -1L, true, 0);
  62.     SetPort(shellWindow);
  63. }
  64.  
  65. void Center (char *str)
  66. {    
  67.     Move ((((circleStart.right - 2) / 2) -
  68.             (StringWidth ((StringPtr) str)) / 2), 0);
  69.     DrawString ((StringPtr) str);
  70.     Move (-(shellWindow->pnLoc.h), (shellWindow->txSize) + 2);
  71. }
  72.  
  73. void SetText (short font, short size, short style)
  74. {
  75.     TextFont (font);
  76.     TextSize (size);
  77.     TextFace (style);
  78. }
  79.  
  80. void DoAbout ()
  81. {
  82.     EraseRect (&circleStart);
  83.     MoveTo (0, 0);
  84.     Move (0, 30);
  85.     SetText (newYork, 18, italic);
  86.     Center ((char*) "\pAn itty bitty bytes™ demo");
  87.     Move (0, 5);
  88.     SetText (newYork, 12, italic);
  89.     Center ((char*) "\pof asynchronous sound play.");
  90.     Move (0, 5);
  91.     SetText (times, 12, outline);
  92.     Center ((char*) "\pPublic Domain (P) November 1994,");
  93.     Move (0, 5);
  94.     Center ((char*) "\pKenneth A. Long.  No rights reserved");
  95.     
  96.     Move (0, 15);
  97.     SetText (0, 12, 0);
  98.     Center ((char*) "\pClick the mouse for some more bull!");
  99.     Move (0, 5);
  100.     Center ((char*) "\pHit number keys as fast as you can.");
  101.     Move (0, 5);
  102.     Center ((char*) "\pHold keys down for continuous sound.");
  103. }
  104.     
  105. void DrawBullseye(short active)
  106. {
  107.     Rect    myRect;
  108.     int        color = true;
  109.     
  110.     SetPort(shellWindow);
  111.     EraseRect(&circleStart);
  112.     myRect = circleStart;
  113.     
  114.     while(myRect.left < myRect.right)
  115.     {
  116.         FrameOval(&myRect);//, color ? (active ? black : gray) : white);
  117. //•     FillOval(&myRect, color ? (active ? black : gray) : white);
  118.         InsetRect(&myRect, theWidth, theWidth);
  119. //•        color = !color;
  120.     } 
  121. }
  122.  
  123. //• The following routine was added by K.A.L.  It was from the Stella 
  124. //• Obscura source, by John Calhoun and ported to C by Ken Long.
  125.  
  126. void DoTheSound (short whichID, Boolean asynch)
  127. {
  128.     Handle theSnd;
  129.     OSErr err;
  130.     Boolean soundActive;
  131.     
  132.     soundActive = true;    
  133.     
  134.     if ((soundActive))
  135.     {
  136.         theSnd = GetResource ('snd ', whichID);
  137.         
  138.         if ((theSnd != 0L) && (ResError () == noErr))
  139.         {
  140.             if ((channelPtr != 0L))
  141.             {
  142.                 err = SndDisposeChannel (channelPtr, true);
  143.                 channelPtr = 0L;
  144.             }
  145.             if ((asynch == true) && 
  146.                 (SndNewChannel 
  147.                 (&channelPtr, 0, initMono, 0L) == noErr)) 
  148.                 err = SndPlay (channelPtr, (SndListHandle)theSnd, true); 
  149.             else    
  150.                 err = SndPlay (0L, (SndListHandle)theSnd, false);
  151.         }
  152.     }
  153. }
  154.  
  155. //• I added this routine to add key hit sound play capability.
  156. void HandleKeyHits (EventRecord *theEvent)
  157. {
  158.     short    chCode;
  159.     long ticks;
  160.     
  161.     chCode = theEvent->message & charCodeMask;
  162.  
  163.     switch (chCode) 
  164.     {
  165.         case '1':  // User hits the 1 key.
  166.                DoTheSound (9001, true);  // '9001' matches res.ID.
  167.         break;
  168.  
  169.         case '2': 
  170.                DoTheSound (9002, true);
  171.         break;
  172.  
  173.         case '3':
  174.                DoTheSound (9003, true);
  175.         break;
  176.  
  177.         case '4':
  178.                DoTheSound (9004, true);
  179.         break;
  180.  
  181.         case '5':
  182.                DoTheSound (9005, true);
  183.         break;
  184.  
  185.         case '6':
  186.                DoTheSound (9006, true);
  187.         break;
  188.  
  189.         case '7':
  190.                DoTheSound (9007, true);
  191.         break;
  192.  
  193.         case '8':
  194.                DoTheSound (9008, true);
  195.         break;
  196.  
  197.         case '9':
  198.                DoTheSound (9009, true);
  199.         break;
  200.  
  201.         case '0':
  202.                DoTheSound (9010, true);
  203.         break;
  204.     }
  205. }
  206.  
  207. void SetUpMenus(void)
  208. {
  209.     InsertMenu(appleMenu = NewMenu(appleID, "\p\024"), 0);
  210.     InsertMenu(fileMenu = NewMenu(fileID, "\pFile"), 0);
  211.     InsertMenu(editMenu = NewMenu(editID, "\pEdit"), 0);
  212.     InsertMenu(widthMenu = NewMenu(widthID, "\pWidth"), 0);
  213.     DrawMenuBar();
  214.     AppendMenu(appleMenu, "\pWhat about it?");
  215.     AddResMenu(appleMenu, 'DRVR');
  216.     AppendMenu(fileMenu, "\pOpen/O;Close/W;(-;Quit/Q");
  217.     AppendMenu(editMenu, "\pUndo/Z;(-;Cut/X;Copy/C;Paste/V;Clear");
  218.     AppendMenu(widthMenu, "\p1/1;2/2;3/3;4/4;5/5;6/6;7/7;8/8;9/9");
  219. }
  220.  
  221. void AdjustMenus(void)
  222. {
  223.     register WindowPeek wp = (WindowPeek) FrontWindow();
  224.     short kind = wp ? wp->windowKind : 0;
  225.     Boolean DA = kind < 0;
  226.     
  227.     enable(editMenu, 1, DA);
  228.     enable(editMenu, 3, DA);
  229.     enable(editMenu, 4, DA);
  230.     enable(editMenu, 5, DA);
  231.     enable(editMenu, 6, DA);
  232.     
  233.     enable(fileMenu, openItem, !((WindowPeek) shellWindow)->visible);
  234.     enable(fileMenu, closeItem, DA || ((WindowPeek) shellWindow)->visible);
  235.  
  236.     CheckItem(widthMenu, theWidth, true);
  237. }
  238.  
  239. int enable(MenuHandle menu, short item, short ok)
  240. {
  241.     if (ok)
  242.         EnableItem(menu, item);
  243.     else
  244.         DisableItem(menu, item);
  245. }
  246.  
  247. void HandleMenu (long mSelect)
  248. {
  249.     int            menuID = HiWord(mSelect);
  250.     int            menuItem = LoWord(mSelect);
  251.     Str255        name;
  252.     GrafPtr        savePort;
  253.     WindowPeek    frontWindow;
  254.     
  255.     switch (menuID)
  256.     {
  257.         case appleID:
  258.             if (menuItem == 1)
  259.                 DoAbout ();
  260.             else
  261.                 {
  262.                     GetPort(&savePort);
  263.                     GetItem(appleMenu, menuItem, name);
  264.                     OpenDeskAcc(name);
  265.                     SetPort(savePort);
  266.             }
  267.         break;
  268.     
  269.         case fileID:
  270.         switch (menuItem)
  271.         {
  272.             case openItem:
  273.                 ShowWindow(shellWindow);
  274.                 SelectWindow(shellWindow);
  275.             break;
  276.                                   
  277.             case closeItem:
  278.                 if ((frontWindow = (WindowPeek) FrontWindow()) == 0L)
  279.                     break;
  280.                     
  281.                 if (frontWindow->windowKind < 0)
  282.                     CloseDeskAcc(frontWindow->windowKind);
  283.                 else if (frontWindow = (WindowPeek) shellWindow)
  284.                     HideWindow(shellWindow);
  285.               break;
  286.                           
  287.             case quitItem:
  288.                 ExitToShell();
  289.             break;
  290.         }
  291.         break;
  292.                   
  293.         case editID:
  294.         if (!SystemEdit(menuItem-1))
  295.             SysBeep(5);
  296.         break;
  297.         
  298.         case widthID:
  299.             CheckItem(widthMenu, theWidth, false);
  300.             theWidth = menuItem;
  301.             InvalRect(&shellWindow->portRect);
  302.         break;
  303.     }
  304. }
  305.  
  306. void InitMacintosh(void)
  307. {
  308.     MaxApplZone();
  309.     
  310.     InitGraf(&qd.thePort);
  311.     InitFonts();
  312.     FlushEvents(everyEvent, 0);
  313.     InitWindows();
  314.     InitMenus();
  315.     TEInit();
  316.     InitDialogs(0L);
  317.     InitCursor();
  318. }
  319.  
  320. void HandleMouseDown (EventRecord    *theEvent)
  321. {
  322.     WindowPtr    theWindow;
  323.     int            windowCode = FindWindow (theEvent->where, &theWindow);
  324.     long ticks;
  325.     
  326.     switch (windowCode)
  327.     {
  328.         case inSysWindow: 
  329.             SystemClick (theEvent, theWindow);
  330.         break;
  331.             
  332.         case inMenuBar:
  333.             AdjustMenus();
  334.             HandleMenu(MenuSelect(theEvent->where));
  335.         break;
  336.             
  337.         case inDrag:
  338.             if (theWindow == shellWindow)
  339.                 DragWindow(shellWindow, theEvent->where, &dragRect);
  340.         break;
  341.                 
  342.         case inContent:
  343.             if (theWindow == shellWindow)
  344.             {
  345.                 if (theWindow != FrontWindow())
  346.                     SelectWindow(shellWindow);
  347.                 else
  348.                     InvalRect(&shellWindow->portRect);
  349.             }
  350.             DoTheSound (8999, true);    //• <-----Added by K.A.L.
  351.         break;
  352.             
  353.         case inGoAway:
  354.             if (theWindow == shellWindow && 
  355.                 TrackGoAway(shellWindow, theEvent->where))
  356.             ExitToShell ();
  357. //            HideWindow(shellWindow);
  358.         break;
  359.     }
  360. }
  361.  
  362. void HandleEvent(void)
  363. {
  364.     int            ok;
  365.     EventRecord    theEvent;
  366.  
  367.     HiliteMenu(0);
  368.     SystemTask ();        /* Handle desk accessories */
  369.     
  370.     ok = GetNextEvent (everyEvent, &theEvent);
  371.     if (ok)
  372.         switch (theEvent.what)
  373.         {
  374.             case mouseDown:
  375.                 HandleMouseDown(&theEvent);
  376.             break;
  377.                 
  378.             case keyDown: 
  379.             case autoKey:
  380.                 if ((theEvent.modifiers & cmdKey) != 0)
  381.                 {
  382.                     AdjustMenus();
  383.                     HandleMenu(MenuKey((char) (theEvent.message & charCodeMask)));
  384.                 }
  385.                 else
  386.                     HandleKeyHits (&theEvent);
  387.             break;
  388.                 
  389.             case updateEvt:
  390.                 BeginUpdate(shellWindow);
  391.                 DrawBullseye(((WindowPeek) shellWindow)->hilited);
  392.                 EndUpdate(shellWindow);
  393.             break;
  394.                     
  395.             case activateEvt:
  396.                 InvalRect(&shellWindow->portRect);
  397.             break;
  398.         }
  399. }
  400.  
  401. void main(void)
  402. {
  403.     long tiks;
  404.     
  405.     InitMacintosh();
  406.     SetUpMenus();
  407.     SetUpWindow();
  408.     DoAbout ();
  409.     Delay (180L, &tiks);
  410.     for (;;)
  411.         HandleEvent();
  412. }
  413.