⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 iforce-ff.c

📁 优龙2410linux2.6.8内核源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Analyse the changes in an effect, and tell if we need to send a periodic * parameter effect */static int need_period_modifier(struct iforce* iforce, struct ff_effect* new){	int id = new->id;	struct ff_effect* old = &iforce->core_effects[id].effect;	if (new->type != FF_PERIODIC) {		printk(KERN_WARNING "iforce.c: bad effect type in need_periodic_modifier\n");		return FALSE;	}	return (old->u.periodic.period != new->u.periodic.period		|| old->u.periodic.magnitude != new->u.periodic.magnitude		|| old->u.periodic.offset != new->u.periodic.offset		|| old->u.periodic.phase != new->u.periodic.phase);}/* * Analyse the changes in an effect, and tell if we need to send an effect * packet */static int need_core(struct iforce* iforce, struct ff_effect* new){	int id = new->id;	struct ff_effect* old = &iforce->core_effects[id].effect;	if (old->direction != new->direction		|| old->trigger.button != new->trigger.button		|| old->trigger.interval != new->trigger.interval		|| old->replay.length != new->replay.length		|| old->replay.delay != new->replay.delay)		return TRUE;	return FALSE;}/* * Send the part common to all effects to the device */static int make_core(struct iforce* iforce, u16 id, u16 mod_id1, u16 mod_id2,	u8 effect_type, u8 axes, u16 duration, u16 delay, u16 button,	u16 interval, u16 direction){	unsigned char data[14];	duration = TIME_SCALE(duration);	delay    = TIME_SCALE(delay);	interval = TIME_SCALE(interval);	data[0]  = LO(id);	data[1]  = effect_type;	data[2]  = LO(axes) | find_button(iforce, button);	data[3]  = LO(duration);	data[4]  = HI(duration);	data[5]  = HI(direction);	data[6]  = LO(interval);	data[7]  = HI(interval);	data[8]  = LO(mod_id1);	data[9]  = HI(mod_id1);	data[10] = LO(mod_id2);	data[11] = HI(mod_id2);	data[12] = LO(delay);	data[13] = HI(delay);	/* Stop effect *//*	iforce_control_playback(iforce, id, 0);*/	iforce_send_packet(iforce, FF_CMD_EFFECT, data);	/* If needed, restart effect */	if (test_bit(FF_CORE_SHOULD_PLAY, iforce->core_effects[id].flags)) {		/* BUG: perhaps we should replay n times, instead of 1. But we do not know n */		iforce_control_playback(iforce, id, 1);	}	return 0;}/* * Upload a periodic effect to the device * See also iforce_upload_constant. */int iforce_upload_periodic(struct iforce* iforce, struct ff_effect* effect, int is_update){	u8 wave_code;	int core_id = effect->id;	struct iforce_core_effect* core_effect = iforce->core_effects + core_id;	struct resource* mod1_chunk = &(iforce->core_effects[core_id].mod1_chunk);	struct resource* mod2_chunk = &(iforce->core_effects[core_id].mod2_chunk);	int param1_err = 1;	int param2_err = 1;	int core_err = 0;	if (!is_update || need_period_modifier(iforce, effect)) {		param1_err = make_period_modifier(iforce, mod1_chunk,			is_update,			effect->u.periodic.magnitude, effect->u.periodic.offset,			effect->u.periodic.period, effect->u.periodic.phase);		if (param1_err) return param1_err;		set_bit(FF_MOD1_IS_USED, core_effect->flags);	}	if (!is_update || need_envelope_modifier(iforce, effect)) {		param2_err = make_envelope_modifier(iforce, mod2_chunk,			is_update,			effect->u.periodic.envelope.attack_length,			effect->u.periodic.envelope.attack_level,			effect->u.periodic.envelope.fade_length,			effect->u.periodic.envelope.fade_level);		if (param2_err) return param2_err;		set_bit(FF_MOD2_IS_USED, core_effect->flags);	}	switch (effect->u.periodic.waveform) {		case FF_SQUARE:		wave_code = 0x20; break;		case FF_TRIANGLE:	wave_code = 0x21; break;		case FF_SINE:		wave_code = 0x22; break;		case FF_SAW_UP:		wave_code = 0x23; break;		case FF_SAW_DOWN:	wave_code = 0x24; break;		default:		wave_code = 0x20; break;	}	if (!is_update || need_core(iforce, effect)) {		core_err = make_core(iforce, effect->id,			mod1_chunk->start,			mod2_chunk->start,			wave_code,			0x20,			effect->replay.length,			effect->replay.delay,			effect->trigger.button,			effect->trigger.interval,			effect->direction);	}	/* If one of the parameter creation failed, we already returned an	 * error code.	 * If the core creation failed, we return its error code.	 * Else: if one parameter at least was created, we return 0	 *       else we return 1;	 */	return core_err < 0 ? core_err : (param1_err && param2_err);}/* * Upload a constant force effect * Return value: *  <0 Error code *  0 Ok, effect created or updated *  1 effect did not change since last upload, and no packet was therefore sent */int iforce_upload_constant(struct iforce* iforce, struct ff_effect* effect, int is_update){	int core_id = effect->id;	struct iforce_core_effect* core_effect = iforce->core_effects + core_id;	struct resource* mod1_chunk = &(iforce->core_effects[core_id].mod1_chunk);	struct resource* mod2_chunk = &(iforce->core_effects[core_id].mod2_chunk);	int param1_err = 1;	int param2_err = 1;	int core_err = 0;	if (!is_update || need_magnitude_modifier(iforce, effect)) {		param1_err = make_magnitude_modifier(iforce, mod1_chunk,			is_update,			effect->u.constant.level);		if (param1_err) return param1_err;		set_bit(FF_MOD1_IS_USED, core_effect->flags);	}	if (!is_update || need_envelope_modifier(iforce, effect)) {		param2_err = make_envelope_modifier(iforce, mod2_chunk,			is_update,			effect->u.constant.envelope.attack_length,			effect->u.constant.envelope.attack_level,			effect->u.constant.envelope.fade_length,			effect->u.constant.envelope.fade_level);		if (param2_err) return param2_err;		set_bit(FF_MOD2_IS_USED, core_effect->flags);	}	if (!is_update || need_core(iforce, effect)) {		core_err = make_core(iforce, effect->id,			mod1_chunk->start,			mod2_chunk->start,			0x00,			0x20,			effect->replay.length,			effect->replay.delay,			effect->trigger.button,			effect->trigger.interval,			effect->direction);	}	/* If one of the parameter creation failed, we already returned an	 * error code.	 * If the core creation failed, we return its error code.	 * Else: if one parameter at least was created, we return 0	 *       else we return 1;	 */	return core_err < 0 ? core_err : (param1_err && param2_err);}/* * Upload an condition effect. Those are for example friction, inertia, springs... */int iforce_upload_condition(struct iforce* iforce, struct ff_effect* effect, int is_update){	int core_id = effect->id;	struct iforce_core_effect* core_effect = iforce->core_effects + core_id;	struct resource* mod1_chunk = &(core_effect->mod1_chunk);	struct resource* mod2_chunk = &(core_effect->mod2_chunk);	u8 type;	int param_err = 1;	int core_err = 0;	switch (effect->type) {		case FF_SPRING:		type = 0x40; break;		case FF_DAMPER:		type = 0x41; break;		default: return -1;	}	if (!is_update || need_condition_modifier(iforce, effect)) {		param_err = make_condition_modifier(iforce, mod1_chunk,			is_update,			effect->u.condition[0].right_saturation,			effect->u.condition[0].left_saturation,			effect->u.condition[0].right_coeff,			effect->u.condition[0].left_coeff,			effect->u.condition[0].deadband,			effect->u.condition[0].center);		if (param_err) return param_err;		set_bit(FF_MOD1_IS_USED, core_effect->flags);		param_err = make_condition_modifier(iforce, mod2_chunk,			is_update,			effect->u.condition[1].right_saturation,			effect->u.condition[1].left_saturation,			effect->u.condition[1].right_coeff,			effect->u.condition[1].left_coeff,			effect->u.condition[1].deadband,			effect->u.condition[1].center);		if (param_err) return param_err;		set_bit(FF_MOD2_IS_USED, core_effect->flags);	}	if (!is_update || need_core(iforce, effect)) {		core_err = make_core(iforce, effect->id,			mod1_chunk->start, mod2_chunk->start,			type, 0xc0,			effect->replay.length, effect->replay.delay,			effect->trigger.button, effect->trigger.interval,			effect->direction);	}	/* If the parameter creation failed, we already returned an	 * error code.	 * If the core creation failed, we return its error code.	 * Else: if a parameter  was created, we return 0	 *       else we return 1;	 */	return core_err < 0 ? core_err : param_err;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -