///////////////////////////////////////////////////////////////////////
// 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 ENGINE_SCREEN;

{$I DEFINES.pas}

interface
uses
  Windows,
  OpenGL,

	ENGINE_VAR,
  ENGINE_CONST,
  ENGINE_UTILS,

  MATH_FAST;

type
  TOptions = record
    app_FullScreen : Boolean;
    wnd_X          : Integer;
    wnd_Y          : Integer;
    wnd_Width      : Integer;
    wnd_Height     : Integer;
    scr_Width      : Integer;
    scr_Height     : Integer;
    scr_BPP        : Integer;
    scr_Refresh    : Byte;
    scr_VSync      : Boolean;
    Reserved       : Boolean;
end;
POptions = ^TOptions;

procedure OE_SetScreenOptions(
                               Width, Height,
                               BPP, Refresh  : Integer;
                               FullScreen,
                               WaitVSync     : Boolean
                             ); stdcall;
procedure OE_ChangeScreenOptions(
                                  Width, Height,
                                  BPP, Refresh  : Integer;
                                  FullScreen,
                                  WaitVSync     : Boolean
                             ); stdcall;
function OE_GetOptions : POptions; stdcall;

procedure OE_SetAdvancedOptions(
                                 UseLog      : Boolean;   
                                 AppCanClose : Boolean;
                                 HaltOnExit  : Boolean
                               ); stdcall;

procedure OE_SetVSync( VSync : Boolean ); stdcall;

function OE_GetFPS : Integer; stdcall;

procedure OE_SetResolutionDependence( NormalResX, NormalResY : Integer ); stdcall;

function Scr_SetSettings : Boolean;
function GetDisplayColors : Integer;
function GetDisplayRefresh : Integer;

//----------------------------------------------------------------------------//
                                 IMPLEMENTATION
//----------------------------------------------------------------------------//
uses
  ENGINE_WINDOW, ENGINE_LOG, UTILS;

var
  TempOptions : TOptions;

function GetDisplayColors;
  var
    tHDC: hdc;
Begin
tHDC := GetDC(0);
Result := GetDeviceCaps( tHDC, BITSPIXEL ) * GetDeviceCaps( tHDC, PLANES );
ReleaseDC( 0, tHDC );
End;

function GetDisplayRefresh;
  var
    tHDC: hdc;
Begin
tHDC := GetDC(0);
Result := GetDeviceCaps( tHDC, VREFRESH );
ReleaseDC( 0, tHDC );
End;

procedure OE_SetScreenOptions;
Begin

app_FullScreen := FullScreen;
scr_VSync      := WaitVSync;

scr_BPP     := BPP;
scr_Refresh := Refresh;
if FullScreen Then
  begin
    scr_Width  := Width;
    scr_Height := Height;
    wnd_Width  := Width;
    wnd_Height := Height;
  end else
    begin
      scr_Width  := scr_OLDSettings.dmPelsWidth;
      scr_Height := scr_OLDSettings.dmPelsHeight;
      scr_BPP    := scr_OLDSettings.dmBitsPerPel;      
      wnd_Width  := Width;
      wnd_Height := Height;
    end;

Scr_SetSettings;

End;

procedure OE_ChangeScreenOptions;
Begin
OE_SetScreenOptions( Width, Height, BPP, Refresh, FullScreen, WaitVSync );
Wnd_SetStyle;
OE_ResizeWindow( Width, Height );

OE_SetScreenOptions( Width, Height, BPP, Refresh, FullScreen, WaitVSync );
Wnd_SetStyle;
OE_ResizeWindow( Width, Height );
End;

function OE_GetOptions;
Begin

TempOptions.app_FullScreen := app_FullScreen;
TempOptions.wnd_X          := wnd_X;
TempOptions.wnd_Y          := wnd_Y;
TempOptions.wnd_Width      := wnd_Width;
TempOptions.wnd_Height     := wnd_Height;
TempOptions.scr_Width      := scr_Width;
TempOptions.scr_Height     := scr_Height;
TempOptions.scr_BPP        := scr_BPP;
TempOptions.scr_Refresh    := scr_Refresh;
TempOptions.scr_VSync      := scr_VSync;

Result := @TempOptions;

End;

procedure OE_SetAdvancedOptions;
Begin

app_Log        := UseLog;
app_CanClose   := AppCanClose;
app_HaltOnExit := HaltOnExit;

End;

procedure OE_SetVSync( VSync : Boolean );
Begin
scr_Vsync := VSync;
End;

function OE_GetFPS;
Begin

Result := app_FPS;

End;

function Scr_SetSettings;
  var
    i : Integer;
    r : Integer; // Максимальная частота экрана
Begin

Result := FALSE;

if app_FullScreen Then
  begin
    i := 0;
    r := 0;
    while EnumDisplaySettings( nil, i, scr_NOWSettings ) <> FALSE do
      with scr_NOWSettings do
        begin
          dmSize   := SizeOf( DEVMODE );
          dmFields := DM_PELSWIDTH or DM_PELSHEIGHT or DM_BITSPERPEL or DM_DISPLAYFREQUENCY;
          if ( dmPelsWidth  = scr_Width  ) and
             ( dmPelsHeight = scr_Height ) and
             ( dmBitsPerPel = scr_BPP    ) and
             ( dmDisplayFrequency > r    ) and
             ( dmDisplayFrequency <= scr_OLDSettings.dmDisplayFrequency ) Then
            begin
              if ( ChangeDisplaySettings( scr_NOWSettings, CDS_TEST or CDS_FULLSCREEN ) = DISP_CHANGE_SUCCESSFUL ) Then
                r := dmDisplayFrequency
              else
                break;
            end;
          INC( i );
        end;

    with scr_NOWSettings do
      begin
        dmSize := SizeOf( DEVMODE );
        if scr_Refresh = 0 Then scr_Refresh := r;
        if scr_Refresh = 1 Then scr_Refresh := 0;

        dmPelsWidth        := scr_Width;
        dmPelsHeight       := scr_Height;
        dmBitsPerPel       := scr_BPP;
        dmDisplayFrequency := scr_Refresh;
        dmFields           := DM_PELSWIDTH or DM_PELSHEIGHT or DM_BITSPERPEL or DM_DISPLAYFREQUENCY;
      end;
      
    if ChangeDisplaySettings( scr_NOWSettings, CDS_TEST or CDS_FULLSCREEN ) <> DISP_CHANGE_SUCCESSFUL Then
      begin
        E_Warning( ERR_CANT_FULLSCREEN );
        app_FullScreen := FALSE;
      end else
        ChangeDisplaySettings( scr_NOWSettings, CDS_FULLSCREEN )
  end else
    ChangeDisplaySettings( scr_OLDSettings, CDS_FULLSCREEN );
Result := TRUE;
End;

procedure OE_SetResolutionDependence;
Begin
scr_ScaleX := ogl_Width  / NormalResX;
scr_ScaleY := ogl_Height / NormalResY;
CropW      := round( ogl_Width / scr_ScaleX );
CropH      := round( ogl_Height / scr_ScaleY );
End;

end.
