unit _Render;

interface

uses
  QuadEngine,
  _Geometry;
  
const
 tile_size = 128;
 Ground_size = 512;

 max_parts = 2000;

type
  TParticle = record
    tip:byte;
    Coord,
    Vector:TVector;
    life:byte;
  end;

  TEmiter = class
    parts: array [0..max_parts] of TParticle;
   public       
    Wind:TVector;
    New_Wind:TVector;
    procedure render(Camera:TVector;Scale:single);
    procedure move;
    procedure add_particle(Point,Vector:TVector;tip,life:byte);
  end;

var
  Quad:IQuadRender;
  Font:IQuadFont;
  Emiter:TEmiter;
 Particles_Tex,
 Bullet_tex,
 Units_tex:IQuadTexture;

procedure Load_Units_Texture;
procedure Draw_Tank(X,Y:Single;TA,CA,Scale:Single;Color:Cardinal;TS,CS:byte);
procedure Draw_Heli(X,Y:Single;H,HA,Scale,Ang:Single;Color:Cardinal);     
procedure Draw_HeliTank(X,Y:Single;H,HA,Scale,Ang:Single;t:byte);
procedure Draw_Bullet(Pt:TVector;Angle,Scale:single);   
procedure Draw_Double_Bullet(Pt:TVector;Angle,Scale:single); 
procedure Draw_Gaus(Pt:TVector;Angle,Scale:single);    
procedure Draw_Platform(X,Y:Single;CA,Scale:Single;anim:byte;Color:Cardinal;CS:byte);

implementation

{$REGION 'Render Something'}
procedure Load_Units_Texture;
begin
 Units_tex:=Quad.CreateAndLoadTexture(0,'data/units.png',tile_size,tile_size);
 Bullet_tex:=Quad.CreateAndLoadTexture(0,'data/bullets.png',16,128);
 Particles_Tex:=Quad.CreateAndLoadTexture(0,'data/particles.png',64,64);
 Font:=Quad.CreateAndLoadFont('data/cg.png','data/cg.qef');
end;
                       
procedure Draw_Tank(X,Y:Single;TA,CA,Scale:Single;Color:Cardinal;TS,CS:byte);
var
 f:single;
begin
 f:=0.6;
 Units_tex.DrawRot(X+5*Scale,Y+5*Scale,TA,Scale*f,$31000000,TS);
 Units_tex.DrawRot(X+5*Scale,Y+5*Scale,CA,Scale*f,$31000000,CS);
 Units_tex.DrawRot(X,Y,TA,Scale*f,Color,TS);
 Units_tex.DrawRot(X,Y,CA,Scale*f,Color,CS);
end;

procedure Draw_Platform(X,Y:Single;CA,Scale:Single;anim:byte;Color:Cardinal;CS:byte);
var
 f:single;
begin
 f:=0.8;
 Units_tex.DrawRot(X+5*Scale,Y+5*Scale,0,Scale*f,$31000000,8);
 Units_tex.DrawRot(X+5*Scale,Y+5*Scale,CA,Scale*f*anim/255,$31000000,CS);
 Units_tex.DrawRot(X,Y,0,Scale*f,Color,8);
 Units_tex.DrawRot(X,Y,CA,Scale*f*anim/255,Color,CS);
end;

procedure Draw_Heli(X,Y:Single;H,HA,Scale,Ang:Single;Color:Cardinal);
var
 f:single;
begin
 f:=0.6;
 Units_tex.DrawRot(X+H*Scale,Y+H*Scale,HA,Scale*f,$31000000,6);
 Units_tex.DrawRot(X,Y,HA,Scale*f,Color,6);
 Units_tex.DrawRot(X+H*Scale,Y+H*Scale,Ang,Scale*f,$31000000,7);
 Units_tex.DrawRot(X,Y,Ang,Scale*f,Color,7);
end;

procedure Draw_HeliTank(X,Y:Single;H,HA,Scale,Ang:Single;t:byte);
var
 f:single;
 Color:Cardinal;
begin
 f:=0.6;
 Color:=$ff404040;
 Units_tex.DrawRot(X+H*Scale,Y+H*Scale,HA,Scale*f,$31000000,0);
 Units_tex.DrawRot(X,Y,HA,Scale*f,Color,0);
 Units_tex.DrawRot(X+H*Scale,Y+H*Scale,Ang,Scale*f,$31000000,t);
 Units_tex.DrawRot(X,Y,Ang,Scale*f,Color,t);
end;

procedure Draw_Bullet(Pt:TVector;Angle,Scale:single);
begin
 Bullet_tex.DrawRot(Pt[0],Pt[1],Angle,Scale*0.6,$ffffffff,0);
end;

procedure Draw_Double_Bullet(Pt:TVector;Angle,Scale:single);
begin
 Bullet_tex.DrawRot(Pt[0],Pt[1],Angle,Scale*0.8,$ffffffff,1);
end;

procedure Draw_Gaus(Pt:TVector;Angle,Scale:single);
begin
 Bullet_tex.DrawRot(Pt[0],Pt[1],Angle,Scale*0.6,$ffffffff,2);
end;
{$ENDREGION}
//Particles
{$REGION 'Render'}
procedure TEmiter.render(Camera:TVector;Scale:single);
var i:word;
begin
 for i:=Max_parts downto 0 do
 if parts[i].tip>0 then
  begin
   Particles_Tex.DrawRot(
          (parts[i].Coord[0]-Camera[0])*Scale,
          (parts[i].Coord[1]-Camera[1])*Scale,
          0,Scale-6*Scale*Parts[i].life/$ff,
          Parts[i].life*4*$1000000+$ffffff,
          parts[i].tip-1);
  end;
end;
{$ENDREGION}

{$REGION 'Move'}
procedure TEmiter.Move;
var i:word;
begin                   
 //wind change
 if Random(200)=0 then
   New_Wind:=Vector(0.05*Random(10)-0.25,0.05*Random(10)-0.25);
 Wind:=plus(multi(Wind,0.9),multi(New_Wind,0.1));
 for i:=0 to Max_parts do
 if parts[i].tip>0 then
  begin
   Parts[i].Coord:=plus(Parts[i].Coord,Parts[i].Vector);
   Parts[i].Vector:=plus(Parts[i].Vector,wind);
   if (Parts[i].life<20) and (parts[i].tip=1) or (parts[i].tip=2) then
    begin
     Parts[i].tip:=Parts[i].tip+2;
    end;
   if (Parts[i].life=1) then Parts[i].tip:=0;
   if (Parts[i].life>0) then dec(Parts[i].life);
  end;
end;
{$ENDREGION}

{$REGION 'Add'}
procedure TEmiter.add_particle(Point,Vector:TVector;tip,life:byte);  
var i:word;
begin
 for i:=0 to Max_parts do
 if parts[i].tip=0 then
  begin
   parts[i].Coord:=Point;
   parts[i].Vector:=Vector;
   parts[i].tip:=tip+1;
   parts[i].life:=life;
   break;
  end;
end;        
{$ENDREGION}

end.
