// IN:  in1 = x, in2 = y
// OUT: out1 = lenght
// length = sqrt( x*x + y*y )
state vec2d_lenght

	setvarvar out1 in1
	mulvarvar out1 out1
	setvarvar math_tmp1 in2
	mulvarvar math_tmp1 math_tmp1
	addvarvar out1 math_tmp1
	sqrt out1 out1
	
ends

// IN:  in1 = x, in2 = y, in3 = z
// OUT: out1 = lenght
// length = sqrt( x*x + y*y + z*z )
state vec3d_length

	setvarvar out1 in1
	mulvarvar out1 out1
	setvarvar math_tmp1 in2
	mulvarvar math_tmp1 math_tmp1
	addvarvar out1 math_tmp1
	setvarvar math_tmp1 in3
	mulvarvar math_tmp1 math_tmp1
	addvarvar out1 math_tmp1
	sqrt out1 out1
	
ends

// IN : in1 = x, in2 = y
// OUT: out1 = x, out2 = y
//
//                         ^
//                         |
//    (left hand normal)<--+--> (right hand normal)
//
state vec2d_get_normal_lh 

	setvarvar out1 in2
	setvarvar out2 in1
	mulvar out2 -1
	
ends

// IN: in1 = x, in2 = y, in3 = z
// values must bee fixed point ( 1000 == 1.0 )
// reduce velocity (in/1000) times
state phys_scale_vel
 
	mulvarvar phys_x_internal 1000
	ifvarg in1 0 divvarvar phys_x_internal in1
	mulvarvar phys_y_internal 1000
	ifvarg in2 0 divvarvar phys_y_internal in2
	mulvarvar phys_z_internal 1000
	ifvarg in3 0 divvarvar phys_z_internal in3
	
ends

// IN : in1 = x, in2 = y, in3 = z
// add vector to velocity
state phys_add_vel

	addvarvar phys_x_internal in1
	addvarvar phys_y_internal in2
	addvarvar phys_z_internal in3
	
ends

// IN :in1 = angle, in2 = length, in3 = z
// transform angle&length in vector, an add to velocity
state phys_add_vel_ang
	
	cos x in1
	sin y in1
	mulvarvar x in2
	divvar x TRIG_MAX
	addvarvar phys_x_internal x
	
	mulvarvar y in2
	divvar y TRIG_MAX
	addvarvar phys_y_internal y
	
	addvarvar phys_z_internal in3
	
ends

// set velocity to 0
state phys_reset_vel
	
	setvar phys_x_internal 0
	setvar phys_y_internal 0
	setvar phys_z_internal 0
	
ends

// IN : in1 = box radius
state phys_add_vel_rand_box

	setvarvar phys_utils_tmp1 in1
	mulvar phys_utils_tmp1 2
	// phys_utils_tmp1 == max-min
	
	randvarvar phys_utils_tmp2 phys_utils_tmp1
	subvarvar phys_utils_tmp2 in1
	addvarvar phys_x_internal phys_utils_tmp2
	
	randvarvar phys_utils_tmp2 phys_utils_tmp1
	subvarvar phys_utils_tmp2 in1
	addvarvar phys_y_internal phys_utils_tmp2
	
	randvarvar phys_utils_tmp2 phys_utils_tmp1
	subvarvar phys_utils_tmp2 in1
	addvarvar phys_z_internal phys_utils_tmp2
	
ends

// start physics interactions ////////////////////////
state physics_start
	
	getactorvar[THISACTOR].phys_vel_x phys_x_internal
	getactorvar[THISACTOR].phys_vel_y phys_y_internal
	getactorvar[THISACTOR].phys_vel_z phys_z_internal

ends

// finish physics interactions ////////////////////////
state physics_end
	
	setactorvar[THISACTOR].phys_vel_x phys_x_internal
	setactorvar[THISACTOR].phys_vel_y phys_y_internal
	setactorvar[THISACTOR].phys_vel_z phys_z_internal
	
ends 
	
