示例#1
0
文件: mixer_sun.c 项目: jolange/cmus
static int sun_mixer_set_volume(int l, int r)
{
	struct mixer_ctrl minf;
	int ovall, ovalr;

	if (sun_mixer_get_volume(&ovall, &ovalr) == -1)
		return -1;

	/* OpenBSD mixer values are `discrete' */
	l = min_delta(ovall, l, sun_mixer_volume_delta);
	r = min_delta(ovalr, r, sun_mixer_volume_delta);

	minf.type = AUDIO_MIXER_VALUE;
	minf.dev = sun_mixer_device_id;

	if (sun_mixer_channels == 1)
		minf.un.value.level[AUDIO_MIXER_LEVEL_MONO] = l;
	else {
		minf.un.value.level[AUDIO_MIXER_LEVEL_LEFT] = l;
		minf.un.value.level[AUDIO_MIXER_LEVEL_RIGHT] = r;
	}
	minf.un.value.num_channels = sun_mixer_channels;

	if (ioctl(mixer_fd, AUDIO_MIXER_WRITE, &minf) == -1)
		return -1;

	return 0;
}
示例#2
0
int TauFiend::handle_damage(SpaceLocation *source, int normal, int direct)
{
	STACKTRACE;
	double alpha;
	if (source->isLine()) {
		Vector2 dpos =
			min_delta(source->normal_pos() + ((SpaceLine*)source)->edge(), map_size);
		//double dx = min_delta(source->normal_x() + ((SpaceLine*)source)->edge_x(), normal_x(), X_MAX);
		//double dy = min_delta(source->normal_y() + ((SpaceLine*)source)->edge_y(), normal_y(), Y_MAX);
		//alpha = fabs(normalize(atan3(dy, dx) * 180 / PI - angle, 360));
		alpha = fabs(normalize(dpos.atan() - angle, PI2));
	}
	else alpha = normalize(trajectory_angle(source) - angle, 360);
	if (alpha > 180) alpha -= 360;
	alpha = (90 - fabs(alpha)) / 90;
	alpha *= alpha;
	alpha *= alpha;
	alpha = normal * (alpha + (1-alpha)*(tw_random(1.0)) );
	int d = normal;
	normal = (int)floor(alpha);
	if (alpha - normal >= 0.5) normal ++;
	d -= normal;
	if (d > 0)
		play_sound(data->sampleExtra[random(8)]);
	return Ship::handle_damage(source, normal, direct);
}
示例#3
0
double TauMCMissile::get_aim(SpaceObject *tgt)
{
	STACKTRACE;
	Vector2 tv = tgt->get_vel();
	//double tvy = tgt->get_vy();
	//double rx  = min_delta(tgt->normal_x(), normal_x(), X_MAX);
	//double ry  = min_delta(tgt->normal_y(), normal_y(), Y_MAX);
	Vector2 r = min_delta(tgt->normal_pos(), normal_pos());
								 //rx*rx + ry*ry;
	double r2  = magnitude_sqr(r);
	double u2  = v * v;
								 //(tvx*tvx + tvy*tvy);
	double d2v = u2 - magnitude_sqr(tv);
	double t = r.dot(tv);		 //(rx*tvx + ry*tvy);
	double q, p;
	if (fabs(d2v/u2) > 0.01 ) {
		q = t*t + r2*d2v;
		if (q > 0) q = sqrt(q);
		else    return (1e10);
		p = (t+q)/d2v;
		q = (t-q)/d2v;
		if (p > 0) t = p;
		else       t = q;
		if (t < 0) return (1e10);
	} else {
		if (fabs(t)<1e-6) return (1e10);
		else    t = - 0.5 * r2 / t;
		if (t < 0) return (1e10);
	}
	t = normalize(atan3(tv.y*t + r.y, tv.x*t + r.x) - angle, PI2);
	if (t > PI) t -= PI2;
	return (t);
}
示例#4
0
int Hook2::handle_damage(SpaceLocation *src, double normal, double direct)
{
	STACKTRACE;
	if ( src == hooktarget )
		return 0;

	if ( src->isShip() || (bHitAsteroids && src->isAsteroid())) {
		if ( hooktarget )		 // if it's already attached to another ship
			return 0;

		if ( src == ship )
			return 0;			 // if it is the ship itself (doh)

		hooktarget = src;

		game->play_sound(data->sampleSpecial[1],this);

		hookfixdist = magnitude(min_delta(pos, src->pos, map_size));
		hookfixorientation = atan(min_delta(pos, src->pos, map_size)) - src->angle;
		hookfixangle = angle - src->angle;

		collide_flag_anyone = 0;
		collide_flag_sameteam = 0;
		collide_flag_sameship = 0;

		hooklocked = 1;			 // stop unrolling any further

		if (src->isShip()) {
			src->ship->turn_rate *= 0.80;
			damage(src, 1.0, 0.0);
		}

		return 0;

	} else {

		SpaceObject::handle_damage(src, normal, direct);

		armour -= normal + direct;
		if ( armour <= 0 )
			state = 0;

		return iround(normal + direct);
	}
}
示例#5
0
void Hook2::animate_ropeseg( Frame *space, Vector2 pos1, Vector2 pos2, int ropecol )
{
	STACKTRACE;
	int ix1, iy1, ix2, iy2;

	Vector2 co;

	co = corner(pos1);
	ix1 = int(co.x);
	iy1 = int(co.y);

	co = corner(pos2);
	ix2 = int(co.x);
	iy2 = int(co.y);

	int dx, dy;
	dx = iround(min_delta(ix2, ix1, map_size.x));
	dy = iround(min_delta(iy2, iy1, map_size.y));
	ix2 = ix1 + dx;
	iy2 = iy1 + dy;

	// simulate visibility of a glittering line in the sun ...
	double a, colscale;
	a = atan2((float)dy,(float)dx);
	colscale = fabs(sin(a));	 // flat lying = less visible.

	int col, r, g, b;
	col = ropecol;
	r = iround(getr(col) * colscale);
	g = iround(getg(col) * colscale);
	b = iround(getb(col) * colscale);
	col = makecol(r, g, b);

	// draw the line

	line(space->surface, ix1, iy1, ix2, iy2, col);
	space->add_line(ix1, iy1, ix2, iy2);

}
示例#6
0
double VelronCruiser::get_aim(SpaceObject *tgt, double min_angle, double max_angle)
{
	STACKTRACE;
	if (tgt == NULL)
		return (-1000);

	Vector2 tv = tgt->get_vel() - specialRelativity * vel;
	double tvx = tv.x;
	double tvy = tv.y;
	tv = min_delta(tgt->normal_pos(), pos);
	double rx  = tv.x;
	double ry  = tv.y;
	double r2  = rx*rx + ry*ry;
	double u2  = specialVelocity;
	u2 *= u2;
	double d2v = u2 - (tvx*tvx + tvy*tvy);
	double t = (rx*tvx + ry*tvy);
	double q, p;
	if (fabs(d2v/u2) > 0.01 ) {
		q = t*t + r2*d2v;
		if (q > 0) q = sqrt(q);
		else    return (-1000);
		p = (t+q)/d2v;
		q = (t-q)/d2v;
		if (p > 0) t = p;
		else       t = q;
		if (t < 0) return (-1000);
	} else {
		if (fabs(t)<1e-6) return (-1000);
		else    t = - 0.5 * r2 / t;
		if (t < 0) return (-1000);
	}
	if (t * specialVelocity > specialRange) return(-1000);
	t = normalize((atan3(tvy*t + ry, tvx*t + rx)) - angle, PI2);
	double d_a = normalize(t - min_angle, PI2);
	if (d_a > PI) d_a -= PI2;
	if (d_a > 0) {
		d_a = normalize(t - max_angle, PI2);
		if (d_a > PI) d_a -= PI2;
		if (d_a < 0)
			return (t);
	}
	return (-1000);
}
示例#7
0
// an exact copy, with a small modification: it also return a boolean value
int ShipPart::collide_SpaceObject(SpaceObject *other)
{
	STACKTRACE;
	//	double dx, dy;
	//	double dvx, dvy;
	double tmp;

	//	int x1, y1;
	//	int x2, y2;

	if (this == other) {tw_error("SpaceObject::collide - self!");}
	if ((!canCollide(other)) || (!other->canCollide(this))) return 0;
	if (!exists() || !other->exists()) return 0;

	pos = normal_pos();

	Vector2 p1, p2, dp, dv;

	p1 = pos;
	p2 = other->normal_pos();
	dp.x = min_delta(p1.x, p2.x, map_size.x);
	dp.y = min_delta(p1.y, p2.y, map_size.y);
	p2 = p1 - dp - other->size / 2;
	p1 = p1 - size / 2;

	/*	x1 = (int)(normal_x() - (w / 2.0));
		y1 = (int)(normal_y() - (h / 2.0));
		dx = min_delta(normal_x(), other->normal_x(), map_size.x);
		dy = min_delta(normal_y(), other->normal_y(), Y_MAX);
		x2 = (int)(normal_x() - dx - ((other->w) / 2.0));
		y2 = (int)(normal_y() - dy - ((other->h) / 2.0));*/

	if (!sprite->collide(iround(p1.x), iround(p1.y), sprite_index, iround(p2.x), iround(p2.y),
		other->get_sprite_index(), other->get_sprite() ))
		return 0;
	//sprite->collide(x1, y1, sprite_index, x2, y2, other->sprite_index, other->sprite);

	inflict_damage(other);
	other->inflict_damage(this);

	if (!mass || !other->mass) return 0;

	dv = vel - other->vel;

	p1 = pos;
	p2 = other->normal_pos();
	dp.x = min_delta(p1.x, p2.x, map_size.x);
	dp.y = min_delta(p1.y, p2.y, map_size.y);
	p2 = p1 - dp - other->size / 2;
	p1 = p1 - size / 2;

	/*x1 = (int)(normal_x() - (w / 2.0));
	y1 = (int)(normal_y() - (h / 2.0));
	dx = min_delta(normal_x(), other->normal_x(), map_size.x);
	dy = min_delta(normal_y(), other->normal_y(), Y_MAX);
	x2 = (int)(normal_x() - dx - ((other->w) / 2.0));
	y2 = (int)(normal_y() - dy - ((other->h) / 2.0));*/

	while ((dp.x == 0) && (dp.y == 0)) {
		dp.x = (tw_random(5) - 2) / 99.0;
		dp.y = (tw_random(5) - 2) / 99.0;
	}

	Vector2 _dp = unit_vector(dp);
	tmp = dot_product(dv, _dp);
	tmp = ( -2 * tmp );

	if (mass + other->mass > 1)
		tmp = tmp * (mass * other->mass) / (mass + other->mass);

	if (tmp >= 0) {
		if (mass > 1)
			vel += _dp * tmp / mass;
		if (other->mass > 1)
			other->change_vel (- _dp * tmp / other->mass );
	}

	Vector2 nd;
	nd = unit_vector(dp);

	if (mass + other->mass > 1)
		nd /= (mass + other->mass);

	while (sprite->collide(iround(p1.x), iround(p1.y), sprite_index, iround(p2.x), iround(p2.y),
	other->get_sprite_index(), other->get_sprite() )) {
		pos = normalize(pos + nd * other->mass);
		other->pos = normalize(other->pos - nd * mass);

		p1 = pos;
		p2 = other->normal_pos();
		dp.x = min_delta(p1.x, p2.x, map_size.x);
		dp.y = min_delta(p1.y, p2.y, map_size.y);
		p2 = p1 - dp - other->size / 2;
		p1 = p1 - size / 2;
	}

	#ifdef _DEBUG
	SpaceObject *c1 = this;
	SpaceObject *c2 = other;
	if (fabs(c1->vel.x) > 1E6 || fabs(c1->vel.y) > 1E6 || fabs(c2->vel.x) > 1E6 || fabs(c2->vel.y) > 1E6 ) {
		int a1 = c1->canCollide(c2);
		int a2 = c2->canCollide(c1);
		bool b = ((c1->canCollide(c2) & c2->canCollide(c1)) == 0 );
		tw_error("velocity error in collision involving objects [%s] and [%s]", c1->get_identity(), c2->get_identity());
	}
	#endif

	return 1;
}
示例#8
0
void Hook2::calculate()
{
	STACKTRACE;
	exist_time += frame_time * 1E-3;
	if ( exist_time > life_time )
		state = 0;

	// if it's completely unrolled ...
	if ( hooklocked && Nnodes <= 0 )
		state = 0;

	// or if the host ship has gone
	if ( !(ship && ship->exists()) ) {
		ship = 0;
		state = 0;
	}

	if ( hooktarget && hooktarget->exists() ) {
		vel = hooktarget->vel;
		angle = hooktarget->angle + hookfixangle;
		sprite_index = get_index(angle);
		pos = hooktarget->pos + hookfixdist * unit_vector(hooktarget->angle + hookfixorientation);
	}
	else if (hooklocked) {
		state = 0;
		hooktarget = 0;
	}

	if ( state == 0 )
		return;

	SpaceObject::calculate();

	if ( !hooklocked)
		roll_time += frame_time * 1E-3;
	else						 // otherwise it keeps pumping energy into the line
		roll_time = 0.0;

	Vector2 hookendpos;
	hookendpos = pos - hooksize * unit_vector(angle);

	Vector2 ejpos;
	if (ship && ship->exists() ) {
		ejpos = ship->pos + ropestart * unit_vector(ship->angle) +
			15 * sin(oscperiod*roll_time) * unit_vector(ship->angle + 0.5*PI);

	}
	else
		ejpos = 0;

	if (ship && ship->exists() && !hooklocked ) {
		// extend the elastic rope slowly

		double dL;
		if ( Nnodes > 0 )
			dL = magnitude(min_delta(ropenode[Nnodes-1].pos, ejpos, map_size));
		else
			dL = magnitude(min_delta(hookendpos, ejpos, map_size));

		if ( dL > ropeseglen && Nnodes < maxnodes ) {

			ropenode[Nnodes].pos = ejpos;
								 // *1E+3 because from now we do calculations in seconds instead of ms.
			ropenode[Nnodes].vel = (ship->vel + ejvel * unit_vector(ship->angle)) * 1E+3;
								 // changes color every 4 pieces ?
			ropenode[Nnodes].col = pallete_color[11 + (Nnodes/4) % 3];
			dL = ropeseglen;
								 // relaxed length of the segment between nodes i and i-1.
			ropenode[Nnodes].dL = dL;

			++ Nnodes;

			if ( Nnodes == maxnodes )
				state = 0;		 // no target found ... poor thing ;)

		}

	}

	// calculate the nodes on the elastic rope (except the end-points, which are fixed:

	double k = springconst;		 // 250.0

	int i;

	Vector2 D;
	double  R;

	//	ropenode[0].acc = ..;
	//	ropenode[Nnodes-1].acc = ..;

	int Ninterpol, iinterpol;

	// this may be needed if values of the spring constant are high
	Ninterpol = 10;
	double dt = frame_time * 1E-3 / Ninterpol;

	for ( iinterpol = 0; iinterpol < Ninterpol; ++iinterpol ) {

		// reset forces
		for ( i = 0; i < Nnodes; ++i )
			ropenode[i].acc = 0;

		// forces between rope nodes
		for ( i = 0; i < Nnodes; ++i ) {
			if ( i > 0 ) {
				D = min_delta(ropenode[i-1].pos - ropenode[i].pos, map_size);
				R = D.length();
				L = ropenode[i].dL;

				if ( R != 0 )
					ropenode[i].acc += k * (R - L) * D / R;
			}

			if ( i < Nnodes-1 ) {
				D = min_delta(ropenode[i+1].pos - ropenode[i].pos, map_size);
				R = D.length();
				L = ropenode[i+1].dL;

				if ( R != 0 )
					ropenode[i].acc += k * (R - L) * D / R;
			}
		}

		// attached to the hook
		Vector2 hookacc;
		hookacc = 0;

		if ( Nnodes > 0 ) {
			i = 0;

			D = min_delta(hookendpos - ropenode[i].pos, map_size);
			R = D.length();
			L = ropenode[i].dL;

			hookacc = k * (R - L) * D / R;

			if ( R != 0 )
				ropenode[i].acc += hookacc;
		}

		// attached to the ship, if it still exists...
		if ( ship && ship->exists() && Nnodes > 0 ) {
			i = Nnodes-1;

			D = min_delta(ejpos - ropenode[i].pos, map_size);
			R = D.length();
			L = ropeseglen;		 // should be i+1, but that doesn't exist
			if ( R != 0 )
				ropenode[i].acc += k * (R - L) * D / R;;
		}

		// slow down a little, for stability
		for ( i = 0; i < Nnodes; ++i )
			ropenode[i].acc -= 10.0 * ropenode[i].vel * dt;

		// apply accelerations (also to the end points)
		for ( i = 0; i < Nnodes; ++i ) {
			ropenode[i].vel += ropenode[i].acc * dt;
			ropenode[i].pos += ropenode[i].vel * dt;
		}

		// apply acceleration to the target:
		if ( hooktarget && hooktarget->exists() ) {
			hooktarget->vel -= 0.1 * 1E-3 * hookacc * dt;

			// and also some deceleration ...
			double a = 1 - 0.1*dt;
			if ( a < 0 ) a = 0;
			if ( a > 1 ) a = 1;
			hooktarget->vel *= a;

			// influence the angle of the enemy ship:

			a = atan(hookendpos - hooktarget->pos);

			double b, da, rotacc;
			b = atan(hookacc);

			da = b - a;

			rotacc = magnitude(hookacc) * sin(da);

			hooktarget->angle -= 0.25 * 1E-3 * rotacc * dt;

			// angle must never exceed half PI with the end of the rope...

			b = atan(ropenode[0].pos - hookendpos);

			da = b - a;

			while ( da >  PI )  da -= PI2;
			while ( da < -PI )  da += PI2;

			if ( da < -0.5*PI || da > 0.5*PI ) {
				double dacorr = fabs(da) - 0.5*PI;
				if ( dacorr > 5*PI2*dt )
					dacorr = 5*PI2*dt;

				if ( da < 0.0 )
					hooktarget->angle -= dacorr;
				else
					hooktarget->angle += dacorr;
			}

			// to stabilize, make sure neither vessels' speed ever exceeds the maximum:

			double V1, V2;

			if ( ship && ship->exists() ) {
				V1 = magnitude(ship->vel);
				V2 = 2 * ship->speed_max;
				if ( V1 > V2 )
					ship->vel *= V2 / V1;
			}

			if ( hooktarget->isShip() ) {
				V1 = magnitude(hooktarget->vel);
				V2 = 2 * ((Ship*) hooktarget)->speed_max;
				if ( V1 > V2 )
					hooktarget->vel *= V2 / V1;
			}

		}

	}

}
示例#9
0
// an exact copy, with a small modification: it also return a boolean value
int ShipPart2::collide_SpaceObject(SpaceObject *other)
{
	STACKTRACE;
	//	double dx, dy;
	//	double dvx, dvy;
	double tmp;

	//	int x1, y1;
	//	int x2, y2;

	if (this == other) {
		tw_error("SpaceObject::collide - self!");
	}
	if ((!canCollide(other)) || (!other->canCollide(this)))
		return 0;
	if (!exists() || !other->exists())
		return 0;

	pos = normal_pos();

	Vector2 p1, p2, dp, dv;

	p1 = pos;
	p2 = other->normal_pos();
	dp.x = min_delta(p1.x, p2.x, map_size.x);
	dp.y = min_delta(p1.y, p2.y, map_size.y);
	p2 = p1 - dp - other->size / 2;
	p1 = p1 - size / 2;

	/*	x1 = (int)(normal_x() - (w / 2.0));
		y1 = (int)(normal_y() - (h / 2.0));
		dx = min_delta(normal_x(), other->normal_x(), map_size.x);
		dy = min_delta(normal_y(), other->normal_y(), Y_MAX);
		x2 = (int)(normal_x() - dx - ((other->w) / 2.0));
		y2 = (int)(normal_y() - dy - ((other->h) / 2.0));*/

	if (!sprite->collide(iround(p1.x), iround(p1.y), sprite_index, iround(p2.x), iround(p2.y),
		other->get_sprite_index(), other->get_sprite() ))
		return 0;
	//sprite->collide(x1, y1, sprite_index, x2, y2, other->sprite_index, other->sprite);

	inflict_damage(other);
	other->inflict_damage(this);

	if (!mass || !other->mass)
		return 0;

	dv = vel - other->vel;

	p1 = pos;
	p2 = other->normal_pos();
	dp.x = min_delta(p1.x, p2.x, map_size.x);
	dp.y = min_delta(p1.y, p2.y, map_size.y);
	p2 = p1 - dp - other->size / 2;
	p1 = p1 - size / 2;

	/*x1 = (int)(normal_x() - (w / 2.0));
	y1 = (int)(normal_y() - (h / 2.0));
	dx = min_delta(normal_x(), other->normal_x(), map_size.x);
	dy = min_delta(normal_y(), other->normal_y(), Y_MAX);
	x2 = (int)(normal_x() - dx - ((other->w) / 2.0));
	y2 = (int)(normal_y() - dy - ((other->h) / 2.0));*/

	while ((dp.x == 0) && (dp.y == 0)) {
		dp.x = (tw_random(5) - 2) / 99.0;
		dp.y = (tw_random(5) - 2) / 99.0;
	}

	Vector2 _dp = unit_vector(dp);
	tmp = dot_product(dv, _dp);
	tmp = ( -2 * tmp );
	tmp = tmp * (mass * other->mass) / (mass + other->mass);
	if (tmp >= 0) {
		vel += _dp * tmp / mass;
		other->vel -= _dp * tmp / other->mass;
	}

	Vector2 nd;
	nd = unit_vector(dp);
	nd /= (mass + other->mass);
	while (sprite->collide(iround(p1.x), iround(p1.y), sprite_index, iround(p2.x), iround(p2.y),
	other->get_sprite_index(), other->get_sprite() )) {
		pos = normalize(pos + nd * other->mass);
		other->pos = normalize(other->pos - nd * mass);

		p1 = pos;
		p2 = other->normal_pos();
		dp.x = min_delta(p1.x, p2.x, map_size.x);
		dp.y = min_delta(p1.y, p2.y, map_size.y);
		p2 = p1 - dp - other->size / 2;
		p1 = p1 - size / 2;
	}

	return 1;
}