unit l_menu;

interface

uses
 Windows, Messages, OpenGL, KOL, err,
 l_gl, l_utils, l_math, MiniFMOD;
 
procedure Menu_Init;
procedure Menu_Load;
procedure Menu_Free;
procedure Menu_Message(msg, wp, lp: integer);
procedure Menu_Update;
procedure Menu_Draw;

procedure Add_Score(frags: integer);

implementation

uses
 l_game, l_model;

const
 logo_time = 1500;
 Menu_item : array [0..2] of string = ('СТАРТ','ПРОДОЛЖИТЬ','ВЫХОД');

type
 TScore = record
  Name  : string[16];
  Score : integer;
 end;

var
 BlurTex : TTexture;
 BlurAng : single;
 CurItem : integer;
 CurY    : single;
 logo       : TTexture;
 logo_idle  : integer = 0;
 spider_ang : single;
 Score   : array [0..7] of TScore; 
 Name    : string[16];

procedure Add_Score(frags: integer);
var
 i, j : integer;
begin
for i := 0 to 7 do
 if Score[i].Score < frags then
  begin
  for j := 7 downto i + 1 do
   Score[j] := Score[j - 1];
  Score[i].Name  := Name;
  Score[i].Score := frags;
  break;
  end;
end; 

procedure LoadScore;
var
 i : integer;
 F : File of Byte;
begin
for i := 0 to 7 do
 with Score[i] do
  begin
  Name  := 'Player';
  Score := 500 - i * 50;
  end;
if FileExists('score.dat') then
 try
  AssignFile(F, 'score.dat');
  Reset(F);
  BlockRead(F, Name, SizeOf(Name));
  BlockRead(F, Score, 8 * SizeOf(TScore));
  CloseFile(F);
 except
 end;
end;

procedure SaveScore;
var
 F : File of Byte;
begin
 try
  AssignFile(F, 'score.dat');
  Rewrite(F);
  BlockWrite(F, Name, SizeOf(Name));
  BlockWrite(F, Score, 8 * SizeOf(TScore));
  CloseFile(F);
 except
 end;
end;

procedure Menu_Init;
begin
glClamp := true;
BlurTex := glTex_Load('data\textures\menu\blur.jpg');
logo    := glTex_Load('data\textures\logo.jpg');
glClamp := false;
CurItem := 0;
spider_ang := 0;
XMLoadFromFile('data\music\baits.xm');
XMPlay;
CurY    := 128;
Name    := 'Player';
LoadScore;
end;

procedure Menu_Load;
begin
XMFree;
XMLoadFromFile('data\music\baits.xm');
XMPlay;
end;

procedure Menu_Free;
begin
glTex_Free(BlurTex);
glTex_Free(logo);
SaveScore;
end;

procedure Menu_Message(msg, wp, lp: integer);
begin
 case msg of
 WM_KEYDOWN :
  begin
   case wp of
   VK_UP   : dec(CurItem);
   VK_DOWN : inc(CurItem);
   VK_RETURN :
    case CurItem of
    0 : begin
        Game_Start;
        inMenu := false;
        end;
    1 : if Player.Health > 0 then inMenu := false;
    2 : isQuit := true;
    end;
   end;
  if CurItem > High(Menu_Item) then CurItem := 0;
  if CurItem < 0 then CurItem := High(Menu_Item);
  end;
 WM_CHAR :
  if wp > 32 then
   Name := Name + chr(wp);
  else
   if wp = 8 then
    Delete(Name, Length(Name), 1); 
 end;
end;

procedure Menu_Update;
begin
if logo_idle >= logo_time then
 begin
 spider_ang := spider_ang - 1;
 BlurAng := BlurAng + 2;
 with spider_xmd do
  begin
  // Текущее время анимации
  CurTime := (CurTime + 30) mod spider_xmd.MaxTime;
  // Текущий кадр
  CurFrame := 3 * CurTime div 100;
  end;
 CurY := CurY + (128 + CurItem * 64 - CurY)/8; 
 end
else
 inc(logo_idle, 20); // 1 тик - 10 мс
end;

procedure Draw_Selection(idx: integer);

 procedure Draw;
 const
  sizex = 128;
  sizey = 32;
 var
  px, py : single;
 begin
 px := 128;
 py := CurY;//128 + idx * sizey * 2;
 glBegin(GL_QUADS);
  glTexCoord2f(0, 0); glVertex2f(px - sizex, py - sizey);
  glTexCoord2f(1, 0); glVertex2f(px + sizex, py - sizey);
  glTexCoord2f(1, 1); glVertex2f(px + sizex, py + sizey);
  glTexCoord2f(0, 1); glVertex2f(px - sizex, py + sizey);
 glEnd;
 end;

begin
glBlend(2);
glMatrixMode(GL_TEXTURE);
glPushMatrix;
glTranslatef(0.5, 0.5, 0);
glRotatef(BlurAng, 0, 0, 1);
glTranslatef(-0.5, -0.5, 0);
glMatrixMode(GL_MODELVIEW);

