home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / Ken Long / Lightspeed-p-c / Metrowerks / Pascal / LightSpeed.p < prev    next >
Encoding:
Text File  |  1994-12-04  |  12.1 KB  |  501 lines  |  [TEXT/MMCC]

  1. program LightSpeed;
  2.     uses
  3.         Sound, Palettes, ToolUtils, Resources, Windows, OSEvents, Memory;
  4.     const
  5.         MBarHeight = $BAA;            {Address of menubar height}
  6.         HUDColor = blackColor;
  7.         IndexColor = greenColor;
  8.         starNumber = 40;            {Number of stars on the screen at one time}
  9.         photonSnd = 9000;
  10.         engineSnd = 9001;
  11.     type
  12.         IntPtr = ^integer;
  13.         StarRecord = record
  14.                 h, v: extended;
  15.                 distance: extended;
  16.             end;
  17.         StarList = array[1..starNumber] of StarRecord;
  18.     var
  19.         stars: StarList;
  20.         starsWindow: WindowPtr;
  21.         dataHandle: Handle;
  22.         currentPort: GrafPtr;
  23.         starswindowRect: Rect;
  24.         GrayRgn: RgnHandle;
  25.         MBarHeightPtr: IntPtr;
  26.         oldMBarHeight: Integer;
  27.         mBarRgn: RgnHandle;
  28.         colorList: array[0..2] of integer;
  29.         TheEvent: EventRecord;
  30.  
  31.     function Randomize (high: Integer): extended;        {Random number}
  32. {between -(high) and (high)}
  33.         var
  34.             rawResult: LONGINT;
  35.     begin
  36.         rawResult := Random;
  37.         Randomize := ((rawResult * high) / 32768)
  38.     end;
  39.  
  40.     function RandMinMax (low, high: extended): extended;        {Pos number}
  41. {between low and high}
  42.         var
  43.             rawResult: LONGINT;
  44.     begin
  45.         rawResult := Random;
  46.         RandMinMax := ABS(rawResult * (high - low) / 32768) + low
  47.     end;
  48.  
  49.     function IntRandomize (high: Integer): Integer;                {Random}
  50. {integer between 1 and high}
  51.         var
  52.             rawResult: LONGINT;
  53.     begin
  54.         rawResult := Random;
  55.         IntRandomize := ABS((rawResult * high) div 32768)
  56.     end;
  57.  
  58.     function Sgn (number: Integer): Integer;            {Signum function}
  59.     begin
  60.         Sgn := 0;
  61.         if number > 0 then
  62.             Sgn := 1;
  63.         if number < 0 then
  64.             Sgn := -1;
  65.     end;
  66.  
  67.     procedure HideMenuBar;
  68.         var
  69.             mBarRect: Rect;
  70.     begin
  71.         oldMBarHeight := MBarHeightPtr^;
  72.         MBarHeightPtr^ := 0;                                        { Make the}
  73. {Menu bar's height zero }
  74.         with qd.screenBits.bounds do
  75.             SetRect(mBarRect, left, top, right, top + oldMBarHeight);
  76.         mBarRgn := NewRgn;
  77.         RectRgn(mBarRgn, mBarRect);
  78.         UnionRgn(GrayRgn, mBarRgn, GrayRgn);  { Tell the desktop it}
  79. {covers the menu bar }
  80.         PaintOne(nil, mBarRgn);                    { redraw desktop }
  81.     end;
  82.  
  83.     procedure ShowMenuBar;
  84.     begin
  85.         MBarHeightPtr^ := oldMBarHeight;
  86.         DiffRgn(GrayRgn, mBarRgn, GrayRgn);        { remove the menu bar from}
  87. {the desktop }
  88.         DisposeRgn(mBarRgn)
  89.     end;
  90.  
  91.     procedure CenterOrigin;
  92.         var
  93.             centerX, centerY: Integer;
  94.     begin
  95.         with currentPort^.portRect do
  96.             begin
  97.                 centerX := -(ABS(right div 2));
  98.                 centerY := -(ABS(bottom div 2));
  99.                 SetOrigin(centerX, centerY)
  100.             end
  101.     end;
  102.  
  103.     procedure ClearScrn;
  104.         var
  105.             oldpenState, oldBkColor: Integer;
  106.             winMgrPort: GrafPtr;
  107.             menuRect: Rect;
  108.     begin
  109.         oldPenState := currentPort^.pnMode;
  110.         GetWMgrPort(winMgrPort);
  111.         oldBkColor := winMgrPort^.bkColor;
  112.         SetPort(winMgrPort);
  113.         BackColor(blackColor);
  114.         SetRect(menuRect, 0, 0, qd.screenBits.bounds.right, 20);
  115.         EraseRect(winMgrPort^.portRect);
  116.         BackColor(oldBkColor);
  117.         SetPort(currentPort)
  118.     end;
  119.  
  120.     procedure MainLoop;
  121.         const
  122.             PhotonNum = 18;
  123.             MaxDist = 24;
  124.         type
  125.             PhotonVector = record
  126.                     h: extended;
  127.                     v: extended;
  128.                     psize: extended;
  129.                 end;
  130.         var
  131.             starColor: RGBColor;
  132.             star, i, t: Integer;
  133.             hPos, vPos: Integer;
  134.             photon: array[1..PhotonNum] of PhotonVector;
  135.             oldPhoton: PhotonVector;
  136.             photonCount: Integer;
  137.             oldpsize: extended;
  138.             continue, past, offscreen: BOOLEAN;
  139.             shipSpeed, dist: extended;
  140.             starRect: Rect;
  141.             windowWidth, windowHight, midH, midV: Integer;
  142.             mouseLoc, oldmouseLoc: Point;
  143.             hOffset, vOffset: Integer;
  144.             hRect, vRect: Rect;
  145.             engineSound, photonSound: Handle;
  146.             soundChannel: SndChannelPtr;
  147.             stopCommand: SndCommand;
  148.             err: OSErr;
  149.         procedure MakeRect (h, v: extended; distance: extended; var theRect: Rect);
  150.             var
  151.                 size: Integer;
  152.         begin
  153.             with theRect do
  154.                 begin
  155.                     size := ROUND(MaxDist / (distance + 0.01));
  156.                     left := ROUND(h);
  157.                     top := ROUND(v);
  158.                     right := left + size;
  159.                     bottom := top + size;
  160.                     OffsetRect(theRect, -(size div 2), -(size div 2));
  161.                 end
  162.         end;
  163.         procedure LoadStars;
  164.             var
  165.                 star: Integer;
  166.                 starRect: Rect;
  167.         begin
  168.             for star := 1 to starNumber do
  169.                 begin
  170.                     stars[star].h := Randomize(midH);
  171.                     stars[star].v := Randomize(midV);
  172.                     stars[star].distance := RandMinMax(3, MaxDist);
  173.                     MakeRect(stars[star].h, stars[star].v, stars[star].distance, starRect);
  174.                     InvertOval(starRect)
  175.                 end
  176.         end;
  177.         procedure DoMouseDown;
  178.         begin
  179.             if photonCount < 10 then
  180.                 begin
  181.                     err := SndDoImmediate(soundChannel, stopCommand);
  182.                     err := SndPlay(soundChannel, photonSound, TRUE);
  183.                     photon[photonCount + 1].h := -midH;
  184.                     photon[photonCount + 1].v := midV;
  185.                     photon[photonCount + 2].h := midH;
  186.                     photon[photonCount + 2].v := midV;
  187.                     photon[photonCount + 1].psize := 48;
  188.                     photon[photonCount + 2].psize := 48;
  189.                     photonCount := photonCount + 2;
  190.                 end
  191.         end;
  192.         procedure DoKeyDown;
  193.             var
  194.                 chCode: Integer;
  195.                 theChar: char;
  196.         begin
  197.             chCode := BitAnd(TheEvent.message, CharCodeMask);
  198.             theChar := CHR(chCode);
  199.             
  200.             if theChar = '+' then
  201.                 shipSpeed := shipSpeed + 0.1;
  202.                 
  203.             if theChar = '-' then
  204.                 shipSpeed := shipSpeed - 0.1;
  205.                 
  206.             if (theChar = 'q') or (theChar = 'Q') then
  207.                 continue := FALSE;
  208.             if theChar = ' ' then
  209.                 DoMouseDown;
  210.                 
  211.             if theChar = '4' then
  212.                 hPos := hPos - 5;
  213.                 
  214.             if theChar = '7' then
  215.                 begin
  216.                     vPos := vPos + 5;
  217.                     hPos := hPos - 5;
  218.                 end;
  219.                 
  220.             if theChar = '8' then
  221.                 vPos := vPos + 5;
  222.                 
  223.             if theChar = '9' then
  224.                 begin
  225.                     vPos := vPos + 5;
  226.                     hPos := hPos + 5;
  227.                 end;
  228.                 
  229.             if theChar = '6' then
  230.                 hPos := hPos + 5;
  231.                 
  232.             if theChar = '3' then
  233.                 begin
  234.                     vPos := vPos - 5;
  235.                     hPos := hPos + 5;
  236.                 end;
  237.                 
  238.             if theChar = '2' then
  239.                 vPos := vPos - 5;
  240.                 
  241.             if theChar = '1' then
  242.                 begin
  243.                     vPos := vPos - 5;
  244.                     hPos := hPos - 5;
  245.                 end;
  246.                 
  247.             if theChar = '5' then
  248.                 begin
  249.                     vPos := 0;
  250.                     hPos := 0
  251.                 end;
  252.                     
  253.             if theChar = '0' then
  254.                 shipSpeed := 0;
  255.     end;
  256.         
  257.         procedure DrawPhoton (h, v, psize: extended);
  258.             var
  259.                 t, offset, offset2: Integer;
  260.                 h2, v2: Integer;
  261.                 photonRect: Rect;
  262.         begin
  263.             h2 := ROUND(h);
  264.             v2 := ROUND(v);
  265.             for t := 0 to 4 do
  266.                 begin
  267.                     ForeColor(colorList[ABS(IntRandomize(3))]);
  268.                     offset := ROUND(SIN(psize + t) * psize);
  269.                     offset2 := ROUND(SIN((psize + t) * 2) * psize);
  270.                     MoveTo(h2 - offset, v2 - offset2);
  271.                     LineTo(h2 + offset, v2 + offset2)
  272.                 end;
  273.         end;
  274.     begin        (*Main Loop*)
  275.         CenterOrigin;
  276.         colorList[0] := blueColor;
  277.         colorList[1] := blueColor;
  278.         colorList[2] := cyanColor;
  279.         BackColor(blackColor);
  280.         with currentPort^.portRect do
  281.             begin
  282.                 windowWidth := (right - left);
  283.                 windowHight := (bottom - top)
  284.             end;
  285.         midH := windowWidth div 2;
  286.         midV := windowHight div 2;
  287.         LoadStars;
  288.         ForeColor(HUDColor);
  289.         PenNormal;
  290.         PenPat(qd.black);
  291.         engineSound := GetResource('snd ', engineSnd);
  292.         photonSound := GetResource('snd ', photonSnd);
  293.         with stopCommand do
  294.             begin
  295.                 cmd := quietCmd;
  296.                 param1 := 0;
  297.                 param2 := 0;
  298.             end;
  299.         soundChannel := nil;
  300.         err := SndNewChannel(soundChannel, sampledSynth, initMono, nil);
  301.         continue := TRUE;
  302.         photonCount := 0;
  303.         shipSpeed := 0;
  304.         hPos := 0;
  305.         vPos := 0;
  306.         with starColor do
  307.             begin
  308.                 red := $AAAA;
  309.                 green := $AAAA;
  310.                 blue := $BBBB;
  311.             end;
  312.         SetEventMask(mDownMask + keyDownMask + autoKeyMask);
  313.         GetMouse(oldmouseLoc);
  314.         while continue do
  315.             begin
  316.                 if GetNextEvent(EveryEvent, TheEvent) then
  317.                     case TheEvent.what of
  318.                         mouseDown: 
  319.                             DoMouseDown;
  320.                         keyDown: 
  321.                             DoKeyDown;
  322.                         autoKey: 
  323.                             DoKeyDown;
  324.                         otherwise
  325.                             ;
  326.                     end;
  327.                 GetMouse(mouseLoc);
  328.                 if not EqualPt(mouseLoc, oldmouseLoc) then
  329.                     begin
  330.                         hPos := hPos + (mouseLoc.h - oldmouseLoc.h);
  331.                         vPos := vPos + (mouseLoc.v - oldmouseLoc.v);
  332.                         oldmouseLoc := mouseLoc;
  333.                     end;
  334.                     
  335.                 {ForeColor(IndexColor);}
  336.                 ForeColor(redColor);
  337.                 PenMode(SrcCopy);
  338.                 if ABS(hPos) > (midH - 2) then
  339.                     hPos := Sgn(hPos) * (midH - 2);
  340.                     
  341.                 if ABS(vPos) > (midV - 2) then
  342.                     vPos := Sgn(vPos) * (midV - 2);
  343.                     
  344.                 vRect.left := -(midH);
  345.     
  346.                 {Changed from "- 8" to make crosshair}
  347.                 vRect.right := -(midH) + qd.screenBits.bounds.right;
  348.                 vRect.top := vPos;
  349.                 
  350.                 {Changed from "- 1" to make one pixel wide}
  351.                 vRect.bottom := vPos + 1;
  352.                 PaintRect(vRect);
  353.                 
  354.                 hRect.bottom := midV;
  355.                 
  356.                 {Changed from "- 8" to make crosshair}
  357.                 hRect.top := midV - qd.screenBits.bounds.bottom;
  358.                 hRect.left := hPos;
  359.  
  360.                 {Changed from "- 1" to make one pixel wide}
  361.                 hRect.right := hPos + 1;
  362.                 PaintRect(hRect);
  363.                 
  364.                 hOffset := -hPos;
  365.                 vOffset := vPos;
  366.                 
  367.                 PenMode(SrcCopy);
  368.                 if photonCount > 0 then
  369.                     begin
  370.                         PenMode(SrcCopy);
  371.                         for i := 1 to photonCount do
  372.                             DrawPhoton(photon[i].h, photon[i].v, photon[i].psize);
  373.                     end;
  374.                 {Calculate new star position, if star out of window, }
  375.                 {reset it}
  376.                 for star := 1 to starNumber do            
  377.                     begin
  378.                         MakeRect(stars[star].h, stars[star].v, stars[star].distance, starRect);
  379.                         EraseOval(starRect);
  380.                         if (shipSpeed < 0) and (stars[star].distance >= MaxDist) then
  381.                             past := TRUE;
  382.                         if (shipSpeed > 0) and (stars[star].distance <= 0) then
  383.                             past := TRUE;
  384.                         if (ABS(stars[star].v) > midV) or (ABS(stars[star].h) > midH) then
  385.                             offscreen := TRUE;
  386.                         if (past or offscreen) then
  387.                             begin            {new star}
  388.                                 past := FALSE;
  389.                                 offscreen := FALSE;
  390.                                 if shipSpeed >= 0 then
  391.                                     begin
  392.                                         stars[star].v := Randomize(midV - 10);
  393.                                         stars[star].h := Randomize(midH - 10);
  394.                                         stars[star].distance := maxDist;
  395.                                     end
  396.                                 else            {shipSpeed < 0}
  397.                                     case IntRandomize(3) of
  398.                                         1: 
  399.                                             begin
  400.                                                 if IntRandomize(2) = 1 then
  401.                                                     stars[star].v := midV
  402.                                                 else
  403.                                                     stars[star].v := -midV;
  404.                                                 stars[star].h := Randomize(midH);
  405.                                                 stars[star].distance := RandMinMax(2, MaxDist - 1);
  406.                                             end;
  407.                                         2: 
  408.                                             begin
  409.                                                 stars[star].v := Randomize(midV);
  410.                                                 if IntRandomize(2) = 1 then
  411.                                                     stars[star].h := midH
  412.                                                 else
  413.                                                     stars[star].h := -midH;
  414.                                                 stars[star].distance := RandMinMax(2, MaxDist - 1);
  415.                                             end;
  416.                                     end
  417.                             end            {new star}
  418.                         else
  419.                             begin
  420.                                 dist := 6 * stars[star].distance;                {How much distance}
  421. {affects apparent speed}
  422.                                 stars[star].h := stars[star].h * (shipSpeed + dist) / dist + (hOffset div 8);
  423.                                 stars[star].v := stars[star].v * (shipSpeed + dist) / dist + (vOffset div 6);
  424.                                 stars[star].distance := stars[star].distance - (shipSpeed / 6);
  425.                             end;
  426.                         MakeRect(stars[star].h, stars[star].v, stars[star].distance, starRect);
  427.                         RGBForeColor(starColor);
  428.                         PaintOval(starRect);
  429.                     end;
  430.                 PenPat(qd.gray);
  431.                 ForeColor(yellowColor);
  432.                 i := 0;
  433.                 while i < midH do
  434.                     begin
  435.                         i := i + 50;
  436.                         MoveTo(i, -5);
  437.                         Line(0, 10);
  438.                         MoveTo(-i, -5);
  439.                         Line(0, 10);
  440.                     end;
  441.                 i := 0;
  442.                 while i < midV do
  443.                     begin
  444.                         i := i + 50;
  445.                         MoveTo(-5, i);
  446.                         Line(10, 0);
  447.                         MoveTo(-5, -i);
  448.                         Line(10, 0);
  449.                     end;
  450.                 PenNormal;
  451.                 if photonCount > 0 then
  452.                     begin
  453.                         PenMode(SrcBic);
  454.                         for i := 1 to photonCount do
  455.                             begin
  456.                                 oldphoton := photon[i];
  457.                                 photon[i].h := photon[i].h * 0.86 + (hOffset div 8);
  458.                                 photon[i].v := photon[i].v * 0.86 + (vOffset div 6);
  459.                                 DrawPhoton(oldphoton.h, oldphoton.v, oldphoton.psize);
  460.                                 oldpsize := photon[i].psize;
  461.                                 photon[i].psize := photon[i].psize * 0.9;
  462.                                 if ABS(oldpsize - photon[i].psize) < 0.09 then
  463.                                     begin
  464.                                         for t := i to (photonCount - 1) do
  465.                                             photon[t] := photon[t + 1];
  466.                                         photonCount := photonCount - 1;
  467.                                     end;
  468.                             end;
  469.                     end;
  470.                 EraseRect(hRect);
  471.                 EraseRect(vRect);
  472.             end;
  473.         ReleaseResource(photonSound);
  474.         ReleaseResource(engineSound);
  475.         err := SndDisposeChannel(soundChannel, TRUE);
  476.         FlushEvents(everyEvent, 0);
  477.     end;
  478.  
  479. begin        (*Main Block*)
  480.     InitGraf(@qd.thePort);
  481.     InitWindows;
  482.     InitCursor;
  483.     MaxApplZone;
  484.     
  485.     with qd.screenBits.bounds do
  486.         begin
  487.             MBarHeightPtr := IntPtr(MBarHeight);
  488.             GrayRgn := GetGrayRgn;
  489.             HideMenuBar;
  490.             starsWindow := NewCWindow(nil, qd.screenBits.bounds, 'LightSpeed', TRUE, NoGrowDocProc, WindowPtr(-1), FALSE, LONGINT(dataHandle));
  491.             SetPort(starsWindow);
  492.         end;
  493.     GetPort(currentPort);
  494.     ClearScrn;
  495.     HideCursor;
  496.     MainLoop;
  497.     ShowCursor;
  498.     ShowMenuBar;
  499.     FlushEvents(MDownMask, 0)            {Clear Event Queue of all mouseDown}
  500. {events}
  501. end.