unit eXgine;

interface

uses
  Windows, OpenGL;

const
  eXgine_DLL = 'eXgine.dll';

// Engine
const
  PROC_UPDATE  = 0;
  PROC_RENDER  = 1;
  PROC_MESSAGE = 2;
  PROC_ACTIVE  = 3;

// Input
const
// мышь
  M_WHEEL  = 256;
  M_BTN_L  = 257;
  M_BTN_R  = 258;
  M_BTN_M  = 259;
// джойстик
  J_BTN_L  = 260;
  J_BTN_R  = 261;
  J_BTN_U  = 262;
  J_BTN_D  = 263;
  J_BTN_1  = 264;
  J_BTN_2  = 265;
  J_BTN_3  = 266;
  J_BTN_4  = 267;
  J_BTN_5  = 268;
  J_BTN_6  = 269;
  J_BTN_7  = 270;
  J_BTN_8  = 271;
  J_BTN_9  = 272;
  J_BTN_10 = 273;
  J_BTN_11 = 274;
  J_BTN_12 = 275;
  J_BTN_13 = 276;
  J_BTN_14 = 277;
  J_BTN_15 = 278;
  J_BTN_16 = 279;

// Log
const
  MSG_NONE    = $00000000;
  MSG_ERROR   = $00000010;
  MSG_INFO    = $00000040;
  MSG_WARNING = $00000030;

// Math
const
  deg2rad = pi / 180;
  rad2deg = 180 / pi;

type
// IOpenGL
  TFont    = Cardinal;
  
// IShader
  TShader    = Integer;
  TShAttrib  = Integer;
  TShUniform = Integer;

// ITexture
  TTexture   = Cardinal;
  TTexMode   = (TM_COLOR = 1, TM_DEPTH = 2);
  TBlendType = (BT_NONE, BT_SUB, BT_ADD, BT_MULT);

// ISound
  TSound     = Integer;
  TChannel   = Integer;

// IEngine
  TProcRender  = procedure;
  TProcUpdate  = procedure;
  TProcMessage = procedure (Msg: Cardinal; wP, lP: Integer);
  TProcActive  = procedure (Active: Boolean);

// IInput
  TPoint = record
    X, Y : Integer;
  end;
  
