unit uGame;

interface

uses  uStateManager;

var GameScene : rState;

implementation

uses  QuadEngine,
      direct3d9,
      SysUtils,
      uQEHelp,
      uSMath,
      uVar,
      uStarsFon,
      uGameTypes,
      uTitle;

const
  UP_TEXT_ALPHA_TIME    = 2.0;
  DOWN_TEXT_ALPHA_TIME  = 2.0;

var game            : cGame;
    gameStarted     : Boolean = False;
    stUpTextAlpha   : Boolean;
    stDownTextAlpha : Boolean;
    textAlpha       : Double;
    startTime       : Double;

procedure GameInit( param: Pointer );
begin
  currentSpeed := Vec2f( -AppScrH * STARS_SPEED_COF, 0 );

  game := cGame.Create;
  game.Init;

  gameStarted := True;

  stUpTextAlpha   := True;
  stDownTextAlpha := False;
  textAlpha       := 0.0;
  startTime       := Timer.GetWholeTime;

  GameScore := 0;
end;

procedure GameDraw;
begin
  Quad.BeginRender;
    Quad.RenderToTexture( True, 0 );
      Quad.Rectangle( 0, 0, AppScrW, AppScrH,
                      GetARGB( 255, 0, 0, 0 ), GetARGB( 255, 0, 0, 0 ),
                      GetARGB( 255, 0, 52, 104 ), GetARGB( 255, 0, 52, 104 ) );
      Quad.SetBlendMode( qbmSrcAlpha );
      DrawAllStars;
    Quad.RenderToTexture( False, 0 );

    Quad.SetBlendMode( qbmNone );
    Quad.RenderToTexture( True, 1 );
      StarsBloomShader.SetShaderState( UseShaders );
        ScreenBuf_0.Draw( 0, 0, $FFFFFFFF );
      StarsBloomShader.SetShaderState( False );
    Quad.RenderToTexture( False, 1 );

    Quad.RenderToTexture( True, 0 );
      Quad.Clear( 0 );
      game.Draw;
    Quad.RenderToTexture( False, 0 );

    Quad.SetBlendMode( qbmSrcAlpha );
    Quad.RenderToTexture( True, 3 );
      Quad.Clear( $FF000000 );
      BloomShader.SetShaderState( UseShaders );
        ScreenBuf_0.Draw( 0, 0, $FFFFFFFF );
      BloomShader.SetShaderState( False );
    Quad.RenderToTexture( False, 3 );

    Quad.RenderToTexture( True, 4 );
      Quad.Clear( $FF000000 );
      BlurHShader.SetShaderState( UseShaders );
        BloomBuf_1.DrawMap( 0, 0, AppScrW, AppScrH, 0, 0, 1, 1, $FFFFFFFF );
      BlurHShader.SetShaderState( False );
    Quad.RenderToTexture( False, 4 );

    Quad.RenderToTexture( True, 5 );
      Quad.Clear( $FF000000 );
      BlurVShader.SetShaderState( UseShaders );
        BloomBuf_2.DrawMap( 0, 0, AppScrW, AppScrH, 0, 0, 1, 1, $FFFFFFFF );
      BlurVShader.SetShaderState( False );
    Quad.RenderToTexture( False, 5 );

    Quad.RenderToTexture( True, 2 );
      Quad.SetBlendMode( qbmNone );
      ScreenBuf_1.Draw( 0, 0, $FFFFFFFF );
      Quad.SetBlendMode( qbmSrcAlpha );
      ScreenBuf_0.Draw( 0, 0, $FFFFFFFF );
      if UseShaders then begin
        Quad.SetBlendMode( qbmSrcAlphaAdd );
        BloomBuf_3.DrawMap( 0, 0, AppScrW, AppScrH, 0, 0, 1, 1, $FFFFFFFF );
      end;
      if gameStarted then begin
        Quad.SetBlendMode( qbmSrcAlpha );
        Font_3.TextOut( 10, AppScrH - 30, 1.0,
                        PAnsiChar( '+' + IntToStr( game.GetPlayerLife ) ),
                        GetARGB( Round( 255 * textAlpha ), 255, 255, 255 ) );

        Font_3.TextOut( 10, 3, 1.0,
                        PAnsiChar( '$' + IntToStr( game.GetScore ) ),
                        GetARGB( Round( 255 * textAlpha ), 255, 255, 255 ) );

        if game.Boss then begin
          Quad.Rectangle( AppScrW * 0.5 - Font_2.TextWidth( 'BOSS', 1.0 ) * 0.5, 8,
                          AppScrW * 0.5 - Font_2.TextWidth( 'BOSS', 1.0 ) * 0.5 + Font_2.TextWidth( 'BOSS', 1.0 ) * game.GetBossHealth / 100,  80,
                          $66FF2222 );
          Font_2.TextOutCentered( AppScrW * 0.5, 10, 1.0, 'BOSS', $CCFFFFFF );
        end;
      end;
    Quad.RenderToTexture( False, 2 );

    Quad.SetBlendMode( qbmNone );
    OldTVShader.SetShaderState( UseShaders );
      ScreenBuf_2.Draw( 0, 0, $FFFFFFFF );
    OldTVShader.SetShaderState( False );

    //Quad.SetBlendMode( qbmNone );
    //BloomBuf_3.DrawMap( 0, 0, AppScrW, AppScrH, 0, 0, 1, 1, $FFFFFFFF );
  Quad.EndRender;
end;

procedure GameUpdate( dt: Double; currentTime: Double );
begin
  if game.GetGameOverStatus and not stDownTextAlpha then begin
    stDownTextAlpha := True;
    startTime       := currentTime;
  end;

  if stUpTextAlpha then begin
    textAlpha := ( currentTime - startTime ) / UP_TEXT_ALPHA_TIME;
    if currentTime - startTime >= UP_TEXT_ALPHA_TIME then begin
      stUpTextAlpha := False;
      textAlpha     := 1.0;
    end;
  end;

  if stDownTextAlpha then begin
    textAlpha := 1.0 - ( currentTime - startTime ) / DOWN_TEXT_ALPHA_TIME;
    if currentTime - startTime >= DOWN_TEXT_ALPHA_TIME then begin
      stDownTextAlpha := False;
      textAlpha     := 0.0;
      GameScore := game.GetScore;
      StateManager.Pop( True );
      StateManager.Push( @TitleScene );
      StateManager.MakeInit;
      Exit;
    end;
  end;

  UpdateAllStars( dt, False );

  game.Update( dt, currentTime );
end;

procedure GameUpdateFrames( dt: Double; currentTime: Double );
begin
  UpdateAllFrames( dt );

  game.UpdateFrames( dt, currentTime );
end;

procedure GameFree;
begin
  gameStarted := False;
  game.Free;
  game := nil;
end;

procedure GameKeyDown( key: Byte );
begin
  game.OnKeyDown( key );
end;

procedure GameKeyUp( key: Byte );
begin
  game.OnKeyUp( key );
end;

initialization
  GameScene.Name    := 'Game Scene';
  GameScene.onInit  := @GameInit;
  GameScene.onDraw  := @GameDraw;
  SetLength( GameScene.onTimer, 2 );
  GameScene.onTimer[ 0 ]  := @GameUpdate;
  GameScene.onTimer[ 1 ]  := @GameUpdateFrames;
  GameScene.onKill        := @GameFree;
  GameScene.onKeyDown     := @GameKeyDown;
  GameScene.onUpdate      := nil;
  GameScene.onActivate    := nil;
  GameScene.onKeyUp       := @GameKeyUp;
  GameScene.onKeyChar     := nil;
  GameScene.onMouseDown   := nil;
  GameScene.onMouseUp     := nil;
  GameScene.onMouseMove   := nil;
end.
