home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / C / Snippets / PlayRiffs 1.0.3 / PlayRiffs.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-07-07  |  11.4 KB  |  556 lines  |  [TEXT/CWIE]

  1. /* ----------------------------------------------------------------------
  2.  
  3.     PlayRiffs
  4.     version 1.0.3
  5.     
  6.     This snippet is a just a fun demo of sounds and sights.
  7.  
  8.     Written by: Ken Long
  9.     Updated for CW9 by: Paul Celestin
  10.     
  11.     950711 - 1.0.1 - ported to CW
  12.     951201 - 1.0.2 - updated for CW7
  13.     960707 - 1.0.3 - updated for CW9
  14.  
  15. ---------------------------------------------------------------------- */
  16.  
  17. #include "Sound.h"
  18.  
  19. #define over qd.screenBits.bounds.right
  20. #define down qd.screenBits.bounds.bottom
  21.  
  22. PicHandle        aboutPict, pattyPict, bluePict;
  23. PixPatHandle    Miss_Patty;
  24.  
  25. short riff;
  26.  
  27. Handle            riff_1, riff_2, riff_3, riff_4, riff_5, 
  28.                 riff_6, riff_7, riff_8, riff_9;
  29.                 
  30. SndChannelPtr    chanPtr = 0L, riff_ptr = 0L, channelPtr;
  31. SndCommand        call_back, flush_out, quiet_down, buffer_it;
  32. Boolean         Jimi_Hendrix = false, hotLicks = false, 
  33.                 quiet = false, tunes = true;
  34.  
  35. char            var_1, var_2;
  36.  
  37. WindowPtr        shell_window, splash_window;
  38.  
  39. RgnHandle        mBarRgn, GrayRgn;
  40. short            *mBarHeightPtr;
  41. short            twenty_pixels;
  42. short             riffRes;
  43. Rect             splashBounds, pictRect;
  44. long             ticks;
  45.  
  46. //• Prototypes:
  47. //• Set up...
  48. void Hide_Menu_Bar (void);
  49. void Show_Menu_Bar (void);
  50. void Do_The_Splash (void);
  51. void Create_Our_Screen (void);
  52. Boolean We_Be_Hued (void);
  53. void Wake_The_Managers (void);
  54. void Bag_Some_Riffs (void);
  55. void Setup_Snd_Commands (void);
  56.  
  57. //• ...and run.
  58. void Do_The_Sound (short whichID, Boolean asynch);
  59. void Stop_The_Riffs (void);
  60. void Jam_Session (void);
  61. pascal void Auto_Redial (SndChannelPtr chan, SndCommand order);
  62. void Play_The_Riffs (void);
  63. void Main_Event_Loop (void);
  64. void Handle_Key_Hits (EventRecord *theEvent);
  65. void Put_Things_Back (void);
  66. void main (void);
  67.  
  68. //• --------------------------------------------------------------- •//
  69. //• ----------------- S E T U P - S E C T I O N ------------------- •//
  70. //• --------------------------------------------------------------- •//
  71.  
  72. void Hide_Menu_Bar (void) 
  73. {
  74.     Rect    mBarRect;
  75.  
  76.     GrayRgn = GetGrayRgn ();
  77.     mBarHeightPtr = (short *)  0x0BAA;
  78.     twenty_pixels = *mBarHeightPtr;
  79.     *mBarHeightPtr = 0;
  80.     mBarRect = qd.screenBits.bounds;
  81.     mBarRect.bottom = mBarRect.top + twenty_pixels;
  82.     mBarRgn = NewRgn ();
  83.     RectRgn (mBarRgn, &mBarRect);
  84.     UnionRgn (GrayRgn, mBarRgn, GrayRgn);
  85.     PaintOne (0L, mBarRgn);
  86. }
  87.  
  88. void Show_Menu_Bar (void) 
  89. {
  90.     *mBarHeightPtr = twenty_pixels;
  91.     DiffRgn (GrayRgn, mBarRgn, GrayRgn);
  92.     DisposeRgn (mBarRgn);
  93. }
  94.  
  95. void Do_The_Splash ()
  96. {
  97.     
  98.     //• A centered, 300w, 250h window.
  99.     SetRect (&splashBounds, over / 2 - 150, 
  100.                             down / 2 - 125, 
  101.                             over / 2 + 150,
  102.                             down / 2 + 125);
  103.  
  104.     //• "C" window so our 'ppat" will draw.
  105.     splash_window = NewCWindow (0L,             //• No storage - LIVE!
  106.                                &splashBounds,     //• As delineated above.
  107.                                "\p",             //• No place for one.
  108.                                true,             //• Yes, it's visible
  109.                                dBoxProc,         //• For dialog border.
  110.                               (WindowPtr) -1L,     //• In front.
  111.                                false,             //• No go away.
  112.                                0);                //• Reference value 0.
  113.                               
  114.     SetPort(splash_window);
  115.  
  116.     //• splash_window is our set port, so we go off local coords.
  117.     SetRect (&pictRect, 0, 0, 300, 249);
  118.     
  119.     aboutPict = GetPicture (128);
  120.     
  121.     DrawPicture (aboutPict, &pictRect);
  122.     Delay (360, &ticks);
  123.     HideWindow (splash_window);
  124. }
  125.  
  126. void Create_Our_Screen ()
  127. {
  128.     Rect windowBounds, blueRect, sisterRect;
  129.     
  130.     windowBounds = qd.screenBits.bounds;
  131.     
  132.     shell_window = NewCWindow(0L, &windowBounds, "\p", true, plainDBox, (WindowPtr) -1L, true, 0);
  133.     SetPort(shell_window);
  134.  
  135.     Miss_Patty = GetPixPat (128);
  136.  
  137.     FillCRect (&windowBounds, Miss_Patty);
  138.  
  139.     SetRect (&blueRect, 73, 217, 73 + 38, 217 + 55);
  140.     bluePict = GetPicture (130);
  141.     DrawPicture (bluePict, &blueRect);
  142. }
  143.  
  144. Boolean We_Be_Hued ()
  145. {
  146.     SysEnvRec whichMac;
  147.     SysEnvirons (2, &whichMac);
  148.     return (whichMac.hasColorQD);
  149. }
  150.  
  151. void Wake_The_Managers ()
  152. {
  153.     MaxApplZone ();
  154.     InitGraf (&qd.thePort);
  155.     InitFonts ();
  156.     FlushEvents (everyEvent, 0);
  157.     InitWindows ();
  158.     InitMenus ();
  159.     TEInit ();
  160.     InitDialogs (0L);
  161.     InitCursor ();
  162.     
  163.     MoreMasters ();
  164.     MoreMasters ();
  165.     MoreMasters ();
  166. }
  167.  
  168. void Bag_Some_Riffs ()
  169. {        
  170. //     riffRes = OpenResFile("\pRiffs");   // Tired this - stack ate heap.
  171.                                         // It needs more work.
  172. //     if (riffRes == 0L)
  173. //         ExitToShell ();
  174.     
  175.     //• We're gathering by name.
  176.     riff_1 = GetNamedResource ('snd ', "\pRiff_01");
  177.     riff_2 = GetNamedResource ('snd ', "\pRiff_02");
  178.     riff_3 = GetNamedResource ('snd ', "\pRiff_03");
  179.     riff_4 = GetNamedResource ('snd ', "\pRiff_04");
  180.     riff_5 = GetNamedResource ('snd ', "\pRiff_05");
  181.     riff_6 = GetNamedResource ('snd ', "\pRiff_06");
  182.     riff_7 = GetNamedResource ('snd ', "\pRiff_07");
  183.     riff_8 = GetNamedResource ('snd ', "\pRiff_08");
  184.     riff_9 = GetNamedResource ('snd ', "\pRiff_09");
  185. }
  186.  
  187. void Setup_Snd_Commands ()
  188. {
  189.     chanPtr = (SndChannelPtr) NewPtrClear (sizeof (SndChannel));
  190.     if (chanPtr != 0L)
  191.     {
  192.         chanPtr->qLength = stdQLength;
  193.     }
  194.     riff_ptr = 0L;
  195.     call_back.cmd = callBackCmd;
  196.     call_back.param1 = 0;
  197.     call_back.param2 = SetCurrentA5 ();
  198.     
  199.     flush_out.cmd = flushCmd;
  200.     flush_out.param1 = 0;
  201.     flush_out.param2 = 0L;
  202.     
  203.     quiet_down.cmd = quietCmd;
  204.     quiet_down.param1 = 0;
  205.     quiet_down.param2 = 0L;
  206.     
  207.     buffer_it.cmd = bufferCmd;
  208.     buffer_it.param1 = 0;
  209.     buffer_it.param2 = 0L;
  210. }
  211.  
  212. //• --------------------------------------------------------------- •//
  213. //• -------------------- R U N - S E C T I O N -------------------- •//
  214. //• --------------------------------------------------------------- •//
  215.  
  216. //• John Calhoun's sound player, from Stella Obscura (again).
  217. void Do_The_Sound (short whichID, Boolean asynch)
  218. {
  219.     Handle theSnd;
  220.     OSErr err;
  221.     Boolean soundActive;
  222.     
  223.     soundActive = true;    
  224.     
  225.     if ((soundActive))
  226.     {
  227.         theSnd = GetResource ('snd ', whichID);
  228.         
  229.         if ((theSnd != 0L) && (ResError () == noErr))
  230.         {
  231.             if ((channelPtr != 0L))
  232.             {
  233.                 err = SndDisposeChannel (channelPtr, true);
  234.                 channelPtr = 0L;
  235.             }
  236.             if ((asynch == true) && 
  237.                 (SndNewChannel 
  238.                 (&channelPtr, 0, initMono, 0L) == noErr)) 
  239.                 err = SndPlay(channelPtr, (SndListHandle)theSnd, true); 
  240.             else    
  241.                 err = SndPlay(0L, (SndListHandle)theSnd, false);
  242.         }
  243.     }
  244. }
  245.  
  246. //• This gets the ball rolling.  Auto_Redial calls Play_The_Riffs,
  247. //• as a loop (calling it back) and the ID number is switched there.
  248. void Jam_Session ()
  249. {
  250.     Boolean formost = true;
  251.     
  252.     if (! tunes)
  253.         return;
  254.         
  255.     if (Jimi_Hendrix)
  256.         return;
  257.     
  258.     //• If it's number one, it's a new sound channel.  Otherwise,
  259.     //• we just use the one we have.
  260.     if (formost)
  261.         SndNewChannel (&riff_ptr, 0, 0, 
  262.                       (SndCallBackUPP) &Auto_Redial);
  263.  
  264.     //• This assignment makes "riff" be riff_01, or ID #9001.
  265.     riff = 1;
  266.     Jimi_Hendrix = true;
  267.     formost = false;
  268.     
  269.     SndPlay (riff_ptr, (SndListHandle)riff_1, true);
  270.     SndDoCommand (riff_ptr, &call_back, true);
  271. }
  272.  
  273. //• Commonly used call back routine.
  274. pascal void Auto_Redial (SndChannelPtr chan, SndCommand order)
  275. {
  276.     long saveA5;
  277.     saveA5 = SetCurrentA5 ();
  278.     SetA5 (order.param2);
  279.     Play_The_Riffs ();
  280.     SetA5 (saveA5);
  281. }
  282.  
  283. //• This is called by Auto_Redial, which is called by SndNewChannel
  284. //• (in Jam_Session).
  285. //• It starts off playing Riff_01 (ID 9001), 
  286. void Play_The_Riffs ()
  287. {
  288.     Handle which_riff;
  289.     
  290.     //• Just a couple toggles to put in more control if needed.
  291.     if (! hotLicks || ! tunes)
  292.         return;    
  293.             
  294.     //• We are already playing riff_1 coming into this routine.
  295.     //• Format 1 snd resources, please.
  296.     switch (riff)
  297.     {
  298.         //• Plays 9002 twice, then bumps up the series value.
  299.         case 1:
  300.         case 2:
  301.             riff++;
  302.             which_riff = riff_2;
  303.         break;
  304.  
  305.         case 3:
  306.             riff++;
  307.             which_riff = riff_3;
  308.         break;
  309.  
  310.         case 4:
  311.             riff++;
  312.             which_riff = riff_4;
  313.         break;
  314.  
  315.         case 5:
  316.         case 6:
  317.             riff++;
  318.             which_riff = riff_2;
  319.         break;
  320.  
  321.         case 7:
  322.         case 8:
  323.             riff++;
  324.             which_riff = riff_5;
  325.         break;
  326.  
  327.         case 9:
  328.             riff++;
  329.             which_riff = riff_6;
  330.         break;
  331.  
  332.         case 10:
  333.             riff++;
  334.             which_riff = riff_7;
  335.         break;
  336.  
  337.         case 11:
  338.             riff++;
  339.             which_riff = riff_8;
  340.         break;
  341.  
  342.         //• History repeats itself!
  343.         case 12:
  344.         case 13:
  345.             riff++;
  346.             which_riff = riff_2;
  347.         break;
  348.  
  349.         case 14:
  350.             riff++;
  351.             which_riff = riff_5;
  352.         break;
  353.  
  354.         case 15:
  355.             riff++;
  356.             which_riff = riff_6;
  357.         break;
  358.  
  359.         case 16:
  360.             riff = 1;
  361.             which_riff = riff_9;
  362.         break;
  363.     }
  364.     
  365.      var_1 = *((Ptr) (((long) *which_riff) + 3));
  366.      var_2 = *((Ptr)  ((long) *which_riff) + 10 * var_1 + 1);
  367.      
  368.      buffer_it.param2 = ((long) *which_riff) + 10 * var_1 + 10 * var_2;
  369.  
  370.     SndDoCommand (riff_ptr, &buffer_it, true);
  371.     SndDoCommand (riff_ptr, &call_back, true);
  372. }
  373.  
  374. void Stop_The_Riffs ()
  375. {
  376.     //• Don't stop it if it's already stopped.
  377.     if (! Jimi_Hendrix)
  378.         return;
  379.         
  380.     //• Boolean meets Jimi, in a negative context.
  381.     Jimi_Hendrix = false;
  382.     
  383.     //• Plays a "sound of silence."
  384.     SndDoImmediate (riff_ptr, &quiet_down);
  385.     
  386.     //• You know what happens when you flush!
  387.     SndDoCommand (riff_ptr, &flush_out, false);
  388. }
  389.  
  390. void Main_Event_Loop ()
  391. {
  392.     short            ok;
  393.     EventRecord        theEvent;
  394.     short             key;
  395.     Rect             pattyRect;
  396.     
  397.     HiliteMenu (0);        //• What menu?
  398.     WaitNextEvent (everyEvent, &theEvent, 0L, 0L);
  399.  
  400.     //• Puts in "Patty with the blue dress, blue dress on..."
  401.     SetRect (&pattyRect, 109, 132, 109 + 97, 132 +72);
  402.     pattyPict = GetPicture (129);
  403.  
  404.     hotLicks = true;    
  405.     Jam_Session ();
  406.     
  407.     switch (theEvent.what)
  408.     {
  409.         //• We do this, instead of a mouse handling routine.
  410.         case mouseDown:
  411.             DrawPicture (pattyPict, &pattyRect);
  412.             Do_The_Sound (10111, true);
  413.         break;
  414.         
  415.         //• More bull.
  416.         case mouseUp:
  417.             Do_The_Sound (10110, true);
  418.             FillCRect (&pattyRect, Miss_Patty);
  419.         break;
  420.         
  421.         case keyDown:
  422.         case autoKey:
  423.             Handle_Key_Hits (&theEvent);
  424.         break;
  425.     
  426.         case keyUp:
  427.         break;
  428.     
  429.         //• We don't use this because we hog the whole screen.
  430.         case updateEvt:
  431.             //• Where'd this come from?
  432. //            BeginUpdate (shell_window);
  433. //            DrawBullseye (((WindowPeek) shell_window)->hilited);
  434. //            EndUpdate (shell_window);
  435.         break;
  436.     
  437.         //• Same here.
  438.         case activateEvt:
  439.         break;
  440.     }
  441. }
  442.  
  443. //• Key hits ala "CheeseToast" and 100 others.
  444. void Handle_Key_Hits (EventRecord *theEvent)
  445. {
  446.     Rect aboutBounds;
  447.     short    chCode;
  448.     long ticks;
  449.     
  450.     chCode = theEvent->message & charCodeMask;
  451.  
  452.     switch (chCode) 
  453.     {
  454.         case '1':  //• User hits the 1 key.
  455.                Do_The_Sound (10001, true);
  456.         break;
  457.  
  458.         case '2':
  459.                Do_The_Sound (10002, true);
  460.         break;
  461.  
  462.         case '3':
  463.                Do_The_Sound (10003, true);
  464.         break;
  465.  
  466.         case '4':
  467.                Do_The_Sound (10004, true);
  468.         break;
  469.  
  470.         case '5':
  471.                Do_The_Sound (10005, true);
  472.         break;
  473.  
  474.         case '6':
  475.                Do_The_Sound (10006, true);
  476.         break;
  477.  
  478.         case '7':
  479.                Do_The_Sound (10007, true);
  480.         break;
  481.  
  482.         case '8':
  483.                Do_The_Sound (10008, true);
  484.         break;
  485.  
  486.         case '9':
  487.                Do_The_Sound (10009, true);
  488.         break;
  489.  
  490.         case '0':
  491.                Do_The_Sound (10009, true);
  492.         break;
  493.  
  494.         case '*':
  495.             quiet = true;        //• Give the quiet command.
  496.             Stop_The_Riffs ();
  497.         break;
  498.  
  499.         case 'q':
  500.             Put_Things_Back ();
  501.         break;
  502.     }
  503. }
  504.  
  505. void Put_Things_Back ()
  506. {
  507.     //• Get rid of the key and mouse hit sound channel.
  508.     if (chanPtr != 0L)
  509.     {
  510.         SndDoImmediate (chanPtr, &flush_out);     //• flush.
  511.         SndDisposeChannel (chanPtr, true);
  512.     }
  513.     //• Get rid of the riff sound channel.
  514.     if (riff_ptr != 0L)
  515.     {
  516.         SndDoImmediate (riff_ptr, &flush_out);     //• flush.
  517.         SndDisposeChannel (riff_ptr, true);
  518.     }
  519.     //• Back to the bar (for drinks and socializing).
  520.     Show_Menu_Bar ();
  521.     ExitToShell ();        //• Back to Findersville.
  522. }
  523.  
  524. void main ()
  525. {
  526.     Rect r1;
  527.     short i;
  528.     SysEnvRec whichMac;
  529.     
  530.     Wake_The_Managers ();
  531.         
  532.     SetEventMask (everyEvent);
  533.  
  534.     Bag_Some_Riffs ();
  535.     Do_The_Splash ();
  536.  
  537.     //• We do this here because we still look like a desktop.
  538.     Hide_Menu_Bar ();
  539.  
  540.     SysEnvirons (2, &whichMac);
  541.     
  542.     //• We don't mess with no antiques!
  543.     if (whichMac.processor == env68000) 
  544.     {
  545.         tunes = false;
  546.         ExitToShell ();
  547.     }
  548.     Create_Our_Screen ();
  549.     Setup_Snd_Commands ();
  550.     
  551.     for (;;)
  552.         Main_Event_Loop ();
  553. //    CloseResFile(riffRes);  //• Remember?
  554. }
  555.  
  556.