// physics interactions in air /////////////////////////
state physics_interact_air

	getactorvar[THISACTOR].phys_gravity_x in1
	getactorvar[THISACTOR].phys_gravity_y in2
	getactorvar[THISACTOR].phys_gravity_z in3
	state phys_add_vel

	getactorvar[THISACTOR].phys_air_damping_x in1
	getactorvar[THISACTOR].phys_air_damping_y in2
	getactorvar[THISACTOR].phys_air_damping_z in3
	state phys_scale_vel
	
ends
	
	
// physics interactions on ground ///////////////////////
// OUT : 1 - if object on ground, 0 - elsewere
state physics_interact_ground

	setvar out1 0
	
	iffloordistl 1
	{
		getactorvar[THISACTOR].phys_max_fall_speed phys_core_tmp1
		ifvarvarg phys_z_internal phys_core_tmp1
			killit
		
		getactorvar[THISACTOR].phys_gnd_damping_x in1
		getactorvar[THISACTOR].phys_gnd_damping_y in2
		getactorvar[THISACTOR].phys_gnd_damping_z in3
		state phys_scale_vel
		
		mulvar phys_z_internal -1
		
		setvar out1 1
				
	}
	
ends

// physics interactions on walls ///////////////////////
// OUT : 1 - if object touch wall, 0 - elsewere
state physics_interact_walls
	
	setvar out1 0
	
	setvarvar phys_core_tmp1 phys_movfalg_interanl
	andvar phys_core_tmp1 TOUCH_MASK
	ifvare phys_core_tmp1 TOUCH_WALL_FLAG
	{

		// calc wall reflection
		// in src is:
		// k = getangle(
        //              wall[wall[j].point2].x-wall[j].x,
        //              wall[wall[j].point2].y-wall[j].y);
        //        s->ang = ((k<<1) - s->ang)&2047;
	
		// j &= (MAXWALLS-1);
		setvarvar phys_core_tmp1 phys_movfalg_interanl
		andvar phys_core_tmp1 MAXWALLS_MASK
		
		getactorvar[THISACTOR].phys_wall_damping_x in1
		getactorvar[THISACTOR].phys_wall_damping_y in2
		getactorvar[THISACTOR].phys_wall_damping_z in3
		state phys_scale_vel
		
		// get wall vector
		// wall[wall[j].point2].x-wall[j].x
		// wall[wall[j].point2].y-wall[j].y
		getwall[phys_core_tmp1].x phys_core_tmp2
		getwall[phys_core_tmp1].y phys_core_tmp3
		getwall[phys_core_tmp1].point2 phys_core_tmp1
		getwall[phys_core_tmp1].x phys_core_tmp4
		getwall[phys_core_tmp1].y phys_core_tmp5
		subvarvar phys_core_tmp4 phys_core_tmp2
		subvarvar phys_core_tmp5 phys_core_tmp3
		// ( phys_core_tmp4,phys_core_tmp5 ) - wall vector
		
		// get reflect angle
		// s->ang = ((k<<1) - s->ang)&2047;
		getangle phys_core_tmp2 phys_core_tmp4 phys_core_tmp5
		getangle phys_core_tmp3 phys_x_internal phys_y_internal
		shiftvarl phys_core_tmp2 1
		subvarvar phys_core_tmp2 phys_core_tmp3
		andvar phys_core_tmp2 2047
		
		// calc vector length
		setvarvar in1 phys_x_internal
		setvarvar in2 phys_y_internal
		state vec2d_lenght
		
		// calc reflect vector
		// phys_out_1 vector lendth
		cos phys_x_internal phys_core_tmp2
		mulvarvar phys_x_internal out1 
		divvar phys_x_internal TRIG_MAX 
		
		sin phys_y_internal phys_core_tmp2
		mulvarvar phys_y_internal out1
		divvar phys_y_internal TRIG_MAX
		
		setvar out1 1
			
	}
	
ends

// moves object /////////////////////////////////////
state physics_move
	movesprite THISACTOR phys_x_internal phys_y_internal phys_z_internal CLIPMASK0 phys_movfalg_interanl
ends