Delphi DirectX 32Bit Color
===

I am a delphi learner. I have download one delphi form effect project from

    http://www.gamedev.net/page/resources/_/technical/graphics-programming-and-theory/the-water-effect-explained-r915

having "DXDraw01", "DXDIB01", "DXDIB02", "Background", and some "BitBtn"s. The actual project was *Bit Color operation. I have tried to implement it in 32Bit Color. I have implemented the following code :

      private
        { Private declarations }
      public
        { Public declarations }
       procedure FrameFadeIn(DIB01, DIB02: TDIB; Step: Byte);
       procedure FrameFadeOut(DIB01, DIB02: TDIB; Step: Byte);
       procedure FrameFill(DIB: TDIB; Color: Byte);
       procedure WaterFrameUpdate;
       procedure WaterFrameInitialize;
       procedure WaterFramePrepare;
       procedure WaterFrameRender(DIB: TDIB);
       procedure WaterBubleDrop(X, Y, W, SplashStrength: Integer);
      end;
      PLongArray = ^TLongArray;
      TLongArray = Array[0..32767] of LongInt;
      TWaterFrame = Array[0..1,0..FrameWidth,0..FrameHeight] of Smallint;
    var
      MainForm: TMainForm;
      CT, NW: Byte;
      Closing: Boolean;
      WaterFrame: TWaterFrame;
      TSin, TCos: Array[0..511] of Single;
      UltimateDisplacement: Array[0..511] of Byte;
    implementation
    {$R *.DFM}

    procedure TMainForm.FrameFill(DIB: TDIB; Color: Byte);
    var
      P: PByteArray;
      W, H: Integer;
    begin
      P := DIB.ScanLine[DIB.Height-1];
      W := DIB.WidthBytes;
      H := DIB.Height;
      asm
        PUSH ESI
        MOV ESI, P
        MOV EDX, W
        MOV EAX, H
        IMUL EDX
        MOV ECX, EAX
        MOV AL, Color
        @@1:
        MOV [ESI], AL
        INC ESI
        DEC ECX
        JNZ @@1
        POP ESI
      end;
    end;
    procedure TMainForm.FrameFadeIn(DIB01, DIB02: TDIB; Step: Byte);
    var
      W, H: Integer;
      P1, P2: PByteArray;
    begin
      P1 := DIB01.ScanLine[DIB02.Height-1];
      P2 := DIB02.ScanLine[DIB02.Height-1];
      W := DIB01.WidthBytes;
      H := DIB01.Height;
      asm
        PUSH ESI
        PUSH EDI
        MOV ESI, P1
        MOV EDI, P2
        MOV EDX, W
        MOV EAX, H
        IMUL EDX
        MOV ECX, EAX
        @@1:
        MOV AL, Step
        MOV AH, [ESI]
        CMP AL, AH
        JB @@2
        MOV AL, AH
    @@2:
        MOV [EDI], AL
        INC ESI
        INC EDI
        DEC ECX
        JNZ @@1
        POP EDI
        POP ESI
      end;
    end;
    procedure TMainForm.FrameFadeOut(DIB01, DIB02: TDIB; Step: Byte);
    var
      W, H: Integer;
      P1, P2: PByteArray;
    begin
      P1 := DIB01.ScanLine[DIB02.Height-1];
      P2 := DIB02.ScanLine[DIB02.Height-1];
      W := DIB01.WidthBytes;
      H := DIB01.Height;
      asm
        PUSH ESI
        PUSH EDI
        MOV ESI, P1
        MOV EDI, P2
        MOV EDX, W
        MOV EAX, H
        IMUL EDX
        MOV ECX, EAX
        @@1:
        MOV AL, Step
        MOV AH, [ESI]
        CMP AL, AH
        JA @@2
        MOV AL, AH
    @@2:
        MOV [EDI], AL
        INC ESI
        INC EDI
        DEC ECX
        JNZ @@1
        POP EDI
        POP ESI
      end;
    end;
    procedure TMainForm.BitBtn01Click(Sender: TObject);
    var
      Opacity: Integer;
      SystemTime01, SystemTime02: TSystemTime;
    begin
      Closing := True;
      Application.ProcessMessages;
      Closing := False;
      GetLocalTime(SystemTime01);
      DXDIB01.DIB.SetSize(Background.DIB.Width, Background.DIB.Height, Background.DIB.BitCount);
      Opacity := 0;
      while Opacity < 255 do
        begin
          FrameFill(DXDIB01.DIB, Byte(Opacity));
          if DXDraw01.CanDraw then
            begin
              DXDraw01.Surface.Assign(DXDIB01.DIB);
              DXDraw01.Flip;
            end;
          Opacity := Opacity + 5;
          Application.ProcessMessages;
          if Closing then Exit;
        end;
      GetLocalTime(SystemTime02);
    end;
    procedure TMainForm.BitBtn02Click(Sender: TObject);
    var
      Opacity: Integer;
    begin
      Closing := True;
      Application.ProcessMessages;
      Closing := False;
    
      DXDIB01.DIB.SetSize(Background.DIB.Width, Background.DIB.Height, Background.DIB.BitCount);
      FrameFill(DXDIB01.DIB, 0);
      for Opacity := 0 to 255 do
        begin
          FrameFadeIn(BackGround.DIB, DXDIB01.DIB, Opacity);
          if DXDraw01.CanDraw then
            begin
              DXDraw01.Surface.Assign(DXDIB01.DIB);
              DXDraw01.Flip;
            end;
          Application.ProcessMessages;
          if Closing then Exit;
        end;
    end;
    procedure TMainForm.BitBtn03Click(Sender: TObject);
    var
      Opacity: Integer;
    begin
      Closing := True;
      Application.ProcessMessages;
      Closing := False;
      DXDIB01.DIB.SetSize(Background.DIB.Width, Background.DIB.Height, Background.DIB.BitCount);
      FrameFill(DXDIB01.DIB, 255);
      for Opacity := 255 downto 0 do
        begin
          FrameFadeOut(BackGround.DIB, DXDIB01.DIB, Opacity);
          if DXDraw01.CanDraw then
            begin
              DXDraw01.Surface.Assign(DXDIB01.DIB);
              DXDraw01.Flip;
            end;
          Application.ProcessMessages;
          if Closing then Exit;
        end;
    end;
    procedure TMainForm.BitBtn04Click(Sender: TObject);
    const
      NumberOfRotation = 10;
    var
      CosY,SinY: real;
      P1,P2: PByteArray;
      X1, Y1, X2, Y2, FrameHorizontalCenter, FrameVerticalCenter, RotationSpeed, RotationAngle: Integer;
    begin
      Closing := True;
      Application.ProcessMessages;
      Closing := False;
      DXDIB01.DIB.SetSize(Background.DIB.Width, Background.DIB.Height, Background.DIB.BitCount);
      FrameHorizontalCenter := Background.DIB.Width div 2;
      FrameVerticalCenter := Background.DIB.Height div 2;
      for RotationSpeed := 0 to 64 do
        begin
          RotationAngle := 384 + (RotationSpeed*NumberOfRotation);
          for Y1 := 0 to BackGround.DIB.Height -1 do
            begin
              P1 := DXDIB01.DIB.ScanLine[Y1];
              CosY := (Y1 - FrameVerticalCenter) * TCos[RotationAngle and $1ff];
              SinY := (Y1 - FrameVerticalCenter) * TSin[RotationAngle and $1ff];
              for X1 := 0 to Background.DIB.Width-1 do
                begin
                  X2 := Trunc((X1 - FrameHorizontalCenter) * TSin[RotationAngle and $1ff] + CosY) + FrameHorizontalCenter;
                  Y2 := Trunc((X1 - FrameHorizontalCenter) * TCos[RotationAngle and $1ff] - SinY) + FrameVerticalCenter;
                  {  Required Logic if Background.DIB.BitCount=32  }
                  if (Y2 >= 0) and (Y2 < Background.DIB.Height) and (X2 >= 0) and (X2 < Background.DIB.Width) then
                    begin
                      PLongArray(P2) := Background.DIB.ScanLine[Y2];
                      PLongArray(P1)[X1] := PLongArray(P2)[FrameWidth - x2];
                    end
                  else
                    begin
                      if PLongArray(P1)[X1] > 4 then PLongArray(P1)[X1] := PLongArray(P1)[X1] - 4 else PLongArray(P1)[X1] := 0;
                    end;
                  {  Required Logic if Background.DIB.BitCount=32  }
                end
            end;
          if DXDraw01.CanDraw then
            begin
              DXDraw01.Surface.Assign(DXDIB01.DIB);
              DXDraw01.Flip;
            end;
          Application.ProcessMessages;
          if Closing then Exit;
        end;
      BitBtn11Click(Sender);
    end;
    procedure TMainForm.BitBtn05Click(Sender: TObject);
    var
      P1,P2: PByteArray;
      ActualDistance, Distance, CosY, SinY: real;
      X1, Y1, X2, Y2, HorizontalCenter, VerticalCenter, A, B, Angle, DistortionFactor: Integer;
    begin
      Closing := True;
      Application.ProcessMessages;
      Closing := False;
      DXDIB01.DIB.SetSize(Background.DIB.Width, Background.DIB.Height, Background.DIB.BitCount);
      HorizontalCenter := Background.DIB.Width div 2;
      VerticalCenter := Background.DIB.Height div 2;
      Distance := sqrt(sqr(HorizontalCenter) + sqr(VerticalCenter));
      for A := 0 to 16 do
        begin
          B := A*8;
          for Y1 := 0 to DXDIB01.DIB.Height - 1 do
            begin
            P1 := DXDIB01.DIB.ScanLine[Y1];
            DistortionFactor := sqr(Y1-VerticalCenter);
            for X1 := 0 to (DXDIB01.DIB.Width) - 1 do
              begin
                ActualDistance := (sqrt((sqr(X1 - HorizontalCenter) + DistortionFactor))/Distance);
                ActualDistance := TSin[ (Trunc(ActualDistance*1024)) and $1ff ];
                Angle := 384 + Trunc( (ActualDistance)* B );
                CosY := (Y1 - VerticalCenter) * TCos[Angle and $1ff];
                SinY := (Y1 - VerticalCenter) * TSin[Angle and $1ff];
                X2 := Trunc((X1 - HorizontalCenter) * TSin[Angle and $1ff] + CosY) + HorizontalCenter;
                Y2 := Trunc((X1 - HorizontalCenter) * TCos[Angle and $1ff] - SinY) + VerticalCenter;
                {  Required Logic if Background.DIB.BitCount=32  }
                if (Y2 >= 0) and (Y2 < Background.DIB.Height) and (X2 >= 0) and (X2 < Background.DIB.Width) then
                  begin
                    PLongArray(P2) := Background.DIB.ScanLine[Y2];
                    PLongArray(P1)[X1] := PLongArray(P2)[FrameWidth - X2];
                  end
                else
                  begin
                    if P1[X1] > 2 then PLongArray(P1)[X1] := PLongArray(P1)[X1] - 2 else PLongArray(P1)[X1] := 0;
                  end;
                {  Required Logic if Background.DIB.BitCount=32  }
              end;
            end;
          if DXDraw01.CanDraw then
            begin
              DXDraw01.Surface.Assign(DXDIB01.DIB);
              DXDraw01.Flip;
            end;
          Application.ProcessMessages;
          if Closing then Exit;
        end;
      for A := 16 downto 0 do
        begin
          B := A*8;
          for Y1 := 0 to DXDIB01.DIB.Height - 1 do
            begin
              P1 := DXDIB01.DIB.ScanLine[Y1];
              DistortionFactor := sqr(Y1 - VerticalCenter);
              for X1 := 0 to (DXDIB01.DIB.Width) - 1 do
                begin
                  ActualDistance := (sqrt((sqr(X1 - HorizontalCenter) + DistortionFactor))/Distance);
                  ActualDistance := TSin[ (Trunc(ActualDistance*1024)) and $1ff ];
                  Angle := 384 + Trunc( (ActualDistance)* B );
                  CosY := (Y1 - VerticalCenter) * TCos[Angle and $1ff];
                  SinY := (Y1 - VerticalCenter) * TSin[Angle and $1ff];
                  X2 := Trunc((X1 - HorizontalCenter) * TSin[Angle and $1ff] + CosY) + HorizontalCenter;
                  Y2 := Trunc((X1 - HorizontalCenter) * TCos[Angle and $1ff] - SinY) + VerticalCenter;
                  {  Required Logic if Background.DIB.BitCount=32  }
                  if (Y2 >= 0) and (Y2 < Background.DIB.Height) and (X2 >= 0) and (X2 < Background.DIB.Width) then
                    begin
                      PLongArray(P2) := Background.DIB.ScanLine[Y2];
                      PLongArray(P1)[X1] := PLongArray(P2)[FrameWidth - X2];
                    end
                  else
                    begin
                      if P1[X1] > 2 then PLongArray(P1)[X1] := PLongArray(P1)[X1] - 2 else PLongArray(P1)[X1] := 0;
                    end;
                  {  Required Logic if Background.DIB.BitCount=32  }
                end;
            end;
          if DXDraw01.CanDraw then
            begin
              DXDraw01.Surface.Assign(DXDIB01.DIB);
              DXDraw01.Flip;
            end;
          Application.ProcessMessages;
          if Closing then Exit;
        end;
      BitBtn11Click(Sender);
    end;
    procedure TMainForm.BitBtn06Click(Sender: TObject);
    var
      P1, P2: PByteArray;
      ActualDistance, Distance,CosY, SinY: real;
      X1, Y1, X2, Y2, HorizontalCenter, VerticalCenter, A, B, Angle, DistortionFactor: Integer;
    begin
      Closing := True;
      Application.ProcessMessages;
      Closing := False;
      DXDIB01.DIB.SetSize(Background.DIB.Width, Background.DIB.Height, Background.DIB.BitCount);
      HorizontalCenter := Background.DIB.Width div 2;
      VerticalCenter := Background.DIB.Height div 2;
      Distance := sqrt(sqr(HorizontalCenter) + sqr(VerticalCenter)) * 0.75;
      for A := 0 to 63 do
        begin
          B := A*8;
          for Y1 := 0 to DXDIB01.DIB.Height - 1 do
            begin
              P1 := DXDIB01.DIB.ScanLine[Y1];
              DistortionFactor := sqr(Y1 - VerticalCenter);
              for X1 := 0 to (DXDIB01.DIB.Width) - 1 do
                begin
                  ActualDistance := 1 - (sqrt((sqr(X1 - HorizontalCenter) + DistortionFactor))/Distance);
                  Angle := 384 + Trunc( (ActualDistance)* B );
                  CosY := (Y1 - VerticalCenter) * TCos[Angle and $1ff];
                  SinY := (Y1 - VerticalCenter) * TSin[Angle and $1ff];
                  X2 := Trunc((X1 - HorizontalCenter) * TSin[Angle and $1ff] + CosY) + HorizontalCenter;
                  Y2 := Trunc((X1 - HorizontalCenter) * TCos[Angle and $1ff] - SinY) + VerticalCenter;
                  {  Required Logic if Background.DIB.BitCount=32  }
                  if (Y2 >= 0) and (Y2 < Background.DIB.Height) and (X2 >= 0) and (X2 < Background.DIB.Width) then
                    begin
                      PLongArray(P2) := Background.DIB.ScanLine[Y2];
                      PLongArray(P1)[X1] := PLongArray(P2)[FrameWidth - X2];
                    end
                  else
                    begin
                      if P1[X1] > 2 then PLongArray(P1)[X1] := PLongArray(P1)[X1] - 2 else PLongArray(P1)[X1] := 0;
                    end;
                  {  Required Logic if Background.DIB.BitCount=32  }
                  end;
              end;
            if DXDraw01.CanDraw then
              begin
                DXDraw01.Surface.Assign(DXDIB01.DIB);
                DXDraw01.Flip;
              end;
          Application.ProcessMessages;
          if Closing then Exit;
        end;
      for A := 64 downto 0 do
        begin
          B := A*8;
          for Y1 := 0 to DXDIB01.DIB.Height - 1 do
            begin
              P1 := DXDIB01.DIB.ScanLine[Y1];
              DistortionFactor := sqr(Y1 - VerticalCenter);
              for X1 := 0 to (DXDIB01.DIB.Width)-1 do
                begin
                  ActualDistance := 1-(sqrt((sqr(X1 - HorizontalCenter) + DistortionFactor))/Distance);
                  Angle := 384 + Trunc( (ActualDistance)* B );
                  CosY := (Y1 - VerticalCenter) * TCos[Angle and $1ff];
                  SinY := (Y1 - VerticalCenter) * TSin[Angle and $1ff];
                  X2 := Trunc((X1 - HorizontalCenter) * TSin[Angle and $1ff] + CosY) + HorizontalCenter;
                  Y2 := Trunc((X1 - HorizontalCenter) * TCos[Angle and $1ff] - SinY) + VerticalCenter;
                  {  Required Logic if Background.DIB.BitCount=32  }
                  if (Y2 >= 0) and (Y2 < Background.DIB.Height) and (X2 >= 0) and (X2 < Background.DIB.Width) then
                    begin
                      PLongArray(P2) := Background.DIB.ScanLine[Y2];
                      PLongArray(P1)[X1] := PLongArray(P2)[FrameWidth - X2];
                    end
                  else
                    begin
                      if P1[X1] > 2 then PLongArray(P1)[X1] := PLongArray(P1)[X1] - 2 else PLongArray(P1)[X1] := 0;
                    end;
                  {  Required Logic if Background.DIB.BitCount=32  }
                end;
            end;
          if DXDraw01.CanDraw then
            begin
              DXDraw01.Surface.Assign(DXDIB01.DIB);
              DXDraw01.Flip;
            end;
          Application.ProcessMessages;
          if Closing then Exit;
        end;
      BitBtn11Click(Sender);
    end;
    procedure TMainForm.BitBtn07Click(Sender: TObject);
    const
     AmountOfSpray = 500;
    var
      X, Y, C: Integer;
      AllBlack: Boolean;
      P1, P2, P3: PByteArray;
    begin
      Closing := True;
      Application.ProcessMessages;
      Closing := False;
      DXDIB01.DIB.SetSize(Background.DIB.Width,Background.DIB.Height,Background.DIB.BitCount);
      for C:=0 to AmountOfSpray do begin
        DXDIB01.DIB.Pixels[ random(Background.DIB.Width-1), random(Background.DIB.Height-1)] :=0;
      end;
      repeat
        AllBlack := True;
        for Y:=0 to DXDIB01.DIB.Height -1 do
          begin
            P2 := DXDIB01.DIB.ScanLine[Y];
            for X:=0 to DXDIB01.DIB.Width-1 do
              begin
              {  Required Logic if Background.DIB.BitCount=32  }
                if PLongArray(P2)[X] < 16 then
                  begin
                    if PLongArray(P2)[X] > 0 then AllBlack := false;
                    if Y > 0 then
                      begin
                        PLongArray(P1) := DXDIB01.DIB.ScanLine[Y - 1];
                        if PLongArray(P1)[X] > 4 then PLongArray(P1)[X] := PLongArray(P1)[X] - 4 else PLongArray(P1)[X] := 0;
                        if X > 0 then if PLongArray(P1)[X - 1] > 2 then PLongArray(P1)[X - 1] := PLongArray(P1)[X - 1] - 2 else PLongArray(P1)[X - 1] := 0;
                        if X < (DXDIB01.DIB.Width - 1) then if PLongArray(P1)[X + 1] > 2 then PLongArray(P1)[X + 1] := PLongArray(P1)[X + 1] - 2 else PLongArray(P1)[X + 1] := 0;
                      end;
                    if Y < (DXDIB01.DIB.Height - 1) then
                      begin
                        PLongArray(P3) := DXDIB01.DIB.ScanLine[Y + 1];
                        if PLongArray(P3)[X] > 4 then PLongArray(P3)[X] := PLongArray(P3)[X] - 4 else PLongArray(P3)[X] := 0;
                        if X > 0 then if PLongArray(P3)[X - 1] > 2 then PLongArray(P3)[X - 1] := PLongArray(P3)[X - 1] - 2 else PLongArray(P3)[X - 1] := 0;
                        if X < (DXDIB01.DIB.Width - 1) then if PLongArray(P3)[X + 1] > 2 then PLongArray(P3)[X + 1] := PLongArray(P3)[X + 1] - 2 else PLongArray(P3)[X + 1] := 0;
                      end;
                    if PLongArray(P2)[X] > 8 then PLongArray(P2)[X] := PLongArray(P2)[X] - 8 else PLongArray(P2)[X] := 0;
                    if X > 0 then if PLongArray(P2)[X - 1] > 4 then PLongArray(P2)[X - 1] := PLongArray(P2)[X - 1] - 4 else PLongArray(P2)[X - 1] := 0;
                    if X < (DXDIB01.DIB.Width - 1) then if PLongArray(P2)[X + 1] > 4 then PLongArray(P2)[X + 1] := PLongArray(P2)[X + 1] - 4 else PLongArray(P2)[X + 1] := 0;
                  end;
              {  Required Logic if Background.DIB.BitCount=32  }
              end;
          end;
        if DXDraw01.CanDraw then
          begin
            DXDraw01.Surface.Assign(DXDIB01.DIB);
            DXDraw01.Flip;
          end;
        Application.ProcessMessages;
      until (AllBlack or Closing);
    end;
    procedure TMainForm.BitBtn08Click(Sender: TObject);
    var
      Tmp: Byte;
    begin
      Closing := True;
      Application.ProcessMessages;
      Closing := False;
      DXDIB01.DIB.SetSize(Background.DIB.Width, Background.DIB.Height, Background.DIB.BitCount);
      CT := 0;
      NW := 1;
      repeat
        WaterFrameUpdate;
        WaterFrameRender(DXDIB01.DIB);
        Tmp := CT;
        CT := NW;
        NW := Tmp;
        if DXDraw01.CanDraw then begin
          DXDraw01.Surface.Assign(DXDIB01.DIB);
          DXDraw01.Flip;
        end;
        Application.ProcessMessages;
      until (Closing);
    end;
    procedure TMainForm.BitBtn09Click(Sender: TObject);
    var
      Tmp: Byte;
      x,y: Smallint;
    begin
      Closing := True;
      Application.ProcessMessages;
      Closing := False;
      DXDIB01.DIB.SetSize(Background.DIB.Width, Background.DIB.Height, Background.DIB.BitCount);
      CT := 0;
      NW := 1;
      repeat
        x := 40 + random(FrameWidth - 40);
        y := 40 + random(FrameHeight - 40);
        WaterBubleDrop(X, Y, 10, 25);
        WaterFrameUpdate;
        WaterFrameRender(DXDIB01.DIB);
        Tmp := CT;
        CT := NW;
        NW := Tmp;
        if DXDraw01.CanDraw then begin
          DXDraw01.Surface.Assign(DXDIB01.DIB);
          DXDraw01.Flip;
        end;
        Application.ProcessMessages;
      until (Closing);
    end;
    procedure TMainForm.BitBtn10Click(Sender: TObject);
    var
      Tmp: Byte;
      CosY, SinY: real;
      X1, Y1, X2, Y2, HorizontalIncrement, VerticalIncrement, HorizontalCenter, VerticalCenter, Angle: Smallint;
    const
      HorizontalStartingPoint = 80;
      VerticalStartingPoint = 80;
    begin
      Closing := True;
      Application.ProcessMessages;
      Closing := False;
      DXDIB01.DIB.SetSize(Background.DIB.Width, Background.DIB.Height, Background.DIB.BitCount);
      HorizontalCenter := Background.DIB.Width div 2;
      VerticalCenter := Background.DIB.Height div 2;
      CT := 0;
      NW := 1;
      Angle := 0;
      X2 := 4; HorizontalIncrement := 4;
      Y2 := 4; VerticalIncrement := 3;
      WaterBubleDrop(HorizontalCenter,VerticalCenter,40,-100);
      repeat
        CosY := (VerticalStartingPoint - VerticalCenter) * TCos[Angle and $1ff];
        SinY := (VerticalStartingPoint - VerticalCenter) * TSin[Angle and $1ff];
        X1 := Trunc((HorizontalStartingPoint - HorizontalCenter) * TSin[Angle and $1ff] + CosY) + HorizontalCenter;
        Y1 := Trunc((HorizontalStartingPoint - HorizontalCenter) * TCos[Angle and $1ff] - SinY) + VerticalCenter;
        Angle := Angle + 8;
        WaterBubleDrop(X1, Y1, 4, -500);
        WaterBubleDrop(X2, Y2, 4, -500);
        X2 := X2 + HorizontalIncrement;
        Y2 := Y2 + VerticalIncrement;
        if (X2 < 4) or (X2 > FrameWidth - 4) then HorizontalIncrement := -HorizontalIncrement;
        if (Y2 < 4) or (Y2 > FrameHeight - 4) then VerticalIncrement := -VerticalIncrement;
        WaterFrameUpdate;
        WaterFrameRender(DXDIB01.DIB);
        Tmp := CT;
        CT := NW;
        NW := Tmp;
        if DXDraw01.CanDraw then begin
          DXDraw01.Surface.Assign(DXDIB01.DIB);
          DXDraw01.Flip;
        end;
        Application.ProcessMessages;
      until (Closing);
    end;
    procedure TMainForm.BitBtn11Click(Sender: TObject);
     begin
      DXDIB01.DIB.SetSize(Background.DIB.Width, Background.DIB.Height, Background.DIB.BitCount);
      DXDIB01.DIB.Assign(Background.DIB);
      if DXDraw01.CanDraw then begin
        DXDraw01.Surface.Assign(DXDIB01.DIB);
        DXDraw01.Flip;
      end;
    end;
    procedure TMainForm.BitBtn12Click(Sender: TObject);
    begin
      MainForm.Close;
    end;
    procedure TMainForm.WaterFrameUpdate;
    const
      DampingCoefficient = 4;
    var
      X, Y, N: Smallint;
    begin
      for Y := 2 to FrameHeight-2 do begin
        for X := 2 to FrameWidth-2 do begin
          N := ( WaterFrame[CT, X-1, Y] + WaterFrame[CT, X-2, Y] + WaterFrame[CT, X+1, Y] + WaterFrame[CT, X+2, Y] +
               WaterFrame[CT, X, Y-1] + WaterFrame[CT, X, Y-2] + WaterFrame[CT, X, Y+1] + WaterFrame[CT, X, Y+2] +
               WaterFrame[CT, X-1, Y-1] + WaterFrame[CT, X+1, Y-1] + WaterFrame[CT, X-1, Y+1] + WaterFrame[CT, X+1, Y+1] )
               div 6 - WaterFrame[NW, X, Y];
          asm
            PUSH BX
            MOV BX, N
            SAR BX, DampingCoefficient
            SUB N, BX
            POP BX
          end;
          WaterFrame[NW, X, Y] := N;
        end;
      end;
    end;
    procedure TMainForm.WaterFrameInitialize;
    var
      X, Y: SmallInt;
    begin
      for Y := 0 to FrameHeight do begin
        for X := 0 to FrameWidth do begin
          WaterFrame[CT, X, Y] := 0;
          WaterFrame[NW, X, Y] := 0;
        end;
      end;
    end;
    procedure TMainForm.WaterFramePrepare;
    const
      RefractiveIndex = 4.0;
    var
      C, D: SmallInt;
    begin
      for C := -256 to 255 do begin
        D := C div 4;
        UltimateDisplacement[C + 256] := Byte(Trunc(Tan(ArcSin((Sin(ArcTan(D)) / RefractiveIndex))) * D));
      end;
      for C := 0 to 511 do begin
        TSin[C] := Sin( ((C * 360) / 511) * Pi / 180 );
        TCos[C] := Cos( ((C * 360) / 511) * Pi / 180 );
      end;
      WaterFrameInitialize;
    end;
    procedure TMainForm.WaterFrameRender(DIB: TDIB);
    var
      X, Y, NewColor, HorizontalDifference, VerticalDifference, HorizontalDisplacement, VerticalDisplacement: Smallint;
    begin
      for Y := 0 to FrameHeight do begin
        for X := 0 to FrameWidth do begin
          HorizontalDifference := WaterFrame[NW, X+1, Y] - WaterFrame[NW, X, Y];
          VerticalDifference := WaterFrame[NW, X, Y+1] - WaterFrame[NW, X, Y];
          HorizontalDisplacement := UltimateDisplacement[HorizontalDifference + 256];
          VerticalDisplacement := UltimateDisplacement[VerticalDifference + 256];
          if HorizontalDifference < 0 then begin
            if (VerticalDifference<0) then
              NewColor := Background.DIB.Pixels[X-HorizontalDisplacement,Y-VerticalDisplacement]
            else
              NewColor := Background.DIB.Pixels[X-HorizontalDisplacement,Y+VerticalDisplacement]
          end else begin
            if (VerticalDifference<0) then
              NewColor := Background.DIB.Pixels[X+HorizontalDisplacement,Y-VerticalDisplacement]
            else
              NewColor := Background.DIB.Pixels[X+HorizontalDisplacement,Y+VerticalDisplacement]
          end;
          DIB.Pixels[X, Y] := NewColor;
        end;
      end;
    end;
    procedure TMainForm.WaterBubleDrop(X,Y,W,SplashStrength: Integer);
    var
      U, V: Integer;
      HorizontalDistanceSquare, VerticalDistanceSquare, BubbleWidthSquare: Integer;
    begin
      BubbleWidthSquare := sqr(W);
      if (X > W) and (X < FrameWidth - W) and (Y > W) and (Y < FrameHeight - W) then begin
        for V := Y - W to Y + W do begin
          VerticalDistanceSquare := sqr(V - Y);
          for U := X - W to X + W do begin
            HorizontalDistanceSquare := sqr(U - X);
            if (HorizontalDistanceSquare + VerticalDistanceSquare) <= BubbleWidthSquare then begin
              WaterFrame[CT, U, V] := SplashStrength*Trunc(W - sqrt(HorizontalDistanceSquare + VerticalDistanceSquare));
            end;
          end;
        end;
      end;
    end;
    procedure TMainForm.FormCreate(Sender: TObject);
    begin
      WaterFramePrepare;
    end;
    procedure TMainForm.FormClose(Sender: TObject; var Action: TCloseAction);
    begin
      DXTimer01.Enabled := true;
      Closing := True;
    end;
    procedure TMainForm.DXDraw01Finalize(Sender: TObject);
    begin
      DXTimer01.Enabled := false;
    end;
    procedure TMainForm.DXDraw01Initialize(Sender: TObject);
    begin
      DXTimer01.Enabled := true;
    end;
    procedure TMainForm.DXDraw01MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
    begin
      WaterBubleDrop(X, Y, 15, -4);
    end;
    procedure TMainForm.DXDraw01MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
    begin
      if (X > 0) and (X < FrameWidth) and (Y > 0) and (Y < FrameHeight) then begin
        WaterBubleDrop(X, Y, 8, -64);
      end;
    end;
    procedure TMainForm.DXTimer01Timer(Sender: TObject; LagCount: Integer);
    begin
      if not DXDraw01.CanDraw then exit;
      DXDraw01.Surface.Fill(0);
      DXDIB01.DIB.SetSize(Background.DIB.Width,Background.DIB.Height,Background.DIB.BitCount);
      DXDIB01.DIB.Assign(Background.DIB);
      if DXDraw01.CanDraw then
      begin
        DXDraw01.Surface.Assign(DXDIB01.DIB);
        with DXDraw01.Surface.Canvas do
          begin
            Brush.Style := bsClear;
            Font.Color := $efefef;
            Font.Size := 30;
            Textout((Background.DIB.Width - TextWidth('M/DD/YY HH:MM:SS AM')) div 2, (Background.DIB.Height - 30) div 2, DateTimeToStr(Now));
            Release;
          end;
      end;
      DXDraw01.Flip;
    end;
    end.

My problem is that all the effects except Water and Rain effects are working properly. In my project the Background.DIB is a 32Bit Image. Plaese help me. As per my knowledge, the problem is in the following procedure definations : 

    procedure WaterFrameUpdate;
    procedure WaterFrameInitialize;
    procedure WaterFramePrepare;
    procedure WaterFrameRender(DIB: TDIB);
    procedure WaterBubleDrop(X, Y, W, SplashStrength: Integer);

I think one or more procedure definations are having 8Bit Color operation. I can't understand which one is 8Bit Color operation. I have also tried to implement LongArray but it also gives error. Then I have tried

      asm
        PUSH BX
        MOV BX, N
        SAR BX, DampingCoefficient
        SUB N, BX
        POP BX
      end;

as

      asm
        PUSH ESI
        MOV ESI, N
        SAR ESI, DampingCoefficient
        SUB N, ESI
        POP ESI
      end;

or

      asm
        PUSH EDI
        MOV EDI, N
        SAR EDI, DampingCoefficient
        SUB N, EDI
        POP EDI
      end;


but it gives an error telling "Operand size mismatch". Plaese, Please help me.