Hey there! I have recently witnessed the wonders that some people can do with graphics (plant engines, 3D environments, etc), so I decided to start with learning about particle systems.

I would like to ask you pros to help me with my most hated difficulty : lag.
I know it's a lot easier to give advice on something concrete, so I pasted here a simple program of mine which simply applies the physics principles of wave interference.

After I made the basic structure of this program, I thought about adding different display effects from the same particle system. So, when the program's running, you can press 'd', enter a value between 1 and 4 to change the display method, and press <Enter>. When you input 4, it simply draws a line from each particle to the point (0,0), but it lags like crazy!

The idea is to get as many ppl to give their opinions on how it could be improved to maximum, so that we can all learn frm one another about anti-lag measures.
I would really like to know why something so simple lags so much more than an entire 3dimensional plant engine! lol

Jst copy the following and paste into a new file ( it was made with Dev-Pascal, so maybe if you use another compiler, it might need a few adaptations ). Btw, I only use Dev-Pascal, so please don't jst tell me to get something else!

Code:
Program Waves;
&#123;By CDB; to learn about particle systems&#125;
uses crt, dos, graph;
type Timerecord = record
           Hours,Minutes,Seconds,S100 &#58; word;
           Tothundreds,Lasthundreds, Timepassed&#58;integer;
           end;
     Waver = record
           Timepassed, Disturb, StringLevel, Detail,
           Howmany,NumOfDist, Colour, Speed, Starter,StartinHeight &#58; integer;
           Disturbance &#58; array&#91;1..100&#93; of record
                       Alive &#58; boolean;
                       Start &#58; integer;
                       Heights &#58; array&#91;1..2000&#93; of real;
                       end;
           end;
     Waveparticles = record
           x,y, vx,vy, oldx,oldy &#58; real;
           end;
var Wave &#58; Waver;
    WaveP &#58; array&#91;1..1100&#93; of waveparticles;  
    Timer &#58; timerecord;
    FPS &#58; integer;
   Procedure Initialize;                                                   forward;
   Procedure CheckForInstruction;                                          forward;
   Procedure FrameIt;                                                      forward;
   Procedure WaveIt;                                                       forward;
   Procedure MakeAMove;                                                    forward;
   Procedure MakeAStand;                                                   forward;
   Procedure MoveNDraw;                                                    forward;

   Procedure Initialize;
   var Gd, Gm &#58; Smallint;
       c &#58; integer;
     begin                                            // the next 3 lines initialise the graph window
          Gd&#58;=Detect;
          InitGraph&#40;Gd,Gm,''&#41;;
          If GraphResult<>0 then Halt;
          Randomize;
          Timer.Timepassed &#58;= 0;
          FPS &#58;= 0; c&#58;=0;
          With Wave do
          begin
               Timepassed &#58;= 0;
               Disturb &#58;= 1;         // how often to create a wave &#40;in sec/100&#41;
               StringLevel &#58;= 300;   // = 'ground' level
               Howmany &#58;= 550;       // how many particles
               NumOfDist &#58;= 100;     // max number of waves at same time
               Detail &#58;= 1;
               colour&#58;= 4;
               Speed&#58;=4;
               Starter &#58;=1000;      // coded&#58; if <0>1020 then starts at middle
               StartinHeight &#58;= 80; // coded&#58; if <0>1000 then default =80;

               //-------Disturbance
               for c&#58;=1 to NumOfDist do
                With Disturbance&#91;c&#93; do
                begin
                     Alive&#58;=false;
                     Start&#58;=510;
                end; &#123;with Disturbance&#125;
               //-------Particles
               for c&#58;=1 to Howmany do
                With WaveP&#91;c&#93; do
                begin
                    x&#58;= c-&#40;Howmany-1020&#41;div 2;       // to centre it
                    y&#58;=StringLevel;
                    oldx&#58;=0;
                    oldy&#58;=y;
                end; &#123;WaterMol&#125;
          end; &#123;With Water&#125;
     end; &#123;initialize&#125;

   Procedure CheckForInstruction;        //to change variables or exit
   var k &#58; char;                         // press the correspondent letter, enter the value, press <Enter>
       s &#58; string;                       // Note&#58; there are no validity checks so take care with what you input!
       c &#58; integer;
     begin
          if keypressed then
          begin
               k&#58;=readkey;
               readln&#40;s&#41;;
               With Wave do
               case k of
                    'f'&#58; begin  //flaten, reset
                              for c&#58;= 1 to NumofDist do Disturbance&#91;c&#93;.Alive&#58;=false;
                              for c&#58;= 1 to Howmany do WaveP&#91;c&#93;.y&#58;=StringLevel;
                              //and velocities if desired
                         end;
                    'h'&#58; begin Val&#40;s,Howmany&#41;; cleardevice; end;   // changes the num of particles
                    't'&#58; Val&#40;s,StartinHeight&#41;;                     // changes how high each wave is
                    's'&#58; Val&#40;s,Starter&#41;;                           // changes where the wave originates from
                    'l'&#58; Val&#40;s,StringLevel&#41;;                       // changes average level
                    'c'&#58; Val&#40;s,Colour&#41;;                            // changes colour
                    'v'&#58; Val&#40;s,Speed&#41;;                             // changes how fast each particle gets to its destination
                    'd'&#58; begin Val&#40;s,Detail&#41;; cleardevice; end;    // changes display
                    'w'&#58; Val&#40;s,Disturb&#41;;                           // changes how often to create a wave
                    'x'&#58; Halt;                                     // exits
                    end; &#123;case&#125;
          end; &#123;if&#125;
     end; &#123;CheckForInstruction&#125;

   Procedure FrameIt;   //not exactly FPS but jst to give an idea of performance
   var s&#58;string;
     begin
          Str&#40;FPS,s&#41;;
          setcolor&#40;0&#41;; outtextxy&#40;10,680,s&#41;;  //erase what's there
          if Timer.Timepassed=0 then FPS&#58;=100 else FPS &#58;= round&#40;100/Timer.Timepassed&#41;;
          Str&#40;FPS,s&#41;;
          setcolor&#40;15&#41;; outtextxy&#40;10,680,s&#41;; //write
     end; &#123;FPS&#125;

   //------------------------Wave procedures
   Procedure WaveIt;
     begin
          MakeAStand;   //creates a new wave
          MakeAMove;    //moves every wave
          MoveNDraw;    //moves and draws particles
     end; &#123;WaveIt&#125;
         
   Procedure MakeAStand;
   var r &#58; integer;
     begin 
           With Wave do
           begin
                Wave.Timepassed += Timer.Timepassed;
                if Timepassed<0>Disturb then
                begin
                     r&#58;=1;
                     while &#40;r<=&#40;NumOfDist+1&#41;&#41;and&#40;Disturbance&#91;r&#93;.Alive&#41; do r+=1;  //find a wave in the array that is not 'Alive'
                     if r<=NumOfDist then
                     With Disturbance&#91;r&#93; do        // and make it alive
                     begin
                          Alive&#58;=true;                                      
