/*
     AstroPong - A 3D Pong Game
     Copyright (C) 2002  Oliver Baker

     This program is free software; you can 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 program 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 program; if not, write to the Free Software
     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA

     For further information visit http://plib.sourceforge.net

     $Id: astropong.psl 1699 2002-09-22 15:22:21Z sjbaker $
*/


#define ARENA_SIZE 8.0  /* meters */
#define ARENA_LENGTH 10.0  /* meters */
#define BALL_SIZE  2.5  /* meters */

#define BOUNCE (ARENA_SIZE/2.0 - BALL_SIZE/2.0)
#define BOUNCEY (ARENA_LENGTH/2.0 - BALL_SIZE/2.0)

#define BAT_SIZE  (1.0 + BALL_SIZE/2.0) /* From the center to the sides */

int arena          ;
int shadow         ;
int difficulty     ;
int scoreBoardR    ;
int scoreBoardB    ;
int ball           ;
int bPaddle        ;
int rPaddle        ;
int camera         ;
int scoreR         ;
int scoreB         ;

float Blue_batspeed = .34;
float scoreSpinR         ;
float scoreSpinB         ;
float ballSpinH          ;
float ballSpinSH         ;
float ballSpinP          ;
float ballSpinSP         ;
float ballSpinR          ;
float ballSpinSR         ;
float ballX              ;
float ballY              ;
float ballZ              ;
float ballSX             ;
float ballSY             ;
float ballSZ             ;
float bpaddleX           ;
float bpaddleZ           ;
float rpaddleX           ;
float rpaddleZ           ;
float userX              ;
float userZ              ;
int  frameno = 0         ;

