/*
    Raydium - CQFD Corp.
    http://raydium.org/
    Released under both BSD license and Lesser GPL library license.
    See "license.txt" file.
*/

// TODO:
// - Blood (red particules)
// - Update this game to use all last Raydium ODE integrations

/*
    Xfennec - CQFD Corp.
    NewSkyDiver (Atari "Sky Diver" clone)
    CQFD Corp.
*/

char *version="version 0.96";

//#define ODE_MANUAL_CALLBACK

#include "raydium/index.c"


#define DEFAULT_ZOOM            20
#define DEFAULT_CAMX            0
#define DEFAULT_CAMY            -100
#define DEFAULT_CAMZ            5
#define PLANE_PLACE             30
#define PARACHUTE_PORTANCE      0.1
#define MAX_TOUCH_TIME          5


GLfloat sun[]={1.0,0.9,0.5,1.0};
GLfloat amb[]={1.0,0.0,0.0,1.0};
GLfloat tmp2[]={1.0,1.0,1.0,1.0};
GLfloat zero[]={0.0,0.0,0.0,0.0};

GLfloat camx=DEFAULT_CAMX;
GLfloat camy=DEFAULT_CAMY;
GLfloat camz=DEFAULT_CAMZ;
GLfloat camzoom=DEFAULT_ZOOM;
dReal wind;
dReal move=0;
char para_open;
char touching;
int touching_steps;
float fly_time;
float dist_from_center;
int breaked_bones;
int best_score=0;
int plane_touched;
char cam[RAYDIUM_MAX_NAME_LEN];
GLfloat last_frame_step;
char tips[6][128]={"^dPress ^fSPACE^d to jump, ^fBACKSPACE^d to restart a game, ^fF1^d for dynamic view.","^cPress ^fSPACE^c to open parachute !","^aUse ^fLEFT^a and ^fRIGHT^a arrows (or joystick/joypad) to move ...","^eUse ^fBACKSPACE^e to try again !","^dBye ! ...",""};
char player_name[RAYDIUM_MAX_NAME_LEN];
int tip=0;
dReal score_timer;
char fp_view=-1;

#define GAME_PART_PLANE    0
#define GAME_PART_JUMP     1
#define GAME_PART_PARA     2
#define GAME_PART_TOUCHED  3
#define GAME_PART_SCORE    4
#define GAME_PART_QUIT     5
int game_part=-1;

int S_plane;
int S_hurt[4];
int S_plane_fall;

// type_* are used as address tag
char type_lander;
char type_para;
char type_plane;

int music_change(char *newfile)
{
raydium_register_variable(newfile,RAYDIUM_REGISTER_STR,"raydium_ogg_file");
raydium_php_exec("playlist.php");
raydium_register_variable_unregister_last();
return strlen(newfile)!=0;
}


int get_score(char growing_fx)
{
// - Scoring (breaked bones, flying time, lander-touching time, wind)
GLfloat score,tmp,w;

w=wind;

if(breaked_bones) return 0;
if(!touching_steps) return 0;
if(w>0) w*=2; // positive wind is harder
score=touching_steps*raydium_math_abs(w); // 2000 max

tmp=3.f-fly_time; // fly time
if(tmp<0) tmp=0;
score+=400*tmp;

tmp=0.5f-dist_from_center; // fly time
if(tmp<0) tmp=0;
score+=4000*tmp;

tmp=score_timer/2;
if(tmp>1 || !growing_fx) tmp=1;
if(score>best_score) best_score=score;
return score*tmp;
}


void post_score(void)
{
int score=get_score(0);
char lversion[RAYDIUM_MAX_NAME_LEN];

if(!score) return;

strcpy(lversion,version); // since PHP will write to variables ..

raydium_register_variable(&wind,RAYDIUM_REGISTER_FLOAT,"wind");
raydium_register_variable(&breaked_bones,RAYDIUM_REGISTER_INT,"breaked_bones");
raydium_register_variable(&fly_time,RAYDIUM_REGISTER_FLOAT,"fly_time");
raydium_register_variable(&touching_steps,RAYDIUM_REGISTER_INT,"touching_steps");
raydium_register_variable(&score,RAYDIUM_REGISTER_INT,"score");
raydium_register_variable(player_name,RAYDIUM_REGISTER_STR,"name");
raydium_register_variable(lversion,RAYDIUM_REGISTER_STR,"version");

raydium_php_exec("score.php");

raydium_register_variable_unregister_last();
raydium_register_variable_unregister_last();
raydium_register_variable_unregister_last();
raydium_register_variable_unregister_last();
raydium_register_variable_unregister_last();
raydium_register_variable_unregister_last();
raydium_register_variable_unregister_last();
}


void play_hurt_sound(void)
{
raydium_sound_SourcePlay(S_hurt[rand()%4]);
}

void frame_step(GLfloat step)
{
last_frame_step=step;
if(game_part==GAME_PART_SCORE)
    score_timer+=(step/60);
}

void bone_break(int j)
{
play_hurt_sound();
breaked_bones++;
}

void camera(GLfloat px, GLfloat py, GLfloat pz, GLfloat lx, GLfloat ly, GLfloat lz, GLfloat zoom)
{
#define SLOW_FACT 30
static GLfloat opx,opy,opz;
static GLfloat olx,oly,olz;
static GLfloat ozoom=DEFAULT_ZOOM;
ALfl