// IVec
  TVector = record
    X, Y, Z : Single;
  end;

  ILog = interface
    function  Create(FileName: PChar): Boolean; 
    procedure Print(Text: PChar); 
    function  Msg(Caption, Text: PChar; ID: Cardinal): Integer; 
    procedure TimeStamp(Active: Boolean = True); 
    procedure Free; 
  end;

  IWindow = interface
    function  Create(Caption: PChar; OnTop: Boolean = True): Boolean;
    function  Handle: Cardinal; 
    procedure Caption(Text: PChar); 
    function  Width: Integer; 
    function  Height: Integer; 
    function  Mode(FullScreen: Boolean; W, H, BPP, Freq: Integer): Boolean; 
    procedure Show(Minimized: Boolean); 
    function  Active: Boolean; 
  end;

  IInput = interface
    procedure Reset; 
    function  KDown(key: Integer): Boolean; 
    function  MDown(btn: Integer): Boolean; 
    function  JDown(btn: Integer): Boolean; 
    function  KLast: Integer; 
    function  MLast: Integer; 
    function  JLast: Integer; 
    function  MDelta: TPoint; 
    function  WDelta: Integer; 
    procedure MCapture(Active: Boolean); 
  end;

  IShader = interface
    function Create: TShader; 
    procedure Free(Shader: TShader); 
    function AddVP(Shader: TShader; FileName: PChar): Boolean; 
    function AddFP(Shader: TShader; FileName: PChar): Boolean; 
    function Link(Shader: TShader): Boolean; 
    function GetAttrib(Shader: TShader; Name: PChar): TShAttrib; 
    function GetUniform(Shader: TShader; Name: PChar): TShUniform; 
    procedure Attrib(a: TShAttrib; x: Single); overload; 
    procedure Attrib(a: TShAttrib; x, y: Single); overload; 
    procedure Attrib(a: TShAttrib; x, y, z: Single); overload; 
    procedure Uniform(u: TShUniform; x: Single); overload; 
    procedure Uniform(u: TShUniform; x, y: Single); overload; 
    procedure Uniform(u: TShUniform; x, y, z: Single); overload; 
    procedure Uniform(u: TShUniform; i: Integer); overload; 
    procedure Enable(Shader: TShader); 
    procedure Disable; 
  end;

  IOpenGL = interface
    function  FPS: Integer; 
    procedure VSync(Active: Boolean); 
    procedure Clear(Color: Boolean = False; Depth: Boolean = False; Stencil: Boolean = False); 
    procedure Set2D(x, y, w, h: Single); 
    procedure Set3D(FOV, zNear, zFar: Single); 
    procedure LightPos(ID: Integer; X, Y, Z: Single); 
    procedure LightColor(ID: Integer; R, G, B: Single); 
    function  FontCreate(Name: PChar; W, H: Integer): TFont; 
    procedure FontFree(Font: TFont); 
    procedure TextOut(Font: TFont; X, Y: Integer; Text: PChar); 
    procedure Blend(BType: TBlendType);
    function  ScreenShot(FileName: PChar): Boolean;
  end;

  ITexture = interface
    function  Create(Name: PChar; c, f, W, H: Integer; Data: Pointer; Clamp: Boolean = False; MipMap: Boolean = True; Group: Integer = 0): TTexture; 
    function  Load(FileName: PChar; Clamp: Boolean = False; MipMap: Boolean = True; Group: Integer = 0): TTexture; 
    procedure Free(ID: TTexture); 
    procedure Enable(ID: TTexture; Channel: Integer = 0); 
    procedure Disable(Channel: Integer = 0); 
    procedure Update_Begin(Group: Integer); 
    procedure Update_End(Group: Integer); 
    function  Render_Init(TexSize: Integer): Boolean; 
    procedure Render_Begin(ID: TTexture; Mode: TTexMode = TM_COLOR); 
    procedure Render_End; 
  end;

  ISound = interface
    function  Create(Name: PChar; Freq, Bpp, Channels, Size: Integer; Data: Pointer): TSound; 
    function  Load(FileName: PChar; Group: Integer = 0): TSound; 
    function  Free(ID: TSound): Boolean; 
    function  Play(ID: TSound; X, Y, Z: Single; Loop: Boolean = False): TChannel; 
    procedure Stop(ID: TChannel); 
    procedure Update_Begin(Group: Integer); 
    procedure Update_End(Group: Integer); 
    procedure Volume(Value: Integer); 
    procedure Freq(Value: Integer); 
    procedure Channel_Pos(ID: TChannel; X, Y, Z: Single); 
    procedure Pos(X, Y, Z: Single); 
    procedure Dir(dX, dY, dZ, uX, uY, uZ: Single); 
    procedure Factor_Pan(Value: Single = 0.5); 
    procedure Factor_Rolloff(Value: Single = 0.005); 
    procedure PlayFile(FileName: PChar; Loop: Boolean = False); 
    procedure StopFile; 
  end;

  IVector = interface
    function Create(X, Y, Z: Single): TVector; 
    function Add(v1, v2: TVector): TVector; 
    function Sub(v1, v2: TVector): TVector; 
    function Mult(v: TVector; x: Single): TVector; 
    function Length(v: TVector): Single; 
    function LengthQ(v: TVector): Single; 
    function Normalize(v: TVector): TVector; 
    function Dot(v1, v2: TVector): Single; 
    function Cross(v1, v2: TVector): TVector; 
    function Angle(v1, v2: TVector): Single; 
  end;

  IEngine = interface
    function  log: ILog; 
    function  wnd: IWindow; 
    function  inp: IInput; 
    function  ogl: IOpenGL; 
    function  tex: ITexture; 
    function  vfp: IShader; 
    function  snd: ISound; 
    function  vec: IVector; 
    function  Version: PChar; 
    procedure Quit; 
    procedure SetProc(ID: Integer; Proc: Pointer); 
    procedure ActiveUpdate(OnlyActive: Boolean); 
    procedure ResetTimer; 
    procedure MainLoop(UPS: Integer);
  end;

// Самое необходимое из новых (> 1.3) версий OpenGL
const
  GL_CLAMP_TO_EDGE = $812F;
  GL_RGB8          = $8051;
  GL_RGBA8         = $8058;
  GL_BGR           = $80E0;
  GL_BGRA          = $80E1;
  GL_TEXTURE0_ARB  = $84C0;

var
  eX  : IEngine;
  log : ILog;
  inp : IInput;
  ogl : IOpenGL;
  wnd : IWindow;
  snd : ISound;
  tex : ITexture;
  vfp : IShader;
  vec : IVector;

  procedure InitEngine(out Engine: IEngine; LogFile: PChar = nil); stdcall; external eXgine_DLL;

  function IntToStr(Value: Integer): string;
  function StrToInt(const Str: string; DefValue: Integer = 0): Integer;

implementation

function IntToStr(Value: Integer): string;
begin
  Str(Value, Result);
end;

function StrToInt(const Str: string; DefValue: Integer): Integer;
var
  er : Integer;
begin
  Val(Str, Result, er);
  if er = 0 then
    Result := DefValue;
end;

initialization
  InitEngine(eX, 'log.txt');
  log := eX.log;
  wnd := eX.wnd;
  inp := eX.inp;
  ogl := eX.ogl;
  tex := eX.tex;
  vfp := eX.vfp;
  snd := eX.snd;
  vec := eX.vec;

end.
