unit l_game;

interface

uses
 Windows, OpenGL, MiniFMOD,
 l_gl,
 l_sound,
 l_input,
 l_math,
 l_utils,
 l_map,
 l_camera,
 l_player,
 l_model,
 l_model_v2,
 l_spider,
 l_zenit,
 l_particle,
 l_menu;

procedure Game_Init;
procedure Game_Start;
procedure Game_Free;
procedure Game_Render;
procedure Game_Update;

var
 Map    : TMap;
 Camera : TCamera;
 Player : TPlayer;

 // шрифты
 impact    : DWORD;
 courier   : DWORD;
 arial     : DWORD;
 fixedsys  : DWORD;

 debug  : boolean = false;

 inmenu : boolean = true;

implementation

const
 IDLE_TIME = 500; // перерыв - 10 секунд

var
 TimeToDie   : integer = IDLE_TIME;
 SpiderNeed  : integer;
 SpiderCount : integer;

procedure Game_Init;
begin
randomize;
Menu_Init;
Particle_Init;
Player.Init;
Camera.Init;
Camera.Target := @Player;
Map.Init;

gun_xmd.Init;
gun_xmd.LoadFromFile('data\models\gun.xmd');
// пауки
spider_xmd.Init;
spider_xmd.LoadFromFile('data\models\spider.xmd');
snd__spider_attack := snd_Load('Data\sounds\spider\attack.wav');
snd__spider_die    := snd_Load('Data\sounds\spider\die.wav');
// пушки
zenit_xmd.Init;
zenit_xmd.LoadFromFile('data\models\zenit.xmd');
snd__zenit_fire := snd_Load('Data\sounds\zenit\fire.wav');
snd__zenit_aim  := snd_Load('Data\sounds\zenit\aim.wav');

impact   := glFont_Init('Impact', 16, 16);
courier  := glFont_Init('Courier New', 16, 8);
arial    := glFont_Init('Impact', 32, 32);
fixedsys := glFont_Init('Fixedsys', 16, 16);
end;

procedure Game_Start;
begin
Player.Start;
Particle_Clear;
Map.LoadFromFile('map1');
XMFree;
XMLoadFromFile('data\music\rave.xm');
XMPlay;
TimeToDie   := IDLE_TIME;
SpiderNeed  := 25;
SpiderCount := SpiderNeed;
end;

procedure Game_Free;
begin
Menu_Free;
Player.Free;
Particle_Free;
glFont_Free(impact);
glFont_Free(courier);
glFont_Free(arial);
glFont_Free(fixedsys);

Map.Clear(true);
spider_xmd.Clear;
gun_xmd.Clear;
zenit_xmd.Clear;
// пауки
snd_Free(snd__spider_attack);
snd_Free(snd__spider_die);
// пушки
snd_Free(snd__zenit_fire);
snd_Free(snd__zenit_aim);
XMStop;
XMFree;
end;

procedure Game_Update;
var
 z : PZenit;
begin
Input_Update;
if inMenu then
 Menu_Update
else
 begin
 if TimeToDie > 1 then
  dec(TimeToDie);

 if Player.Health > 0 then
 if (TimeToDie = 1) and (SpiderCount > 0) then // МАЧИ КАЗЛОФФФ!!!
  if random(15) = 0 then
   with Map.Spider_add^ do
    begin
     case random(3) of
     0 : Pos := Vector(220, 0, 50);
     1 : Pos := Vector(220, 0, 220);
     2 : Pos := Vector( 50, 0, 220);
     end;
    dec(SpiderCount);
    if SpiderCount = 0 then
     TimeToDie := 0;
    GetAngle;
    end;

 Particle_Update;
 Player.Update;

 if Player.Health > 0 then
 if (Map.Spiders = 0) and (TimeToDie = 0) then
  begin
  TimeToDie := IDLE_TIME; // уф... заслуженный отдых
  inc(SpiderNeed, 25);
  SpiderCount := SpiderNeed;
  z := Map.Zenit;
  while z <> nil do
   begin
   z^.Die;
   z := z^.Next;
   end;
  XMStop;
  XMPlay;
  end;
 Camera.Update; // Вертим башней меняем положение камеры
 Map.Update;
 end;
MDelta.X := 0;
MDelta.Y := 0;
end;

procedure Game_Render;
{
 function BStr(b: boolean): string;
 begin
 if b then
  Result := ' (on)  '
 else
  Result := ' (off) ';
 end;
}
begin
if inMenu then
 Menu_Draw
else
 begin
 glClear(GL_DEPTH_BUFFER_BIT);
 glBlend(0);
 Camera.SetProj;
 Camera.SetRender;
 Map.Render;
 Particle_Render;
 Player.Render;
 // вывод отладочной информации
 {if debug then  // скажем нет читерами и дебагерам! :D
  begin
  glBlend(0);
  glTex_Disable;
  glDisable(GL_DEPTH_TEST);
  glSetOrtho(0, 0, 640, 480);
  glColor3f(0, 1, 1);
  glTextOut('Spiders  : ' + IntToStr(vis_spiders) + '/' + IntToStr(Map.Spiders), 32, 448, impact);
  glTextOut('Particle : ' + IntToStr(Particle_Count), 32, 432, impact);
  glTextOut('Zenits   : ' + IntToStr(Map.Zenits), 32, 416, impact);
  glColor3f(0.7, 1, 0.5);
  glTextOut('FPS: ' + IntToStr(glFPS), 32, 32, impact);
  glColor3f(1, 1, 1);
  glTextOut('Debug keys:', 32, 48, courier);
  glTextOut('F1 :' + BStr(debug)   + 'Debug menu',      40, 64, courier);
  glTextOut('F2 :' + BStr(detail)  + 'Detail Texture',  40, 80, courier);
  glTextOut('F3 :' + BStr(vsync)   + 'VSync',           40, 96, courier);
  glTextOut('F4 :' + BStr(culling) + 'Frustum Culling', 40, 112, courier);
  end;}
 end;
glSwap;
end;

end.

