///////////////////////////////////////////////////////////////////////
// Copyright (C) Andru 2007                                          //
// mail: dr.andru@gmail.com                                          //
// site: http://andru.2x4.ru                                         //
//                                                                   //
// OMEGA Engine is free software.                                    //
//                                                                   //
// You may redistribute it and/or modify it under the terms of the   //
// GNU General Public License, as published by the Free Software     //
// Foundation; either version 2 of the License, or (at your option)  //
// any later version.                                                //
//                                                                   //
// this module is distributed in the hope that it will be useful,    //
// but WITHOUT ANY WARRANTY; without even the implied warranty of    //
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.              //
// See the GNU General Public License for more details.              //
//                                                                   //
// You should have received a copy of the GNU General Public License //
// along with this module.  If not, write to:                        //
// 	The Free Software Foundation, Inc.,                              //
// 	51 Franklin Street, Fifth Floor                                  //
// 	Boston, MA  02110-1301, USA.                                     //
///////////////////////////////////////////////////////////////////////
unit UTILS;

{$I DEFINES.pas}

interface
uses
  Windows,
  OpenGL,
  minClasses,
  minFile,

  ENGINE_VAR,
  ENGINE_UTILS,   

  TEXTURE_MANAGER,
  TEXTURE_LOADER,
  TEXTURE_TGA,

  MATH_FAST
  ;

function U_IntToStr( Num : Integer ) : PChar; stdcall;
function U_StrToInt( Str : PChar ) : Integer; stdcall;
function U_FloatToStr( Num : Single ) : PChar; stdcall;

function U_GetCPUName : PChar; stdcall;
function U_GetTotalRAM : Integer; stdcall;
function U_Is3DAccelerator : Boolean; stdcall;
function U_GetMaxAnisotropy : Integer; stdcall;
function U_GetMaxTexSize : Integer; stdcall;

procedure U_SnapShot( Path, FileName : PChar ); stdcall;

function U_GetTime : Double; stdcall;

//----------------------------------------------------------------------------//
                                 IMPLEMENTATION
//----------------------------------------------------------------------------//
var
  Frequency : int64;
  Freq      : Single;
  t_start   : Double;

function U_IntToStr;
begin
Str( Num, TempString );
Result := PChar( TempString );
end;

function U_FloatToStr;
begin
Str( Num : 3 : 7, TempString );
Result := PChar( TempString );
end;

function U_StrToInt;
  var
    E : Integer;
begin
  Val( Str, Result, E );
  if E <> 0 Then
    E_Warning(
               {$IFDEF RUS} 'Невозможно конвертировать "' + Str + '" в тип Integer!' {$ELSE}
                            'Unable to convert "' + Str + '" into Integer!'          {$ENDIF}
             );
end;

function U_GetCPUName;
  var
    tmp : array[ 0..95 ] of Char;
Begin
  asm
    mov eax, $80000002
    db $0F, $A2
    mov DWORD ptr[ tmp      ], eax
    mov DWORD ptr[ tmp + 4  ], ebx
    mov DWORD ptr[ tmp + 8  ], ecx
    mov DWORD ptr[ tmp + 12 ], edx

    mov eax, $80000003
    db $0F, $A2
    mov DWORD ptr[ tmp + 16 ], eax
    mov DWORD ptr[ tmp + 20 ], ebx
    mov DWORD ptr[ tmp + 24 ], ecx
    mov DWORD ptr[ tmp + 28 ], edx

    mov eax, $80000004
    db $0F, $A2
    mov DWORD ptr[ tmp + 32 ], eax
    mov DWORD ptr[ tmp + 36 ], ebx
    mov DWORD ptr[ tmp + 40 ], ecx
    mov DWORD ptr[ tmp + 44 ], edx
  end;
  Result := tmp;
end;

function U_GetTotalRAM;
  var
    Status : TMemoryStatus;
Begin

Status.dwLength := SizeOf( TMemoryStatus );
GlobalMemoryStatus( Status );
Result := Status.dwTotalPhys shr 20 + 1;

End;

function U_Is3DAccelerator;
Begin

Result := ogl_3DAccelerator;

End;

function U_GetMaxAnisotropy;
Begin

Result := ogl_MaxAnisotropy;

End;

function U_GetMaxTexSize;
Begin

Result := ogl_MaxTextureSize;

End;

procedure U_SnapShot;
var
  F      : TMemoryStream;
  TGA    : TTGAHeader;
  pData  : Pointer;
  FFile  : String;
  FPath  : String;
  ST     : _SYSTEMTIME;
  Mil0   : String;
Begin

FPath := Path;
if not DirectoryExists( Path ) Then FPath := '';
if FPath <> '' Then FPath := Path + '\';
GetSystemTime( ST );
if ST.wMilliseconds > 0  Then Mil0 := '00';
if ST.wMilliseconds > 10 Then Mil0 := '0';
if ST.wMilliseconds > 99 Then Mil0 := '';

FFile :=
          FPath                          +
          String( FileName )             +
          '_'                            +
          U_IntToStr( ST.wYear )         +
          '-'                            +
          U_IntToStr( ST.wMonth )        +
          '-'                            +
          U_IntToStr( ST.wDay )          +
          '-'                            +
          U_IntToStr( ST.wHour )         +
          '-'                            +
          U_IntToStr( ST.wMinute )       +
          '-'                            +
          U_IntToStr( ST.wSecond )       +
          '-'                            +
          Mil0                           +
          U_IntToStr( ST.wMilliseconds ) +
          '.tga';

Mem_Get( pData, wnd_Width * wnd_Height * 3 );
asm call app_PDraw end;
glReadPixels( 0, 0, wnd_Width, wnd_Height, GL_BGR, GL_UNSIGNED_BYTE, pData );

TGA.IDLength            := 0;
TGA.CPalType            := 0;
TGA.ImageType           := 2;
TGA.CPalSpec.FirstEntry := 0;
TGA.CPalSpec.Length     := 0;
TGA.CPalSpec.EntrySize  := 0;
TGA.ImgSpec.X           := 0;
TGA.ImgSpec.Y           := 0;
TGA.ImgSpec.Width       := wnd_Width;
TGA.ImgSpec.Height      := wnd_Height;
TGA.ImgSpec.Depth       := 24;
TGA.ImgSpec.Desc        := 0;

F := TMemoryStream.Create;
F.Write( TGA, SizeOf( TTGAHeader ) );
F.Write( pData^, wnd_Width * wnd_Height * 3 );
F.SaveToFile( FFile );
F.Free;

End;

function U_GetTime;
  var
    T : int64;
begin
QueryPerformanceCounter( T );
Result := 1000 * T * Freq - t_start;
end;

initialization
QueryPerformanceFrequency( Frequency );
Freq := 1 / Frequency;
t_start := U_GetTime;

end.