writeln&#40;'Creatin wave ',r&#41;;                        //jst a check, can be commented out
                          for r&#58;= 1 to 2000 do Heights&#91;r&#93;&#58;=0;  //makes sure it's all flat
                          Case Starter of                  //Starter can be set in real time.  <0>1025 will make it centered
                               -100..-1    &#58; start &#58;= random&#40;Howmany-5&#41;+3;
                               0..1024     &#58; start &#58;= Starter;
                               1025..10000 &#58; start &#58;= Howmany div 2;
                               end; &#123;case&#125;
                          Case StartinHeight of                  //can be set in real time.  <0>1000 will make it default
                               -100..-1    &#58; Heights&#91;start&#93; &#58;= random&#40;-StartinHeight&#41;;
                               0..1000     &#58; Heights&#91;start&#93; &#58;= StartinHeight;
                               1001..10000 &#58; Heights&#91;start&#93; &#58;= 80;
                               end; &#123;case&#125;
                     end; &#123;if&#125;
                     Timepassed&#58;=0;
                end; &#123;if&#125;
           end; &#123;with&#125;
     end; &#123;MakeAStand&#125;

   Procedure MakeAMove;      //Moves each wave sideways
   var b,c &#58; integer;
     begin
          With Wave do
           for c&#58;=1 to NumOfDist do
           With Disturbance&#91;c&#93; do       //goes through the Disturbance array, and if alive, moves it
            if Alive then
            begin
                 Alive&#58;=false;       //if the wave is still moving through the array, it will become true again
                 for b &#58;= 2 to &#40;Start-1&#41; do //Start is where the disturbance started
                 begin
                      if Heights&#91;b&#93; <> Heights&#91;b+1&#93; then Alive&#58;=true; //if the wave is still moving, it has to stay alive
                      Heights&#91;b&#93; &#58;= Heights&#91;b+1&#93;;    //Moves half of the wave to the left
                 end; &#123;for&#125;
                 for b &#58;= &#40;Howmany-1&#41;downto&#40;Start+1&#41; do
                 begin
                      if Heights&#91;b&#93; <> Heights&#91;b-1&#93; then Alive&#58;=true;
                      Heights&#91;b&#93; &#58;= Heights&#91;b-1&#93;;     //Moves half of the wave to the right      
                 end; &#123;for&#125;
                 Heights&#91;start&#93; *= 4/5; if Heights&#91;start&#93;<5>4 then r&#58;=4; r/=500;   // serious doubts about this...
                                                       // The idea was to make the wave move depending on how long the previous round took
                                                       // so tht it wouldn't slow down, bt it doesnt seem good.
          r &#58;= 1/50000;
          With Wave do
          for c&#58;= 2 to &#40;Howmany-1&#41; do  // The first and last have to be constant to set the average level
           With WaveP&#91;c&#93; do
           begin
                d&#58;=0;
                for b&#58;=1 to NumOfDist do
                 if Disturbance&#91;b&#93;.Alive then d += Disturbance&#91;b&#93;.Heights&#91;c&#93;; //adds all heights of waves at that point
                d+= StringLevel;                                              // adds the total to SeaLevel
                vx += 0;
                vy += &#40;d-y&#41;;                       //vy is how far up or down the particle has to go &#40;smthg like velocity&#41;
                x += vx*r*speed;
                y += vy*r*speed;                   //the particle moves depending on its velocity, how long since last round, and speed
                if y<10>800 then y&#58;=800;                
                if &#40;y<>oldy&#41;or&#40;x<oldx>2 then line&#40;round&#40;x&#41;,round&#40;y&#41;,round&#40;WaveP&#91;c-1&#93;.x&#41;,round&#40;WaveP&#91;c-1&#93;.y&#41;&#41;;
                           end;
                        3&#58; begin          //line to bottom of screen &#40;sea effect&#41;
                                setcolor&#40;0&#41;; line&#40;round&#40;oldx&#41;,round&#40;oldy&#41;,round&#40;oldx&#41;,1020&#41;;
                                setcolor&#40;Colour&#41;; line&#40;round&#40;x&#41;,round&#40;y&#41;,round&#40;x&#41;,1020&#41;;
                                oldx&#58;=x;
                                oldy&#58;=y;
                           end;
                        4&#58;              // line to pt &#40;0,0&#41;
                                        // This is where my problem is.
                                        // I simply wanted to draw a line between every particle and the origin
                                        // so as to create the effect of a horizontal plane being distorted in 3D.
                                        // But, for some reason, unknown to me, it lags like crazy!
                                        // so I tried to draw the lines only with every 5th point, but it still lags
                                        // way too much.
                                        // Please tell me how I could improve this!
                          if c mod 5=0 then begin
                                setcolor&#40;0&#41;; line&#40;round&#40;oldx&#41;,round&#40;oldy&#41;,0,0&#41;;  
                                setcolor&#40;Colour&#41;; line&#40;round&#40;x&#41;,round&#40;y&#41;,0,0&#41;;
                                oldx&#58;=x;
                                oldy&#58;=y;
                           end;
                        else Detail&#58;=1;
                        end; &#123;case&#125;
                end; &#123;if&#125;
           end; &#123;for, with&#125;

           if Wave.Detail=2 then              //has to be put separately because needs to be done all at once
            for c&#58;= 2 to Wave.Howmany do
             With WaveP&#91;c&#93; do
                   begin
                        oldx&#58;=x;
                        oldy&#58;=y;
                   end;
     end; &#123;MoveNDraw&#125;
   //-------------------------------------
begin
     Initialize;     
     Repeat
           With Timer do
           begin
                Gettime&#40;hours,minutes,seconds,s100&#41;;
                Tothundreds&#58;=&#40;s100&#41;+&#40;seconds*100&#41;+&#40;minutes*6000&#41;+&#40;hours*360000&#41;;
                Timepassed &#58;= Tothundreds-Lasthundreds;    //time passed since last time round
                Lasthundreds &#58;= Tothundreds;
                if Timepassed<0 then Timepassed&#58;=0;
           end;
           FrameIt;
           CheckForInstruction;
           WaveIt;
     Until false;
end.
This is when you give all the advice you can to improve it!!! Thank you!

NB: I deleted lots of spaces to make it shorter; and some lines might have been split into 2