int main()
{
  camera      = 0     ;
  arena       = siLoad ( "arena2.ac")     ;
  ball        = siLoad ( "ball3.ac")      ;
  bPaddle     = siLoad ( "bluepaddle2.ac");
  rPaddle     = siLoad ( "redpaddle2.ac") ;
  scoreBoardR = siLoad ( "Scoreboard.ac") ;
  scoreBoardB = siLoad ( "Scoreboard.ac") ;
  shadow      = siLoad ( "shadow2.ac")    ;

  scoreSpinR = 0     ;
  scoreSpinB = 0     ;
  ballSX     = 0.166 ;
  ballSY     = 0.155 ;
  ballSZ     = 0.016 ;
  ballSpinSH = 4     ;
  ballSpinSP = 4     ;
  ballSpinSR = 4     ;

  difficulty = 1 ;

  if ( difficulty == 1 ) { Blue_batspeed = .275 ; }
  else { Blue_batspeed = .34 ; }

  while ( 1 )
  { 
    frameno = frameno + 1 ;

    /* Read the joystick */

    userX = siJoystickLR();
    userZ = siJoystickUD();

    /* Move the ball */

    ballX     += ballSX       ;
    ballY     += ballSY       ;
    ballZ     += ballSZ       ;
    ballSpinH += ballSpinSH   ;
    ballSpinP += ballSpinSP   ;
    ballSpinR += ballSpinSR   ;

    /* Bounce off the sides? */

    if ( ballX > BOUNCE || ballX < -BOUNCE )
    {
      ballSX = -ballSX ;
    }

    /* Bounce off the top and bottom? */

    if ( ballZ >  BOUNCE || ballZ < -BOUNCE )
    {
      ballSZ = -ballSZ ;
    }



    /* What happens at the ends? */

    if ( ballY > BOUNCEY )  /* Passed the blue paddle? */
    {
     /* Is the blue bat there? */

     if (ballX > bpaddleX - BAT_SIZE && ballX < bpaddleX + BAT_SIZE && 
	 ballZ > bpaddleZ - BAT_SIZE && ballZ < bpaddleZ + BAT_SIZE )
     {
       float hitX = ballX - bpaddleX ;
       float hitZ = ballZ - bpaddleZ ;

       if ( ballSX > 0 )
	 ballSX = fabs ( hitX / 2.0 ) ;
       else
	 ballSX = -fabs ( hitX / 2.0 ) ;

       if ( ballSZ > 0 )
	 ballSZ = fabs ( hitZ / 2.0 ) ;
       else
	 ballSZ = -fabs ( hitZ / 2.0 ) ;

       ballSY = -ballSY ;
     }
     else
     { 
       scoreR++ ;

       print ("The score is Red:", scoreR, " Blue:", scoreB, "\n" ) ; 

       ballSX = 0.1 ;
       ballSY = 0.1 ;
       ballSZ = 0.1;
       ballSY = -ballSY ;
       ballX = 0.0 ;
       ballY = 0.0 ;
       ballZ = 0.0;
       for ( int i = 0 ; i < 60 ; i++ ) pause ;
     }
    }

   
    if ( ballY < -BOUNCEY )  /* Passed the red paddle? */
    {
     /* Was the red bat there? */

     if (ballX > rpaddleX - BAT_SIZE && ballX < rpaddleX + BAT_SIZE &&
	 ballZ > rpaddleZ - BAT_SIZE && ballZ < rpaddleZ + BAT_SIZE )
     {
       float hitX = ballX - rpaddleX ;
       float hitZ = ballZ - rpaddleZ ;

       if ( ballSX > 0 )
	 ballSX = fabs ( hitX / 2.0 ) ;
       else
	 ballSX = -fabs ( hitX / 2.0 ) ;

       if ( ballSZ > 0 )
	 ballSZ = fabs ( hitZ / 2.0 ) ;
       else
	 ballSZ = -fabs ( hitZ / 2.0 ) ;

       ballSY = -ballSY ;
     }
     else
     { 
       scoreB++ ;
       print ("The score is Red:", scoreR, " Blue:", scoreB, "\n" ) ; 
       ballSX = .1 ;
       ballSY = .1 ;
       ballSZ = .1;
       ballSY = -ballSY ;
       ballX = 0.0 ;
       ballY = 0.0 ;
       ballZ = 0.0;
       for ( int i = 0 ; i < 60 ; i++ ) pause ;
     }
    }

    /* Update the scoreboard */

    scoreSpinR = scoreR * -36.0 ;
    scoreSpinB = scoreB * -36.0 ;
    
    /* How should the computer move the paddle? */

    if ( ballZ > bpaddleZ ) { bpaddleZ += Blue_batspeed ; }
    else { bpaddleZ -= Blue_batspeed ; }

    if ( ballX > bpaddleX ) { bpaddleX += Blue_batspeed ; }
    else { bpaddleX -= Blue_batspeed ; }

    /* How did the player move the paddle? */

    rpaddleX += userX * -.5;
    rpaddleZ += userZ *  .5;

    /* Did the paddle move off the edge of the screen? */

    if ( rpaddleX >  BOUNCE  ) rpaddleX =  BOUNCE  ;
    if ( rpaddleX < -BOUNCE  ) rpaddleX = -BOUNCE  ;
    if ( rpaddleZ >  BOUNCE  ) rpaddleZ =  BOUNCE  ;
    if ( rpaddleZ < -BOUNCE  ) rpaddleZ = -BOUNCE  ;

    /* Tell SIMON where to position the paddle, ball and camera */
    
    /*           MODEL         X, Y, Z,               H, P, R    */
    siPosition ( scoreBoardR,  1, 0, 0,               0, scoreSpinR, 0 ) ;
    siPosition ( scoreBoardB, -1, 0, 0,               0, scoreSpinB, 0 ) ;
    siPosition ( bPaddle    , bpaddleX,  5, bpaddleZ, 0,     0     , 0 ) ;
    siPosition ( rPaddle    , rpaddleX, -5, rpaddleZ, 0,     0     , 0 ) ;
    siPosition ( ball       , ballX, ballY, ballZ,
                              ballSpinH,ballSpinP,ballSpinR);
    siPosition ( arena      , 0, 0, 0,                0,     0     , 0 ) ;
    siPosition ( shadow     , ballX, ballY, -4,       0,     0     , 0 ) ;
    siPosition ( camera     ,  0, -10, 0,             0,     0     , 0 ) ;

    pause ;
  }
}


