home *** CD-ROM | disk | FTP | other *** search
/ Chip 2005 November / CDVD1105.ISO / Software / Freeware / programare / bass / Delphi / 3dTest / DTMain.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  2004-11-21  |  14.7 KB  |  613 lines

  1. unit DTMain;
  2.  
  3. interface
  4.  
  5. uses
  6.   Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  7.   StdCtrls, ExtCtrls, BASS, Math, ComCtrls;
  8.  
  9. const
  10.   MV_LEFT            = 1;
  11.   MV_RIGHT           = 2;
  12.   MV_UP              = 4;
  13.   MV_DOWN            = 8;
  14.  
  15.   XDIST              = 70;
  16.   YDIST              = 65;
  17.   XCENTER            = 268;
  18.   YCENTER            = 92;
  19.  
  20.   DIAM               = 10;
  21.  
  22.   MAXDIST            = 500;             // maximum distance of the channels (m)
  23.   SPEED              = 5.0;             // speed of the channels' movement (m/s)
  24.   PAR                = 50;
  25.  
  26. type
  27.   PSource = ^TSource;
  28.   TSource = record
  29.     x, y: Float;
  30.     next: PSource;
  31.     movement: Integer;
  32.     sample, channel: Integer;
  33.     playing: Boolean;
  34.   end;
  35.  
  36.   TForm1 = class(TForm)
  37.     GroupBox1: TGroupBox;
  38.     ListBox1: TListBox;
  39.     Button1: TButton;
  40.     Button2: TButton;
  41.     Button3: TButton;
  42.     Button4: TButton;
  43.     Bevel1: TBevel;
  44.     StaticText1: TStaticText;
  45.     RadioButton1: TRadioButton;
  46.     RadioButton2: TRadioButton;
  47.     RadioButton3: TRadioButton;
  48.     RadioButton4: TRadioButton;
  49.     RadioButton5: TRadioButton;
  50.     GroupBox2: TGroupBox;
  51.     ComboBox1: TComboBox;
  52.     GroupBox3: TGroupBox;
  53.     GroupBox4: TGroupBox;
  54.  
  55.  
  56.     Bevel2: TBevel;
  57.     Timer1: TTimer;
  58.     Bevel3: TBevel;
  59.     OpenDialog1: TOpenDialog;
  60.     ScrollBar1: TTrackBar;
  61.     ScrollBar2: TTrackBar;
  62.     procedure FormCreate(Sender: TObject);
  63.     procedure FormPaint(Sender: TObject);
  64.     procedure Timer1Timer(Sender: TObject);
  65.     procedure Button1Click(Sender: TObject);
  66.     procedure FormDestroy(Sender: TObject);
  67.     procedure ListBox1Click(Sender: TObject);
  68.     procedure Button2Click(Sender: TObject);
  69.     procedure ListBox1KeyDown(Sender: TObject; var Key: Word;
  70.       Shift: TShiftState);
  71.     procedure Button3Click(Sender: TObject);
  72.     procedure Button4Click(Sender: TObject);
  73.     procedure RadioButton1Click(Sender: TObject);
  74.     procedure RadioButton2Click(Sender: TObject);
  75.     procedure RadioButton3Click(Sender: TObject);
  76.     procedure RadioButton4Click(Sender: TObject);
  77.     procedure RadioButton5Click(Sender: TObject);
  78.     procedure ComboBox1Change(Sender: TObject);
  79.     procedure ScrollBar1Change(Sender: TObject);
  80.     procedure ScrollBar2Change(Sender: TObject);
  81.   private
  82.     { Private-Deklarationen }
  83.     sources: PSource;
  84.     procedure Error(msg: string);
  85.     procedure AddSource(name: string);
  86.     procedure RemSource(num: Integer);
  87.     function GetSource(num: Integer): PSource;
  88.     procedure DrawSources;
  89.     procedure FreeSources;
  90.     procedure ActualizeSources(forceupdate: Boolean);
  91.     procedure ActualizeButtons;
  92.     function GetVel(p: PSource): BASS_3DVECTOR;
  93.   public
  94.     { Public-Deklarationen }
  95.   end;
  96.  
  97. var
  98.   Form1: TForm1;
  99.  
  100. implementation
  101.  
  102. uses DTSelect;
  103.  
  104. {$R *.DFM}
  105.  
  106. procedure TForm1.Error(msg: string);
  107. var
  108.   s: string;
  109. begin
  110.   s := msg + #13#10 + '(error code: ' + IntToStr(BASS_ErrorGetCode) + ')';
  111.   MessageBox(handle, PChar(s), 'Error', MB_ICONERROR or MB_OK);
  112. end;
  113.  
  114. procedure TForm1.FormCreate(Sender: TObject);
  115. begin
  116.   sources := nil;
  117. end;
  118.  
  119. procedure TForm1.AddSource(name: string);
  120. var
  121.   p, last: PSource;
  122.   newchan, newsamp: Integer;
  123.   sam: BASS_SAMPLE;
  124. begin
  125.   newsamp := 0;
  126.   // Load a music from "file" with 3D enabled, and make it loop & use ramping
  127.   newchan := BASS_MusicLoad(FALSE, PChar(name), 0, 0, BASS_MUSIC_RAMP or BASS_MUSIC_LOOP or BASS_SAMPLE_3D, 0);
  128.   if (newchan <> 0) then
  129.   begin
  130.     // Set the min/max distance to 15/1000 meters
  131.     BASS_ChannelSet3DAttributes(newchan, -1, 35.0, 1000.0, -1, -1, -1);
  132.   end
  133.   else
  134.   begin
  135.     // Load a sample from "file" with 3D enabled, and make it loop
  136.     newsamp := BASS_SampleLoad(FALSE, PChar(name), 0, 0, 1, BASS_SAMPLE_LOOP or BASS_SAMPLE_3D or BASS_SAMPLE_VAM);
  137.     if (newsamp <> 0) then
  138.       begin
  139.       // Set the min/max distance to 15/1000 meters
  140.       BASS_SampleGetInfo(newsamp, sam);
  141.       sam.mindist := 35.0;
  142.       sam.maxdist := 1000.0;
  143.       BASS_SampleSetInfo(newsamp, sam);
  144.     end;
  145.   end;
  146.   if (newchan = 0) and (newsamp = 0) then
  147.   begin
  148.     Error('Can''t load file');
  149.     Exit;
  150.   end;
  151.  
  152.   New(p);
  153.   p.x := 0;
  154.   p.y := 0;
  155.   p.movement := 0;
  156.   p.sample := newsamp;
  157.   p.channel := newchan;
  158.   BASS_SampleGetChannel(newchan, False); // initialize sample channel
  159.   p.playing := FALSE;
  160.   p.next := nil;
  161.   last := sources;
  162.   if last <> nil then
  163.     while (last.next <> nil) do last := last.next;
  164.   if last = nil then
  165.     sources := p
  166.   else
  167.     last.next := p;
  168.   ListBox1.Items.Add(name);
  169.   ActualizeButtons;
  170. end;
  171.  
  172. procedure TForm1.RemSource(num: Integer);
  173. var
  174.   p, prev: PSource;
  175.   i: Integer;
  176. begin
  177.   prev := nil;
  178.   p := sources;
  179.   i := 0;
  180.   while (p <> nil) and (i < num) do
  181.   begin
  182.     Inc(i);
  183.     prev := p;
  184.     p := p.next;
  185.   end;
  186.   if (p <> nil) then
  187.   begin
  188.     if (prev <> nil) then
  189.       prev.next := p.next
  190.     else
  191.       sources := p.next;
  192.     if (p.sample <> 0) then
  193.       BASS_SampleFree(p.sample)
  194.     else
  195.       BASS_MusicFree(p.channel);
  196.     Dispose(p);
  197.   end;
  198.   ListBox1.Items.Delete(num);
  199.   ActualizeButtons;
  200. end;
  201.  
  202. function TForm1.GetSource(num: Integer): PSource;
  203. var
  204.   p: PSource;
  205.   i: Integer;
  206. begin
  207.   if num < 0 then
  208.   begin
  209.     Result := nil;
  210.     Exit;
  211.   end;
  212.   p := sources;
  213.   i := 0;
  214.   while (p <> nil) and (i < num) do
  215.   begin
  216.     Inc(i);
  217.     p := p.next;
  218.   end;
  219.   Result := p;
  220. end;
  221.  
  222. procedure TForm1.DrawSources;
  223. var
  224.   p: PSource;
  225.   i, j: Integer;
  226. begin
  227.   p := sources;
  228.   with Canvas do
  229.   begin
  230.     Brush.Color := Form1.Color;
  231.     Pen.Color := Form1.Color;
  232.     Rectangle(XCENTER - XDIST - DIAM,
  233.               YCENTER - YDIST - DIAM,
  234.               XCENTER + XDIST + DIAM,
  235.               YCENTER + YDIST + DIAM);
  236.     Brush.Color := clGray;
  237.     Pen.Color := clBlack;
  238.     Ellipse(XCENTER - DIAM div 2,
  239.             YCENTER - DIAM div 2,
  240.             XCENTER + DIAM div 2,
  241.             YCENTER + DIAM div 2);
  242.     Pen.Color := Form1.Color;
  243.     i := 0; j := ListBox1.ItemIndex;
  244.     while (p <> nil) do
  245.     begin
  246.       if (i = j) then
  247.         Brush.Color := clRed
  248.       else
  249.         Brush.Color := clBlack;
  250.         Ellipse(XCENTER + Trunc(p.x * XDIST / MAXDIST) - DIAM div 2,
  251.                 YCENTER + Trunc(p.y * YDIST / MAXDIST) - DIAM div 2,
  252.                 XCENTER + Trunc(p.x * XDIST / MAXDIST) + DIAM div 2,
  253.                 YCENTER + Trunc(p.y * YDIST / MAXDIST) + DIAM div 2);
  254.       p := p.next;
  255.       Inc(i);
  256.     end;
  257.   end;
  258. end;
  259.  
  260. procedure TForm1.ActualizeSources(forceupdate: Boolean);
  261. var
  262.   p: PSource;
  263.   chng, fchng: Boolean;
  264.   pos, rot, vel: BASS_3DVECTOR;
  265. begin
  266.   pos.y := 0;
  267.   rot.x := 0;
  268.   rot.y := 0;
  269.   rot.z := 0;
  270.   fchng := forceupdate;
  271.   p := sources;
  272.   while (p <> nil) do
  273.   begin
  274.     chng := forceupdate;
  275.     if (p.playing) then
  276.     begin
  277.       if ((p.movement and MV_LEFT) = MV_LEFT) then
  278.       begin
  279.         p.x := p.x - SPEED;
  280.         chng := TRUE;
  281.       end;
  282.       if ((p.movement and MV_RIGHT) = MV_RIGHT) then
  283.       begin
  284.         p.x := p.x + SPEED;
  285.         chng := TRUE;
  286.       end;
  287.       if ((p.movement and MV_UP) = MV_UP) then
  288.       begin
  289.         p.y := p.y - SPEED;
  290.         chng := TRUE;
  291.       end;
  292.       if ((p.movement and MV_DOWN) = MV_DOWN) then
  293.       begin
  294.         p.y := p.y + SPEED;
  295.         chng := TRUE;
  296.       end;
  297.       if (p.x < -MAXDIST) then
  298.       begin
  299.         p.x := -MAXDIST;
  300.         p.movement := MV_RIGHT;
  301.       end;
  302.       if (p.x > MAXDIST) then
  303.       begin
  304.         p.x := MAXDIST;
  305.         p.movement := MV_LEFT;
  306.       end;
  307.       if (p.y < -MAXDIST) then
  308.       begin
  309.         p.y := -MAXDIST;
  310.         p.movement := MV_DOWN;
  311.       end;
  312.       if (p.y > MAXDIST) then
  313.       begin
  314.         p.y := MAXDIST;
  315.         p.movement := MV_UP;
  316.       end;
  317.       if chng then
  318.       begin
  319.         pos.x := p.x;
  320.         pos.z := -p.y;
  321.         vel := getVel(p);
  322.     BASS_ChannelSet3DPosition(p.channel, pos, rot, vel);
  323.       end;
  324.     end;
  325.     p := p.next;
  326.     if chng then fchng := TRUE;
  327.   end;
  328.   if fchng then
  329.   begin
  330.     DrawSources;
  331.     BASS_Apply3D;
  332.   end;
  333. end;
  334.  
  335. procedure TForm1.FreeSources;
  336. var
  337.   p, v: PSource;
  338. begin
  339.   p := sources;
  340.   while (p <> nil) do
  341.   begin
  342.     v := p.next;
  343.     Dispose(v);
  344.     p := v;
  345.   end;
  346.   sources := nil;
  347. end;
  348.  
  349. procedure TForm1.FormPaint(Sender: TObject);
  350. begin
  351.   DrawSources;
  352. end;
  353.  
  354. procedure TForm1.Timer1Timer(Sender: TObject);
  355. begin
  356.   ActualizeSources(FALSE);
  357. end;
  358.  
  359. procedure TForm1.Button1Click(Sender: TObject);
  360. begin
  361.   If OpenDialog1.Execute then
  362.   begin
  363.     AddSource(OpenDialog1.FileName);
  364.   end;
  365. end;
  366.  
  367. procedure TForm1.FormDestroy(Sender: TObject);
  368. begin
  369.   FreeSources;
  370.   BASS_Stop;
  371.   BASS_Free;
  372. end;
  373.  
  374. procedure TForm1.ActualizeButtons;
  375. var
  376.   en: Boolean;
  377.   p: PSource;
  378. begin
  379.   en := (ListBox1.ItemIndex >= 0);
  380.   Button2.Enabled := en;
  381.   Button3.Enabled := en;
  382.   Button4.Enabled := en;
  383.   RadioButton1.Enabled := en;
  384.   RadioButton2.Enabled := en;
  385.   RadioButton3.Enabled := en;
  386.   RadioButton4.Enabled := en;
  387.   RadioButton5.Enabled := en;
  388.   DrawSources;
  389.   p := GetSource(ListBox1.ItemIndex);
  390.   if p = nil then Exit;
  391.   if (p.x = -PAR) and ((p.movement = MV_UP) or (p.movement = MV_DOWN)) then
  392.     RadioButton1.Checked := TRUE
  393.   else if (p.x = PAR) and ((p.movement = MV_UP) or (p.movement = MV_DOWN)) then
  394.     RadioButton2.Checked := TRUE
  395.   else if (p.y = -PAR) and ((p.movement = MV_LEFT) or (p.movement = MV_RIGHT)) then
  396.     RadioButton3.Checked := TRUE
  397.   else if (p.y = PAR) and ((p.movement = MV_LEFT) or (p.movement = MV_RIGHT)) then
  398.     RadioButton4.Checked := TRUE
  399.   else
  400.     RadioButton5.Checked := TRUE;
  401. end;
  402.  
  403. procedure TForm1.ListBox1Click(Sender: TObject);
  404. begin
  405.   ActualizeButtons;
  406. end;
  407.  
  408. procedure TForm1.Button2Click(Sender: TObject);
  409. begin
  410.   if ListBox1.ItemIndex >= 0 then
  411.     RemSource(ListBox1.ItemIndex);
  412. end;
  413.  
  414. procedure TForm1.ListBox1KeyDown(Sender: TObject; var Key: Word;
  415.   Shift: TShiftState);
  416. begin
  417.   ActualizeButtons;
  418. end;
  419.  
  420. procedure TForm1.Button3Click(Sender: TObject);
  421. var
  422.   p: PSource;
  423.   pos, rot, vel: BASS_3DVECTOR;
  424. begin
  425.   if ListBox1.ItemIndex < 0 then Exit;
  426.   p := GetSource(ListBox1.itemIndex);
  427.   if not p.playing then
  428.   begin
  429.     p.playing := TRUE;
  430.     pos.x := p.x;
  431.     pos.y := 0;
  432.     pos.z := -p.y;
  433.     vel := GetVel(p);
  434.     rot.x := 0;
  435.     rot.y := 0;
  436.     rot.z := 0;
  437.     p.channel := BASS_SampleGetChannel(p.sample, False);
  438.  
  439.     BASS_ChannelPlay(p.channel, False);
  440.   end;
  441. end;
  442.  
  443. procedure TForm1.Button4Click(Sender: TObject);
  444. var
  445.   p: PSource;
  446. begin
  447.   if ListBox1.ItemIndex < 0 then Exit;
  448.   p := GetSource(ListBox1.ItemIndex);
  449.   if p = nil then Exit;
  450.   BASS_ChannelStop(p.channel);
  451.   if (p.sample <> 0) then p.channel := 0;
  452.   p.playing := FALSE;
  453. end;
  454.  
  455. procedure TForm1.RadioButton1Click(Sender: TObject);
  456. var
  457.   p: PSource;
  458. begin
  459.   if ListBox1.ItemIndex < 0 then Exit;
  460.   p := GetSource(ListBox1.ItemIndex);
  461.   if p = nil then Exit;
  462.   if (p.movement and MV_UP = 0) and
  463.      (p.movement and MV_DOWN = 0) then
  464.   begin
  465.     p.movement := MV_UP;
  466.     p.x := -PAR;
  467.     p.y := 0;
  468.   end
  469.   else
  470.     p.x := -PAR;
  471.   DrawSources;
  472. end;
  473.  
  474. procedure TForm1.RadioButton2Click(Sender: TObject);
  475. var
  476.   p: PSource;
  477. begin
  478.   if ListBox1.ItemIndex < 0 then Exit;
  479.   p := GetSource(ListBox1.ItemIndex);
  480.   if p = nil then Exit;
  481.   if (p.movement and MV_UP = 0) and
  482.      (p.movement and MV_DOWN = 0) then
  483.   begin
  484.     p.movement := MV_UP;
  485.     p.x := PAR;
  486.     p.y := 0;
  487.   end
  488.   else
  489.     p.x := PAR;
  490.   DrawSources;
  491. end;
  492.  
  493. procedure TForm1.RadioButton3Click(Sender: TObject);
  494. var
  495.   p: PSource;
  496. begin
  497.   if ListBox1.ItemIndex < 0 then Exit;
  498.   p := GetSource(ListBox1.ItemIndex);
  499.   if p = nil then Exit;
  500.   if (p.movement and MV_LEFT = 0) and
  501.      (p.movement and MV_RIGHT = 0) then
  502.   begin
  503.     p.movement := MV_RIGHT;
  504.     p.x := 0;
  505.     p.y := -PAR;
  506.   end
  507.   else
  508.     p.y := -PAR;
  509.   DrawSources;
  510. end;
  511.  
  512. procedure TForm1.RadioButton4Click(Sender: TObject);
  513. var
  514.   p: PSource;
  515. begin
  516.   if ListBox1.ItemIndex < 0 then Exit;
  517.   p := GetSource(ListBox1.ItemIndex);
  518.   if p = nil then Exit;
  519.   if (p.movement and MV_LEFT = 0) and
  520.      (p.movement and MV_RIGHT = 0) then
  521.   begin
  522.     p.movement := MV_RIGHT;
  523.     p.x := 0;
  524.     p.y := PAR;
  525.   end
  526.   else
  527.     p.y := PAR;
  528.   DrawSources;
  529. end;
  530.  
  531. procedure TForm1.RadioButton5Click(Sender: TObject);
  532. var
  533.   p: PSource;
  534. begin
  535.   if ListBox1.ItemIndex < 0 then Exit;
  536.   p := GetSource(ListBox1.ItemIndex);
  537.   if p = nil then Exit;
  538.   p.movement := 0;
  539.   ActualizeSources(TRUE);
  540. end;
  541.  
  542. function TForm1.GetVel(p: PSource): BASS_3DVECTOR;
  543. var
  544.   x, z: Float;
  545.   sp: Float;
  546. begin
  547.   x := 0;
  548.   z := 0;
  549.   if p.playing then
  550.   begin
  551.     sp := SPEED * 1000 / Timer1.Interval;
  552.     if (p.movement = MV_LEFT) then x := -sp
  553.     else if (p.movement = MV_RIGHT) then x := sp
  554.     else if (p.movement = MV_UP) then z := sp
  555.     else if (p.movement = MV_DOWN) then z := -sp;
  556.   end;
  557.   Result.x := x;
  558.   Result.y := 0;
  559.   Result.z := z;
  560. end;
  561.  
  562. procedure TForm1.ComboBox1Change(Sender: TObject);
  563. begin
  564.   case (ComboBox1.ItemIndex) of
  565.     0: BASS_SetEAXPreset(EAX_ENVIRONMENT_OFF);
  566.     1: BASS_SetEAXPreset(EAX_ENVIRONMENT_GENERIC);
  567.     2: BASS_SetEAXPreset(EAX_ENVIRONMENT_PADDEDCELL);
  568.     3: BASS_SetEAXPreset(EAX_ENVIRONMENT_ROOM);
  569.     4: BASS_SetEAXPreset(EAX_ENVIRONMENT_BATHROOM);
  570.     5: BASS_SetEAXPreset(EAX_ENVIRONMENT_LIVINGROOM);
  571.     6: BASS_SetEAXPreset(EAX_ENVIRONMENT_STONEROOM);
  572.     7: BASS_SetEAXPreset(EAX_ENVIRONMENT_AUDITORIUM);
  573.     8: BASS_SetEAXPreset(EAX_ENVIRONMENT_CONCERTHALL);
  574.     9: BASS_SetEAXPreset(EAX_ENVIRONMENT_CAVE);
  575.     10: BASS_SetEAXPreset(EAX_ENVIRONMENT_ARENA);
  576.     11: BASS_SetEAXPreset(EAX_ENVIRONMENT_HANGAR);
  577.     12: BASS_SetEAXPreset(EAX_ENVIRONMENT_CARPETEDHALLWAY);
  578.     13: BASS_SetEAXPreset(EAX_ENVIRONMENT_HALLWAY);
  579.     14: BASS_SetEAXPreset(EAX_ENVIRONMENT_STONECORRIDOR);
  580.     15: BASS_SetEAXPreset(EAX_ENVIRONMENT_ALLEY);
  581.     16: BASS_SetEAXPreset(EAX_ENVIRONMENT_FOREST);
  582.     17: BASS_SetEAXPreset(EAX_ENVIRONMENT_CITY);
  583.     18: BASS_SetEAXPreset(EAX_ENVIRONMENT_MOUNTAINS);
  584.     19: BASS_SetEAXPreset(EAX_ENVIRONMENT_QUARRY);
  585.     20: BASS_SetEAXPreset(EAX_ENVIRONMENT_PLAIN);
  586.     21: BASS_SetEAXPreset(EAX_ENVIRONMENT_PARKINGLOT);
  587.     22: BASS_SetEAXPreset(EAX_ENVIRONMENT_SEWERPIPE);
  588.     23: BASS_SetEAXPreset(EAX_ENVIRONMENT_UNDERWATER);
  589.     24: BASS_SetEAXPreset(EAX_ENVIRONMENT_DRUGGED);
  590.     25: BASS_SetEAXPreset(EAX_ENVIRONMENT_DIZZY);
  591.     26: BASS_SetEAXPreset(EAX_ENVIRONMENT_PSYCHOTIC);
  592.   end;
  593. end;
  594.  
  595. procedure TForm1.ScrollBar1Change(Sender: TObject);
  596. var
  597.   a: Float;
  598. begin
  599.   a := ScrollBar1.Position;
  600.   BASS_Set3DFactors(-1, Power(2.0, a / 4.0), -1);
  601. end;
  602.  
  603. procedure TForm1.ScrollBar2Change(Sender: TObject);
  604. var
  605.   a: Float;
  606. begin
  607.   a := ScrollBar2.Position;
  608.   BASS_Set3DFactors(-1, -1, Power(2.0, a / 4.0));
  609. end;
  610.  
  611. end.
  612.  
  613.