home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / Ken Long / Lightspeed-p-c / Symantec / Think C / LightSpeed.c < prev    next >
Encoding:
Text File  |  1994-12-04  |  12.4 KB  |  595 lines  |  [TEXT/KAHL]

  1.  
  2. //• C translation from Pascal source file: LightSpeed.p
  3. //• by Kenneth A. Long, at itty bitty bytes(tm), on 19 November 1994.
  4. //• Original Pascal by Jonathan Birge.
  5.  
  6. //• LightSpeed.c
  7.  
  8. #include <Sound.h>
  9. #include <math.h>
  10.  
  11. enum {
  12. //    MBarHeight = 0xBAA, //• Address of menubar height.
  13.     HUDColor = blackColor,
  14.     IndexColor = greenColor,
  15.     starNumber = 80,  //• Number of stars on the screen at one time.
  16.     photonSnd = 9000,
  17.     engineSnd = 9001
  18. };
  19.  
  20. typedef short *IntPtr;
  21. typedef struct {
  22.     double h, v;
  23.     double distance;
  24. } StarRecord;
  25.  
  26. enum {
  27.     PhotonNum = 18,
  28.     maxDist = 24
  29. };
  30.  
  31. typedef struct {
  32.     float h;
  33.     float v;
  34.     double pSize;
  35. } PhotonVector;
  36.  
  37. RGBColor starColor;
  38. short star, i, t;
  39. short hPos, vPos;
  40. PhotonVector photon[PhotonNum];
  41. PhotonVector oldPhoton;
  42. short photonCount;
  43. double oldpsize;
  44. Boolean keepRunning, past, outOfSight;
  45. double shipSpeed, dist;
  46. Rect starRect;
  47. short windowWidth, windowHight, midH, midV;
  48. Point mouseLoc, oldmouseLoc;
  49. short hOffset, vOffset;
  50. Rect hRect, vRect;
  51. Handle engineSound, photonSound;
  52. SndChannelPtr soundChannel;
  53. SndCommand stopCommand;
  54. OSErr err;
  55.  
  56. typedef StarRecord StarList[starNumber];
  57.  
  58. StarList stars;
  59. WindowPtr starsWindow;
  60. Handle dataHandle;
  61. GrafPtr currentPort;
  62. Rect starswindowRect;
  63. RgnHandle GrayRgn;
  64. short *mBarHeightPtr;
  65. short oldMBarHeight;
  66. RgnHandle mBarRgn;
  67. short colorList[3];
  68. EventRecord theEvent;
  69.  
  70. #include <SANE.h>
  71.  
  72. //• Random number between -(high) and (high).
  73. double Randomize (short high)
  74. {
  75.     long rawResult;
  76.  
  77.     rawResult = Random  ();
  78.     return (((rawResult * high) / 32768));
  79. }
  80.  
  81. //• Pos number between low and high.
  82. double RandMinMax (double low, double high)
  83. {
  84.     long rawResult;
  85.     
  86.     rawResult = Random  ();
  87.     return (rawResult * (high - low) / 32768) + low;
  88. }
  89.  
  90. //• Random integer between 1 and high.
  91. short IntRandomize (short range)
  92. {
  93.     long rawResult;
  94.  
  95.     rawResult = Random  ();
  96.     return ((rawResult * range) / 32768);
  97. }
  98.  
  99. short Sgn (short number)
  100. {
  101.     if (number > 0)
  102.         return (1);
  103.     else 
  104.         if (number < 0)
  105.             return (-1);
  106.     else
  107.         return (0);
  108. }
  109.  
  110. short noSgn (short number)
  111. {
  112.     return (0);
  113.     if (number > 0)
  114.         return (1);
  115.     if (number < 0)
  116.         return (-1);
  117. }
  118.  
  119. void HideMenuBar ()
  120. {
  121.     Rect mBarRect;
  122.  
  123.     oldMBarHeight = *mBarHeightPtr;
  124.  
  125.     //• Make the Menu Bar's height zero.
  126.     *mBarHeightPtr = 0;
  127.     mBarRect = qd.screenBits.bounds; 
  128.     mBarRect.bottom = mBarRect.top + oldMBarHeight;                        
  129.     mBarRgn = NewRgn ();
  130.     RectRgn (mBarRgn, &mBarRect);
  131.     UnionRgn (GrayRgn, mBarRgn, GrayRgn); //• Tell the desktop it.
  132.     
  133.     //• covers the menu bar.
  134.     PaintOne (0L, mBarRgn);  //• Redraw desktop.
  135. }
  136.  
  137. void ShowMenuBar ()
  138. {
  139.     *mBarHeightPtr = oldMBarHeight;
  140.  
  141.     //• Remove the menu bar from the desktop.
  142.     DiffRgn (GrayRgn, mBarRgn, GrayRgn);  
  143.     DisposeRgn (mBarRgn);
  144. }
  145.  
  146. void CenterOrigin ()
  147. {
  148.     short centerX, centerY;
  149.  
  150.     centerX = - (qd.screenBits.bounds.right / 2);
  151. //    centerX = - (abs (currentPort->portRect.right / 2));
  152.     centerY = - (qd.screenBits.bounds.bottom / 2);
  153. //    centerY = - (abs (currentPort->portRect.bottom / 2));
  154.     SetOrigin (centerX, centerY);
  155. }
  156.  
  157. void ClearScrn ()
  158. {
  159.     short oldPenState, oldBkColor;
  160.     GrafPtr winMgrPort;
  161.     Rect menuRect;
  162.  
  163.     oldPenState = currentPort->pnMode;
  164.     GetWMgrPort (&winMgrPort);
  165.     oldBkColor = winMgrPort->bkColor;
  166.     SetPort (winMgrPort);
  167.     BackColor (blackColor);
  168.     SetRect (&menuRect, 0, 0, qd.screenBits.bounds.right, 20);
  169.     EraseRect (&winMgrPort->portRect);
  170.     BackColor (oldBkColor);
  171.     SetPort (currentPort);
  172. }
  173.  
  174. void MakeRect (double h, double v, double distance, Rect *theRect)
  175. {
  176.     short rectSize;
  177.  
  178.     rectSize = maxDist / (distance + 0.01);
  179.     theRect->left = h;    //• was "ceil (h)"
  180.     theRect->top  = v;  //• was "ceil (v)"
  181.     theRect->right = theRect->left + rectSize;
  182.     theRect->bottom = theRect->top + rectSize;
  183.     OffsetRect (theRect, - (rectSize / 2), - (rectSize / 2));
  184.  
  185. }
  186.  
  187. void LoadStars ()
  188. {
  189.     short star;
  190.     Rect starRect;
  191.     
  192.     for (star = 1; star <= starNumber; star++)
  193.     {
  194.         stars[star].h = Randomize (midH);
  195.         stars[star].v = Randomize (midV);
  196.         stars[star].distance = RandMinMax (3, maxDist);
  197.  
  198.         MakeRect (stars[star].h, 
  199.                   stars[star].v, 
  200.                   stars[star].distance, &starRect);
  201.  
  202. //        InvertOval (&starRect);
  203.     }
  204. }
  205.     
  206. //• All this does is add two photons to the photonCount of a 48 pixel
  207. //• size, then DrawPhonton takes over.  Plays the photonSnd.
  208. void DoMouseDown ()
  209. {
  210.     if (photonCount < 10)
  211.     {
  212.         err = SndDoImmediate (soundChannel, &stopCommand);
  213.         err = SndPlay (soundChannel, photonSound, true);
  214.         photon[photonCount + 1].h = -midH;
  215.         photon[photonCount + 1].v = midV;
  216.         photon[photonCount + 2].h = midH;
  217.         photon[photonCount + 2].v = midV;
  218.         photon[photonCount + 1].pSize = 48;
  219.         photon[photonCount + 2].pSize = 48;
  220.         photonCount = photonCount + 2;
  221.     }
  222. }
  223.     
  224. void DoKeyDown (EventRecord *theEvent)
  225. {
  226.     short    chCode;
  227.     chCode = theEvent->message & charCodeMask;
  228.     
  229.     switch (chCode) 
  230.     {
  231.         case '+':
  232.             shipSpeed = shipSpeed + 0.1;
  233.         break;
  234.         
  235.         case '-':
  236.             shipSpeed = shipSpeed - 0.1;
  237.         break;
  238.         
  239.         case 'q':
  240.         case 'Q':
  241.             keepRunning = false;
  242.         break;
  243.         
  244.         case '0':
  245.             shipSpeed = 0;
  246.         break;
  247.         
  248.         case ' ':
  249.             DoMouseDown ();
  250.         break;
  251.         
  252.         //• Horizontal minus 5 (screen left, ship right).
  253.         case '4':
  254.             hPos = hPos - 5;
  255.         break;
  256.         
  257.         //• Combination of '4' and '8'.
  258.         case '7':
  259.             hPos = hPos - 5;
  260.             vPos = vPos + 5;
  261.         break;
  262.         
  263.         //• Vertical plus 5 (screen down, ship up).
  264.         case '8':
  265.             vPos = vPos + 5;
  266.         break;
  267.  
  268.         //• Combination of '4' and '8'.
  269.         case '9':
  270.             hPos = hPos + 5;
  271.             vPos = vPos + 5;
  272.         break;
  273.         
  274.         //• Horizontal plus 5 (screen right, ship left).
  275.         case '6':
  276.             hPos = hPos + 5;
  277.         break;
  278.         
  279.         //• Combination of '6' and '2'.
  280.         case '3':
  281.             hPos = hPos + 5;
  282.             vPos = vPos - 5;
  283.         break;
  284.  
  285.         //• Vertical minus 5 (screen up, ship down).
  286.         case '2':
  287.             vPos = vPos - 5;
  288.         break;
  289.  
  290.         //• Combination of '4' and '2'.
  291.         case '1':
  292.             hPos = hPos - 5;
  293.             vPos = vPos - 5;
  294.         break;
  295.         
  296.         //• Straight ahead or straight back.
  297.         case '5':
  298.         {
  299.             vPos = 0;
  300.             hPos = 0;
  301.         }
  302.         break;
  303.     }
  304. }
  305.  
  306. void DrawPhoton (float h, float v, double pSize)
  307. {
  308.     short t, offset, offset2;
  309.     short h2, v2;
  310.     Rect photonRect;
  311.  
  312.     colorList[1] = blueColor;
  313.     colorList[0] = magentaColor;
  314.     colorList[2] = cyanColor;
  315.  
  316.     h2 = ceil (h);
  317.     v2 = ceil (v);
  318.     for (t = 0; t < 4; t++)
  319.     {
  320.         ForeColor (colorList[IntRandomize (3)]);
  321.         
  322.         offset = ceil (sin (pSize + t) * pSize);
  323.         offset2 = ceil (sin ((pSize + t) * 2) * pSize);
  324.         
  325.         MoveTo (h2 - offset, v2 - offset2);
  326.         LineTo (h2 + offset, v2 + offset2);
  327.     }
  328. }
  329.  
  330. void MainLoop ()
  331. {
  332.     CenterOrigin ();
  333.     BackColor (blackColor);
  334.     
  335.     windowWidth = qd.screenBits.bounds.right;
  336. //    windowWidth = (currentPort->portRect.right - currentPort->portRect.left);
  337.     windowHight = qd.screenBits.bounds.bottom;
  338. //    windowHight = (currentPort->portRect.bottom - currentPort->portRect.top);
  339.  
  340.     midH = windowWidth / 2;
  341.     midV = windowHight / 2;
  342.     LoadStars ();
  343.     ForeColor (HUDColor);
  344.     PenNormal ();
  345.     PenPat (&qd.black);
  346.     engineSound = GetResource ('snd ', engineSnd);
  347.     photonSound = GetResource ('snd ', photonSnd);
  348.     
  349.     stopCommand.cmd = quietCmd;
  350.     stopCommand.param1 = 0;
  351.     stopCommand.param2 = 0;
  352.  
  353.     soundChannel = 0L;
  354.     err = SndNewChannel (&soundChannel, sampledSynth, initMono, 0L);
  355.  
  356.     keepRunning = true;
  357.     photonCount = 0;
  358.     shipSpeed = 0;
  359.     hPos = 0;
  360.     vPos = 0;
  361.     
  362.     starColor.red     = 0xffff;
  363.     starColor.green = 0xffff;
  364.     starColor.blue     = 0xbbbb;
  365.  
  366.     SetEventMask (mDownMask + keyDownMask + autoKeyMask);
  367.     GetMouse (&oldmouseLoc);
  368.     while (keepRunning)
  369.     {
  370.         if (GetNextEvent (everyEvent, &theEvent))
  371.             switch (theEvent.what)
  372.             {
  373.                 case mouseDown: 
  374.                     DoMouseDown ();
  375.                 break;
  376.                 
  377.                 case keyDown: 
  378.                 case autoKey: 
  379.                     DoKeyDown (&theEvent);
  380.                 break;
  381.                 
  382.                 default:
  383.                 break;
  384.             }
  385.             //• Moves the direction indicators.
  386.             GetMouse (&mouseLoc);
  387.             if (! EqualPt (mouseLoc, oldmouseLoc))
  388.             {
  389.                 hPos = hPos + (mouseLoc.h - oldmouseLoc.h);
  390.                 vPos = vPos + (mouseLoc.v - oldmouseLoc.v);
  391.                 oldmouseLoc = mouseLoc;
  392.             }
  393.             //• Draws the index bars.
  394.             ForeColor (IndexColor);        //• Green color.
  395.             PenMode (srcCopy);
  396.             
  397.             if (abs (hPos) > (midH - 2))
  398.                 hPos = Sgn (hPos) * (midH - 2);
  399.                 
  400.             if (abs (vPos) > (midV - 2))
  401.                 vPos = Sgn (vPos) * (midV - 2);
  402.                 
  403.             vRect.left = - (midH);
  404.             vRect.right = - (midH) + 8;
  405.             vRect.top = vPos;
  406.             vRect.bottom = vPos + 2;
  407.             PaintRect (&vRect);
  408.             
  409.             hRect.bottom = midV;
  410.             hRect.top = midV - 8;
  411.             hRect.left = hPos;
  412.             hRect.right = hPos + 2;
  413.             PaintRect (&hRect);
  414.             
  415.             hOffset = -hPos;
  416.             vOffset = vPos;
  417.             PenMode (srcCopy);
  418.             
  419.             //• If there are any photons...
  420.             if (photonCount > 0)
  421.             {
  422.                 PenMode (srcCopy);
  423.                 for (i = 1; i <= photonCount; i++)
  424.                     DrawPhoton (photon[i].h,         //• Horizontal.
  425.                                 photon[i].v,         //• Vertical.
  426.                                 photon[i].pSize);    //• Size.
  427.             }
  428.             
  429.             //• Calculate new star position.
  430.             //• If star out of window, reset it.
  431.             for (star = 1; star <= starNumber; star++)  
  432.             {
  433.                 MakeRect (stars[star].h, stars[star].v, stars[star].distance, &starRect);
  434.                 EraseOval (&starRect);
  435.                 
  436.                 if ((shipSpeed < 0) && (stars[star].distance >= maxDist))
  437.                     past = true;
  438.                     
  439.                 if ((shipSpeed > 0) && (stars[star].distance <= 0))
  440.                     past = true;
  441.                     
  442.                 if ((/*abs*/ (stars[star].v) > midV) || (/*abs*/ (stars[star].h) > midH))
  443.                     outOfSight = true;
  444.                     
  445.                 //• Create a new star.
  446.                 if ((past || outOfSight))
  447.                 {
  448.                     past = false;
  449.                     outOfSight = false;
  450.                     if (shipSpeed >= 0)
  451.                     {
  452.                         stars[star].v = Randomize (midV - 10);
  453.                         stars[star].h = Randomize (midH - 10);
  454.                         stars[star].distance = maxDist;
  455.                     }
  456.                     else //• shipSpeed < 0.
  457.                         switch (IntRandomize (3))
  458.                         {
  459.                             case 1: 
  460.                             {
  461.                                 if (IntRandomize (2) == 1)
  462.                                     stars[star].v = midV;
  463.                                 else
  464.                                     stars[star].v = -midV;
  465.                                     
  466.                                 stars[star].h = Randomize (midH);
  467.                                 stars[star].distance = RandMinMax (2, maxDist - 1);
  468.                             }
  469.                             break;
  470.                             
  471.                             case 2: 
  472.                             {
  473.                                 stars[star].v = Randomize (midV);
  474.                                 if (IntRandomize (2) == 1)
  475.                                     stars[star].h = midH;
  476.                                 else
  477.                                     stars[star].h = -midH;
  478.                                     
  479.                                 stars[star].distance = RandMinMax (2, maxDist - 1);
  480.                             }
  481.                             break;
  482.                         }
  483.                 }  //• new star.
  484.                 else
  485.                     {
  486.                         dist = 6 * stars[star].distance;
  487.                          
  488.                         //• How much distance affects apparent speed.
  489.                         stars[star].h = stars[star].h * (shipSpeed + dist) / dist + 
  490.                                                         (hOffset / 8);
  491.                                                         
  492.                         stars[star].v = stars[star].v * (shipSpeed + dist) / dist + 
  493.                                                         (vOffset / 6);
  494.                                                         
  495.                         stars[star].distance = stars[star].distance - (shipSpeed / 6);
  496.                 }
  497.                 
  498.                 MakeRect (stars[star].h, stars[star].v, stars[star].distance, &starRect);
  499.  
  500.                 RGBForeColor (&starColor);
  501.                 PaintOval (&starRect);
  502.             }
  503.             
  504.             //• Draw the "heads up" display (sight).
  505.             //• Moved to here so stars and photons don't erase it.
  506.             PenPat (&qd.gray);
  507.             ForeColor (yellowColor);
  508.             i = 0;
  509.             while (i < midH)
  510.             {
  511.                 i = i + 50;
  512.                 MoveTo (i, -5);
  513.                 Line (0, 10);
  514.                 MoveTo (-i, -5);
  515.                 Line (0, 10);
  516.             }
  517.             i = 0;
  518.             while (i < midV)
  519.             {
  520.                 i = i + 50;
  521.                 MoveTo (-5, i);
  522.                 Line (10, 0);
  523.                 MoveTo (-5, -i);
  524.                 Line (10, 0);
  525.             }    //• Done drawing sight.
  526.             
  527.             PenNormal ();
  528.             
  529.             //• If there are photons, we want them to disappear 
  530.             //• in the distance.
  531.             if (photonCount > 0)
  532.             {
  533.                 PenMode (srcBic);
  534.                 for (i = 1; i <= photonCount; i++)
  535.                 {
  536.                     oldPhoton = photon[i];
  537.                     photon[i].h = photon[i].h * 0.86 + (hOffset / 8);
  538.                     photon[i].v = photon[i].v * 0.86 + (vOffset / 6);
  539.     
  540.                     DrawPhoton (oldPhoton.h, oldPhoton.v, oldPhoton.pSize);
  541.     
  542.                     oldpsize = photon[i].pSize;
  543.                     
  544.                     photon[i].pSize = photon[i].pSize * 0.9;
  545.                     
  546.                     //• Reduced to double and abs removed to make
  547.                     //• it work at half the value.
  548.                     //• This part kills the farthest photon.
  549.                     if ((oldpsize - photon[i].pSize) < 0.09)
  550.                     {
  551.                         for (t = i; t <= (photonCount - 1); t++)
  552.                             photon[t] = photon[t + 1];
  553.                         photonCount = photonCount - 1;
  554.                     }
  555.                 }
  556.             }
  557.             EraseRect (&hRect);
  558.             EraseRect (&vRect);
  559.     }
  560.     ReleaseResource (photonSound);
  561.     ReleaseResource (engineSound);
  562.     err = SndDisposeChannel (soundChannel, true);
  563.     SetEventMask (everyEvent);
  564. }
  565.  
  566. main ()
  567. {
  568.     InitGraf(&qd.thePort);
  569.     InitFonts();
  570.     FlushEvents(everyEvent, 0);
  571.     InitWindows();
  572.     InitMenus();
  573.     TEInit();
  574.     InitDialogs(0);
  575.     
  576.     InitCursor();
  577.  
  578.     MaxApplZone ();
  579.     
  580.     GetDateTime ((unsigned long *) qd.randSeed);
  581.     
  582.     mBarHeightPtr = (short *)  0x0BAA;
  583.     GrayRgn = GetGrayRgn ();
  584.     HideMenuBar ();
  585.     starsWindow = NewCWindow (0L, &qd.screenBits.bounds, "\pLightSpeed", true, noGrowDocProc, (WindowPtr)-1L, false, (long) dataHandle);
  586.     SetPort (starsWindow);
  587.  
  588.     GetPort (¤tPort);
  589.     ClearScrn ();
  590.     HideCursor ();
  591.     MainLoop ();
  592.     ShowCursor ();
  593.     ShowMenuBar ();
  594.     FlushEvents (mDownMask, 0);    //• Clear Event Queue of all mouseDown events.
  595. }