{$M 65520, 20000, 655360}
{This version uses EMM Memory and my coolest keyboard handler}
Uses Objects3,Graph,My_Mem,CoolKey;
Procedure EGAVGADriver;external;
Function KeyPressed:boolean;assembler;
asm
  mov ah, 1
  int 16h
  mov al, 0
  jz @@2
  mov al, 1
@@2:
end;{KeyPressed}
{----------------------}
Function ReadKey:char;assembler;
asm
  mov ah, 00
  int 16h
  cmp al, 0
  jnz @@1
  mov al, ah
@@1:
end;
{ReadKey}
var
  Wrld          : PWorld;
  Timer         : LongInt Absolute $0040:$006c;
  BegMem,MinMem : LongInt;
  Last,i,Beg    : Longint;
  MyRAH         : pRAH;
  MyStinger     : pSting;
  MyExpl        : pExpl;
  mP            : TParams;
  Page          : byte;
  gD,gM         : integer;

  ifExit        : boolean;
  KT            : PKeyTable;
begin
  BegMem := MaxAvail;MinMem := BegMem;
  if not InitEMM then
   Begin
     WriteLn('Sorry, can''t find EMM driver (probably there is no line in config.sys ''device=EMM386''');
     Halt(233);
   end;
  if not TestAllocEMM(300 shl 10) then
   Begin
     WriteLn('Sorry, no enought EMS, need ', 300 shl 10, ' get ', MaxEMM);
     Halt(233);
   end;
  TIME_FACTOR := 0.2;
  FPS         := 1;
  FIELD_X     := 600;
  GLOB_G      := 0.1;

  Randomize;

  {$L EGAVGA.OBJ}
  RegisterBGIDriver(@EGAVGADriver);
  Gd:=VGA;
  Gm:=VGAMed;
  INitGraph(gD,gM,'');
  SIZE_Y := 350;
  New(Wrld,Init('BG2.dat'));
  Wrld^.Message('Move, rotate stinger with keys, change dAngle with Del/PgDown',1,Red);
  With mP do begin
    Pos.x:=75.0;
    Pos.y := 300.0;
    Speed.X := 5.0;
    Speed.Y := 0.0;
    Accel.X := 0.0;
    Accel.Y := 0.0;
  end;
  New(MyRAH,Init('rah-66-2.dat',mP,100));
  with MyRah^ do
  begin
   CountBase := 2;
   countVar  := 2;

   SpeedBase:=10;
   SpeedVar := 3;

   TrapBase := 60;
   TrapVar  := 10;
   NextTrap := TrapBase + random(TrapVar) - (TrapVar shr 1);
  end;
  Wrld^.AddObject(MyRAH);
{
  With mP do begin
    Pos.x:=75.0;
    Pos.y := 200.0;
    Speed.X := 7.0;
    Speed.Y := 0.0;
    Accel.X := 0.0;
    Accel.Y := 0.0;
  end;
  New(MyRAH,Init('rah-66-2.dat',mP,105));
  with MyRah^ do
  begin
   CountBase := 5;
   countVar  := 2;

   SpeedBase:=10;
   SpeedVar := 3;

   TrapBase := 30;
   TrapVar  := 10;
   NextTrap := TrapBase + random(TrapVar) - (TrapVar shr 1);
  end;
  Wrld^.AddObject(MyRAH);
 }
  With mP do begin
    Pos.x:=520.0;
    Pos.y := 60.0;
    Speed.X := 10;
    Speed.Y := 0;
    Accel.X := 0.0;
    Accel.Y := 0.0;
  end;
  New(MyStinger,Init('stinger.dat',mP,10,110));
  Wrld^.AddObject(MyStinger);
  MyStinger^.ChangeAngle(90);

  Last := timeR;
  i:=0;
  page:=0;
  SetActivePage(0);
  Wrld^.Draw;
  SetActivePage(1);
  Wrld^.Draw;
  KT := InitKeyboard;
  ifExit := false;

  while not ifExit do
  begin
    if KT^[SC_ESCAPE] then ifExit := true;
    if MaxAvail < MinMem then MinMem := maxAvail;
     if KT^[SC_UP] and (not MyStinger^.started) and (MyStinger^.ObjType = 'Stinger') then
           MyStinger^.ChangeAngle(MyStinger^.Angle-1);
     if KT^[SC_DOWN] and (not MyStinger^.started) and (MyStinger^.ObjType = 'Stinger') then
           MyStinger^.ChangeAngle(MyStinger^.Angle+1);
     if KT^[SC_LEFT] and (not MyStinger^.started) and (MyStinger^.ObjType = 'Stinger') then begin
           MyStinger^.Params.Pos.x := MyStinger^.Params.Pos.x-1;
           if MyStinger^.Params.Pos.X < (MyStinger^.xsize^[0] shr 1) then
             MyStinger^.Params.Pos.x :=MyStinger^.xsize^[0] shr 1;
          end;
     if KT^[SC_RIGHT] and (not MyStinger^.started) and (MyStinger^.ObjType = 'Stinger') then begin
           MyStinger^.Params.Pos.x := MyStinger^.Params.Pos.x+1;
           if MyStinger^.Params.Pos.X > (FIELD_X-MyStinger^.xsize^[0] shr 1) then
             MyStinger^.Params.Pos.x :=(FIELD_X-MyStinger^.xsize^[0] shr 1)
          end;
     if KT^[SC_ENTER] then begin
            if MyStinger^.ObjType <> 'Stinger' then ifExit := true;
            if not MyRAH^.Started then
             begin
               Wrld^.StartObjects('RAH-66');
               Beg:=Timer;
               i:=0;
             end
            else if not MyStinger^.Started then
            begin
             Wrld^.StartObjects('Stinger');
             Wrld^.Message('',1,0);
            end;
          end;
     if KT^[SC_DELETE] and (not MyStinger^.started) and (MyStinger^.ObjType = 'Stinger') then begin
           Dec(MyStinger^.dAngle);
           if MyStinger^.dAngle < 2 then MyStinger^.dAngle := 1;
          end;
     if KT^[SC_PGDN] and (not MyStinger^.started) and (MyStinger^.ObjType = 'Stinger') then begin
           Inc(MyStinger^.dAngle);
           if MyStinger^.dAngle > 180 then MyStinger^.dAngle := 180;
          end;
{    if (MyRah^.Started or MyStinger^.Started) a then}
    begin
      Inc(i);
      SetActivePage(Page);
      Wrld^.Draw;
      repeat until (Port[$03DA] and 8) <> 8;
      repeat until (Port[$03DA] and 8) =  8;
      SetVisualPage(Page);
      Page:=1-Page;
    end;
    if (MyRah^.Started or MyStinger^.Started) then
    begin
     repeat until (Timer-Last) <> 0;
     Wrld^.Frame(Timer-Last);
    end;
    Last := timeR;
  end;
  Beg := Timer - Beg;
  Dispose(Wrld,Done);
  CloseGraph;
  if MaxAvail <> BegMem then WriteLn('Suxx, losing memory: ', BegMem-MaxAvail);
  WriteLn('MaxMemory - ', BegMem - MinMem);
  WriteLn('Average FPS - ', i/(Beg*0.055):0:4);
  CloseKeyboard;
end.