unit fwPandoraSDLEngine;

{$IFDEF FPC}
  {$MODE DELPHI}
{$ENDIF}

interface

uses SysUtils,

     SDL,
     SDL_Mixer,
     SDL_Image,
     SDL_TTF,

     fwLogging,
     fwTypes,
     fwCustomEngine,
	 fwCustomSDLEngine;

const
  cKeyLen          = 512;
  cStartVolume     = 25;
  cColorBits       = 16;
  cFXFactor        = 1.5;
  cSoundBufferSize = 2048;

type
  // -----------------------------------------------------------------------
  TfwPandoraSDLEngine= class(TfwCustomSDLEngine)
  protected
    function  CreateInputStates : TfwCEInputStates; override;
  public
    function  Init(aWidth, aHeight, aBPP : Integer) : TfwCESurface; override;
    procedure UpdateInput(); override;
    function  ExitKeyPressed() : Boolean; override;
  end;

implementation

// TfwSDLEngine ----------------------------------------------------------
procedure QuitSDLProc;
begin
  SDL_Quit();
end;

procedure HandleMusicDoneEvent(); stdcall;
begin
  HAL().MusicDone();
end;

function TfwPandoraSDLEngine.CreateInputStates : TfwCEInputStates;
begin
  Result := TfwSDLInputStates.Create;
end;

function TfwPandoraSDLEngine.Init(aWidth, aHeight, aBPP : Integer) : TfwCESurface;
begin
  Result := nil;

  if (SDL_Init (SDL_INIT_VIDEO or SDL_INIT_AUDIO) < 0) then begin
    fwLOG('sdl not initialized');
    Exit;
  end;

  // Automatische Deinitialisierung
  AddExitProc(QuitSDLProc);

  // Erzeuge die Schnittstelle zu den Eingabegeraeten
  fInputStates := CreateInputStates();

  // Initialize SDL_mixer
  if (Mix_OpenAudio(MIX_DEFAULT_FREQUENCY, AUDIO_S16, MIX_DEFAULT_CHANNELS, cSoundBufferSize) = -1)
  then begin
    fwLOG('audio not initialized');
  end else begin
  	// Standardeinstellung, damit einem nicht die Ohren wegfliegen
  	Mix_VolumeMusic(cStartVolume);
  	Mix_Volume(-1, Trunc(cStartVolume * cFXFactor));

  	// Wann ist die Hintergrundmusik zu ende?
  	Mix_HookMusicFinished(@HandleMusicDoneEvent);
  end;

  fVideoInfo := SDL_GetVideoInfo();
  if not Assigned(fVideoInfo) then begin
    fwLOG('SDL_GetVideoInfo failed');
  end;

  fVideoFlags := SDL_FULLSCREEN or SDL_HWSURFACE or SDL_HWPALETTE or SDL_DOUBLEBUF or SDL_HWACCEL;

  // Set 320x240 16-bits video mode
  fScreen := TfwSDLSurface.Create(SDL_SetVideoMode(aWidth, aHeight, cColorBits, fVideoFlags));
  if (not fScreen.HasSurface) then begin
    FreeAndNil(fScreen);
    fwLOG('SDL_SetVideoMode failed');
    Exit;
  end;

  SDL_SetClipRect(fScreen.Surface, nil);

  // disable mouse cursor, must be after calling SDL_SetVideoMode()
  if fShowMouse then begin
    fwLOG('show mouse cursor');
    SDL_ShowCursor(SDL_ENABLE);
  end else begin
    fwLOG('hide mouse cursor');
    SDL_ShowCursor(SDL_DISABLE);
  end;

  fwLOG('engine init done');

  Result := fScreen;
end;

procedure TfwPandoraSDLEngine.UpdateInput();
begin
  inherited UpdateInput();
  
  if Assigned(fInputStates) then begin
    // Pruefe eine bestimmte Taste
    if (fInputStates.KeyPressed(SDLK_E)) then begin
      fExitKeyPressed := True;
    end;
  end;  
end;

function TfwPandoraSDLEngine.ExitKeyPressed() : Boolean;
begin
  if fInputStates.KeyPressed(SDLK_ESCAPE) then begin
    fExitKeyPressed := True;
  end;

  Result := fExitKeyPressed;
end;

end.
