Index: kinghill2.c
===================================================================
--- kinghill2.c	(revision 2)
+++ kinghill2.c	(revision 3)
@@ -0,0 +1,468 @@
+// TODO :
+// timelimit (sync server side ?)
+// spectate mode ? (raydium modif : "no element" client keep alive)
+
+#include "raydium/index.c"
+
+void create_car(void);
+ 
+GLfloat sun[]={1.0,0.9,0.9,1.0};
+int son_moteur;
+int game_state;
+
+//#define DEFAULT_RESPAWN_ONLY
+#define MAX_RESPAWNS		16
+GLfloat respawns[MAX_RESPAWNS][6];
+int respawn_index=0;
+GLfloat ground_z=0;
+GLfloat static_camera[3];
+short scores[RAYDIUM_NETWORK_MAX_CLIENTS];
+char camera_file[128];
+
+#define GAME_MENU		1
+#define GAME_GAME		2
+#define GAME_END		3
+#define GAME_OUT		4
+
+#define TYPE_BALANCIER          6
+#define TYPE_CORPS          	7
+
+
+
+void read_world(char *filename)
+{
+FILE *fp;
+int v;
+dReal p[6];
+char ent[128];
+
+respawn_index=0;
+fp=raydium_file_fopen(filename,"rt");
+if(!fp) return;
+fscanf(fp,"%i\n",&v);
+while(fscanf(fp,"%f %f %f %f %f %f %s\n",&p[0],&p[1],&p[2],&p[3],&p[4],&p[5],ent)!=EOF)
+    {
+    switch(ent[0])
+	{
+	case 'r':
+	    memcpy(respawns[respawn_index],p,sizeof(GLfloat)*6);
+	    respawn_index++;
+	    break;
+	case 'g':
+	    ground_z=p[2];
+	    break;
+
+	}
+    }
+
+fclose(fp);
+}
+
+void set_world(char *root)
+{
+char f[256];
+
+sprintf(f,"%s.tri",root);
+raydium_ode_ground_set_name(f);
+
+sprintf(f,"%s.ent",root);
+read_world(f);
+
+sprintf(camera_file,"%s.cam",root);
+} PHP_v_s(set_world)
+
+
+
+void game_state_change(int state)
+{
+int i;
+
+game_state=state;
+switch(state)
+    {
+    case GAME_MENU:
+	raydium_gui_show();
+	break;
+    case GAME_GAME:
+	raydium_gui_hide();
+	create_car();
+	break;
+    case GAME_END:
+	raydium_ode_object_delete_name("WATURE");
+	break;
+    case GAME_OUT:
+	// "tu tombes !"
+	i=raydium_network_uid;
+	if(i<0) i=0;
+	scores[i]++;
+	raydium_network_propag_refresh(RAYDIUM_NETWORK_PACKET_BASE+i);
+	break;
+    }
+}
+
+
+char collide(int e1, int e2, dContact *c)
+{
+int i1,i2;
+i1=raydium_ode_element_tag_get(e1);
+i2=raydium_ode_element_tag_get(e2);
+
+if(i1==TYPE_BALANCIER || i2==TYPE_BALANCIER)
+    return 0;
+
+return 1;
+}
+
+
+char draw_element_after(int elem)
+{
+int type;
+dReal *pos;
+                                                                                
+type=raydium_ode_element_tag_get(elem);
+if(type==TYPE_CORPS && raydium_ode_network_element_isdistant(elem))
+    {
+    int player;
+    int his_score;
+    int our_score;
+    char color;
+    pos=raydium_ode_element_pos_get(elem);
+    player=raydium_ode_network_element_distantowner(elem);
+
+    his_score=scores[player];
+    our_score=scores[raydium_network_uid];
+    color=(our_score>=his_score?'c':'a');
+
+    raydium_osd_printf_3D(pos[0],pos[1],pos[2],12,0.5,"font2.tga","^f%s^f (^%c%i^f)",raydium_network_name[player],color,his_score);
+    }
+return 1;
+}
+
+
+void btnErrorOkClick(raydium_gui_Object *w)
+{
+raydium_gui_window_delete_name("error");
+}
+
+
+void btnTrainingClick(raydium_gui_Object *w)
+{
+game_state_change(GAME_GAME);
+}
+
+void btnConnect(raydium_gui_Object *w)
+{
+char server[512];
+
+raydium_gui_read_name("menu","edtServer",server);
+raydium_gui_read_name("menu","edtPlayerName",raydium_network_name_local);
+
+if(!raydium_network_client_connect_to(server))
+    {
+    int handle;
+
+    handle=raydium_gui_window_create("error",25,45,50,15);
+    raydium_gui_widget_sizes(0,0,18);
+    raydium_gui_label_create("lblError",handle,50,80,"Cannot connect to server ...",0,0,0);
+    raydium_gui_widget_sizes(15,5,18);
+    raydium_gui_button_create("btnErrorOk",handle,35,15,"OK",btnErrorOkClick);
+
+    return;
+    }
+
+game_state_change(GAME_GAME);
+}
+			
+
+void create_menu(void)
+{
+int handle;
+
+raydium_gui_theme_load("theme-raydium2.gui");
+
+handle=raydium_gui_window_create("menu",45,75,50,20);
+raydium_gui_widget_sizes(0,0,18);
+raydium_gui_label_create("lblPlayerName",handle,25,85,"Player Name :",0,0,0);
+raydium_gui_widget_sizes(25,4,18);
+raydium_gui_edit_create("edtPlayerName",handle,47,75,raydium_network_name_local);
+
+raydium_gui_widget_sizes(0,0,18);
+raydium_gui_label_create("lblServer",handle,32.5,55,"Server :",0,0,0);
+raydium_gui_widget_sizes(25,4,18);
+raydium_gui_edit_create("edtServer",handle,47,45,"192.168.1.5");
+
+raydium_gui_widget_sizes(15,5,18);
+raydium_gui_button_create("btnTraining",handle,5,15,"Training",btnTrainingClick);
+raydium_gui_widget_sizes(20,5,18);
+raydium_gui_button_create("btnMulti",handle,50,15,"Multiplayer",btnConnect);
+
+}
+
+
+void create_car(void)
+{
+int a;
+int respawn;
+ 
+#define BREAK_FORCE     130
+#define ROTFRICTION     0.0005
+#define ERP_CFM         0.1,1.0
+ 
+raydium_ode_object_delete_name("WATURE");
+ 
+a=raydium_ode_object_create("WATURE");
+raydium_ode_object_box_add("corps",a,0.5,RAYDIUM_ODE_AUTODETECT,0,0,RAYDIUM_ODE_STANDARD,TYPE_CORPS,"jeepch.tri");
+raydium_ode_element_slip_name("corps",RAYDIUM_ODE_SLIP_ICE);
+
+raydium_ode_network_next_local_only=1;
+raydium_ode_object_box_add("balancier",a,1.8,0.1,0.1,0.1,RAYDIUM_ODE_STANDARD,TYPE_BALANCIER,"");
+raydium_ode_element_move_name_3f("balancier",0,0,-0.5);
+raydium_ode_joint_attach_fixed_name("balanfixed","corps","balancier");
+ 
+raydium_ode_object_sphere_add("pneu_ag",a,0.5,RAYDIUM_ODE_AUTODETECT,RAYDIUM_ODE_STANDARD,0,"roue_barbare.tri");
+//raydium_ode_element_rotfriction_name("pneu_ag",ROTFRICTION);
+raydium_ode_element_move_name_3f("pneu_ag",0.42,0.453,-0.180);
+raydium_ode_joint_attach_hinge2_name("suspet_ag","corps","pneu_ag",RAYDIUM_ODE_JOINT_SUSP_DEFAULT_AXES);
+raydium_ode_joint_break_force_name("suspet_ag",BREAK_FORCE);
+raydium_ode_joint_suspension_name("suspet_ag",ERP_CFM);
+
+raydium_ode_object_sphere_add("pneu_ad",a,0.5,RAYDIUM_ODE_AUTODETECT,RAYDIUM_ODE_STANDARD,0,"roue_barbare.tri");
+//raydium_ode_element_rotfriction_name("pneu_ad",ROTFRICTION);
+raydium_ode_element_move_name_3f("pneu_ad",0.42,-0.453,-0.180);
+raydium_ode_joint_attach_hinge2_name("suspet_ad","corps","pneu_ad",RAYDIUM_ODE_JOINT_SUSP_DEFAULT_AXES);
+raydium_ode_joint_break_force_name("suspet_ad",BREAK_FORCE);
+raydium_ode_joint_suspension_name("suspet_ad",ERP_CFM);
+
+raydium_ode_object_sphere_add("pneu_rg",a,0.5,RAYDIUM_ODE_AUTODETECT,RAYDIUM_ODE_STANDARD,0,"roue_barbare.tri");
+//raydium_ode_element_rotfriction_name("pneu_rg",ROTFRICTION);
+raydium_ode_element_move_name_3f("pneu_rg",-0.444,0.453,-0.180);
+raydium_ode_joint_attach_hinge2_name("suspet_rg","corps","pneu_rg",RAYDIUM_ODE_JOINT_SUSP_DEFAULT_AXES);
+raydium_ode_joint_hinge2_block_name("suspet_rg",1);
+raydium_ode_joint_break_force_name("suspet_rg",BREAK_FORCE);
+raydium_ode_joint_suspension_name("suspet_rg",ERP_CFM);
+ 
+raydium_ode_object_sphere_add("pneu_rd",a,0.5,RAYDIUM_ODE_AUTODETECT,RAYDIUM_ODE_STANDARD,0,"roue_barbare.tri");
+//raydium_ode_element_rotfriction_name("pneu_rd",ROTFRICTION);
+raydium_ode_element_move_name_3f("pneu_rd",-0.444,-0.453,-0.180);
+raydium_ode_joint_attach_hinge2_name("suspet_rd","corps","pneu_rd",RAYDIUM_ODE_JOINT_SUSP_DEFAULT_AXES);
+raydium_ode_joint_hinge2_block_name("suspet_rd",1);
+raydium_ode_joint_break_force_name("suspet_rd",BREAK_FORCE);
+raydium_ode_joint_suspension_name("suspet_rd",ERP_CFM);
+ 
+raydium_ode_motor_create("moteur",a,RAYDIUM_ODE_MOTOR_ENGINE);
+raydium_ode_motor_attach_name("moteur","suspet_ag",1);
+raydium_ode_motor_attach_name("moteur","suspet_ad",1);
+raydium_ode_motor_attach_name("moteur","suspet_rg",1);
+raydium_ode_motor_attach_name("moteur","suspet_rd",1);
+//raydium_ode_motor_power_max_name("moteur",0.2);
+ 
+raydium_ode_motor_create("direction",a,RAYDIUM_ODE_MOTOR_ANGULAR);
+raydium_ode_motor_attach_name("direction","suspet_ag",0);
+raydium_ode_motor_attach_name("direction","suspet_ad",0);
+raydium_ode_motor_power_max_name("direction",0.2);
+
+raydium_sound_SourcePlay(son_moteur);
+
+respawn=raydium_random_i(0,respawn_index-1);
+#ifndef DEFAULT_RESPAWN_ONLY
+raydium_ode_object_move(a,respawns[respawn]);
+raydium_ode_object_rotate(a,respawns[respawn]+3);
+#endif
+
+//raydium_log("%i (%i)",respawn,respawn_index);
+/*raydium_log("%i | %f %f %f | %f %f %f",respawn,
+				  respawns[respawn][0],
+				  respawns[respawn][1],
+				  respawns[respawn][2],
+				  respawns[respawn][3],
+				  respawns[respawn][4],
+				  respawns[respawn][5]);*/
+}
+
+
+void display_all(void)
+{
+raydium_ode_draw_all(0);
+if(raydium_key[GLUT_KEY_F1]) raydium_ode_draw_all(1);
+}
+ 
+void display(void)
+{
+float speed=0,direct=0;
+float accel=0.2;
+char tag=0;
+dReal *pos;
+dReal cam[3];
+static float secs=0;
+int i;
+
+
+if(raydium_key_last==1027) exit(0);
+
+raydium_clear_frame();
+
+
+switch(game_state)
+    { 
+    case GAME_GAME:
+
+	raydium_joy_key_emul();
+ 
+        direct=raydium_joy_x*0.3;
+
+        if(raydium_joy_y>0.3)
+    	    {
+    	    speed=raydium_joy_y*10;
+	    raydium_ode_motor_power_max_name("moteur",accel);
+	    tag=1;
+	    }
+	else
+	if(raydium_joy_y<-0.3)
+	    {
+    	    speed=raydium_joy_y*5;
+	    raydium_ode_motor_power_max_name("moteur",0.2 * -raydium_joy_y);
+	    tag=1;
+	    }
+
+	if(!tag)
+	    {
+		speed=0;
+		raydium_ode_motor_power_max_name("moteur",0.05);
+	    }
+ 
+	raydium_ode_motor_speed_name("moteur",-speed);
+        raydium_ode_motor_angle_name("direction",direct);
+  
+	// get element position
+        pos=raydium_ode_element_pos_get_name("corps");
+
+	// raydium_log("%f %f",pos[2],ground_z);
+#ifndef DEFAULT_RESPAWN_ONLY
+	if(pos[2]<ground_z)
+	    {
+	    // raydium_log("toto");
+	    game_state_change(GAME_OUT);
+	    }
+#endif	
+
+        // get position of camera in world coords
+        raydium_ode_element_RelPointPos_name("corps",-1,0,0,cam);
+
+        // correct z pos (always at top of the car, for example)
+	cam[2]=pos[2]+0.5;
+    
+        // standard smooth lookat camera
+        raydium_camera_smooth(cam[0],cam[1],cam[2],pos[1],-pos[2],pos[0],
+			      70,0,raydium_frame_time*3);
+
+
+        static_camera[0]=cam[0];
+        static_camera[1]=cam[1];
+	static_camera[2]=cam[2];
+ 
+	display_all();
+	raydium_osd_printf(3.4,96.6,35,0.5,"font2.tga","^0- %s -",raydium_network_name_local);
+	raydium_osd_printf(3,97,35,0.5,"font2.tga","^f- %s -",raydium_network_name_local);
+
+
+	i=raydium_network_uid;
+	if(i<0) i=0;
+	raydium_osd_printf(2,2,15,0.5,"font2.tga","^fscore: %i",scores[i]);
+
+        raydium_ode_element_sound_update_name("corps",son_moteur);
+
+
+	speed=raydium_ode_motor_speed_get_name("moteur",1);
+	speed/=12;
+	speed+=0.5;
+	speed+=(raydium_random_neg_pos_1()/15);
+	raydium_sound_SetSourcePitch(son_moteur,raydium_trigo_abs(speed));
+    break;
+
+
+    case GAME_OUT:
+	raydium_ode_element_slip_name("corps",RAYDIUM_ODE_SLIP_DEFAULT);
+	raydium_ode_motor_power_max_name("moteur",10);
+	raydium_ode_motor_speed_name("moteur",0);
+        raydium_ode_motor_angle_name("direction",0);
+        raydium_ode_element_sound_update_name("corps",son_moteur);
+	raydium_sound_SetSourcePitch(son_moteur,0.2);
+
+	if(raydium_key_last==1032)
+	    game_state_change(GAME_GAME);
+
+
+	pos=raydium_ode_element_pos_get_name("corps");
+	raydium_camera_smooth(static_camera[0],
+			      static_camera[1],	
+			      static_camera[2],	
+			      pos[1],-pos[2],pos[0],
+			      90,0,raydium_frame_time*3);
+
+	display_all();
+	raydium_osd_printf(47,53,15,0.5,"font2.tga","^f[ ^cOUT!^f ]");
+    break;
+
+    case GAME_MENU:
+	secs+=raydium_frame_time;
+	raydium_camera_smooth_path_to_pos(camera_file,0,0,0,secs,2*raydium_frame_time);
+	display_all();
+    break;
+    }
+
+
+raydium_rendering_finish();
+
+raydium_ode_network_element_send_iterative(RAYDIUM_ODE_NETWORK_OPTIMAL);
+}
+ 
+int main(int argc, char **argv)
+{
+int i;
+
+raydium_init_args(argc,argv);
+raydium_window_create(640,480,RAYDIUM_RENDERING_WINDOW,"King of the Hill 2");
+raydium_texture_filter_change(RAYDIUM_TEXTURE_FILTER_TRILINEAR);
+raydium_projection_near=0.01;
+raydium_projection_far=1000;
+raydium_projection_fov=60;
+raydium_window_view_update();
+raydium_light_on(0);
+memcpy(raydium_light_color[0],sun,raydium_internal_size_vector_float_4);
+raydium_light_intensity[0]=1000000;
+ 
+raydium_light_position[0][0]=50;
+raydium_light_position[0][1]=150;
+raydium_light_position[0][2]=200;
+ 
+raydium_light_update_all(0);
+raydium_background_color_change(sun[0],sun[1],sun[2],sun[3]);
+raydium_fog_disable();
+ 
+raydium_ode_CollideCallback=collide;
+raydium_ode_AfterElementDrawCallback=draw_element_after;
+
+raydium_register_function(C2PHP(set_world),"set_world");
+
+set_world("kinghill2");
+//set_world("jeep_hangarl");
+
+
+raydium_sound_DefaultReferenceDistance=4.f;
+son_moteur=raydium_sound_LoadWav("jeepch.wav");
+create_menu();
+ 
+// scores init
+for(i=0;i<RAYDIUM_NETWORK_MAX_CLIENTS;i++)
+    {
+    scores[i]=0;
+    raydium_network_propag_add(RAYDIUM_NETWORK_PACKET_BASE+i,scores+i,sizeof(short));
+    }
+
+game_state_change(GAME_MENU);
+
+raydium_callback(&display);
+ 
+return 0;
+}
+