glDisable(GL_DEPTH_TEST);
glTex_Enable(BlurTex);
glColor3f(1, 1, 1);
Draw;

glMatrixMode(GL_TEXTURE);
glTranslatef(0.5, 0.5, 0);
glScalef(-1, 1, 1);
glTranslatef(-0.5, -0.5, 0);
glMatrixMode(GL_MODELVIEW);

Draw;

glMatrixMode(GL_TEXTURE);
glPopMatrix;
glMatrixMode(GL_MODELVIEW);
end;

procedure Draw_Items;
var
 px, py : integer;
 i      : integer;
begin
glTex_Disable;
glBlend(0);
glColor3f(1, 1, 1);
glTextOut('Игрок: ' + Name, 32, 64, fixedsys);
for i := 0 to HIGH(Menu_Item) do
 begin
 // некрасивый кусочек кода
 if i <> 1 then
  glColor3f(0, 0, 0)
 else
  if Player.Health = 0 then
   glColor3f(0.5, 0.5, 0.5); // т.е. если не в игре - то продолдать нельзя
 px := 128 - Length(Menu_Item[i]) * 8;
 py := 128 + i * 64 + 4;
 glTextOut(Menu_Item[i], px, py, fixedsys);
 end;
end;

procedure Draw_Logo;
const
 X = 320 - 128;
 Y = 240 - 128;
 W = 256;
 H = 256;
begin
glTex_Enable(logo);
glBegin(GL_QUADS);
 glTexCoord2f(0, 0); glVertex2f(    X,     Y);
 glTexCoord2f(1, 0); glVertex2f(X + W,     Y);
 glTexCoord2f(1, 1); glVertex2f(X + W, Y + H);
 glTexCoord2f(0, 1); glVertex2f(    X, Y + H);
glEnd;
end;

procedure Draw_Spider;
begin
glTex_Disable;
glColor3f(1, 1, 1);
glBlend(0);
glEnable(GL_DEPTH_TEST);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glLight_Pos(GL_LIGHT0, Vector(100, 100, 100));
glEnableClientState(GL_COLOR_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
glEnableClientState(GL_VERTEX_ARRAY);

glPushMatrix;
glTranslatef(7, -6, -10);
glRotatef(-spider_ang, 0, 1, 0);
spider_xmd.Render;
glPopMatrix;

glPushMatrix;
glTranslatef(-7, -6, -10);
glRotatef(spider_ang, 0, 1, 0);
spider_xmd.Render;
glPopMatrix;

glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
glDisable(GL_LIGHTING);
glDisable(GL_DEPTH_TEST);
end;

procedure Draw_Score;
const
 px = 240;
 py = 128;
 sizex = 320;
 sizey = 128;
var
 i, y : integer; 
begin
glTex_Disable;
glBlend(1);
glColor4f(0, 0, 0, 0.5);
glBegin(GL_QUADS);
 glVertex2f(        px, py);
 glVertex2f(px + sizex, py);
 glVertex2f(px + sizex, py + sizey);
 glVertex2f(        px, py + sizey);
glEnd;
glColor4f(0, 0, 0, 1);
glBegin(GL_LINE_LOOP);
 glVertex2f(        px, py);
 glVertex2f(px + sizex, py);
 glVertex2f(px + sizex, py + sizey);
 glVertex2f(        px, py + sizey);
glEnd;

glBlend(0);
for i := 0 to 7 do
 begin
 if i = 0 then
  glColor3f(1, 0, 0)
 else
  glColor3f(1, 1, 1);
 y := py + i * 16 + 8;
 glTextOut(IntToStr(i + 1) + '. ', px, y, courier);
 glTextOut(Score[i].Name, px + 32, y, courier);
 glTextOut(IntToStr(Score[i].Score), px + 196, y, courier);
 end;
end;

procedure Menu_Draw;
var
 i : integer;
 a : single;
begin
glSetOrtho(0, 0, 640, 480);
glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);

if logo_idle < logo_time then
 begin
 // рисуем лого конкурса
 glBlend(1);
 i := logo_time div 3;
 a := sin((logo_idle mod i)/i * pi/2);
 if logo_idle < i then
  glColor4f(1, 1, 1, a)         // fade in
 else
  if logo_idle < i * 2 then
   glColor4f(1, 1, 1, 1)
  else
   glColor4f(1, 1, 1, 1 - a);   // fade out
 Draw_Logo;
 end
else
 begin
 glSetProj(90, 0.5, 512);
 Camera.Pos := Vector(0, 0, 0);
 Map.RenderSkyBox; // используем его в качестве фона :)
 Draw_Spider;
 glSetOrtho(0, 0, 640, 480);
 Draw_Selection(CurItem);
 Draw_Items;
 Draw_Score;
 // копирайт
 glColor3f(1, 0, 0);
 glTextOut('XTropper (c) 2005. Created by XProger', 320 - 144, 456, courier);
 glTextOut('www.XProger.mirgames.ru', 320 - 88, 472, courier);
 end;
end;

end.
