📄 iforce-ff.c
字号:
/* * $Id: iforce-ff.c,v 1.9 2002/02/02 19:28:35 jdeneux Exp $ * * Copyright (c) 2000-2002 Vojtech Pavlik <vojtech@ucw.cz> * Copyright (c) 2001-2002 Johann Deneux <deneux@ifrance.com> * * USB/RS232 I-Force joysticks and wheels. *//* * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * Should you need to contact me, the author, you can do so either by * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail: * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic */#include "iforce.h"/* * Set the magnitude of a constant force effect * Return error code * * Note: caller must ensure exclusive access to device */static int make_magnitude_modifier(struct iforce* iforce, struct resource* mod_chunk, int no_alloc, __s16 level){ unsigned char data[3]; if (!no_alloc) { down(&iforce->mem_mutex); if (allocate_resource(&(iforce->device_memory), mod_chunk, 2, iforce->device_memory.start, iforce->device_memory.end, 2L, NULL, NULL)) { up(&iforce->mem_mutex); return -ENOMEM; } up(&iforce->mem_mutex); } data[0] = LO(mod_chunk->start); data[1] = HI(mod_chunk->start); data[2] = HIFIX80(level); iforce_send_packet(iforce, FF_CMD_MAGNITUDE, data); iforce_dump_packet("magnitude: ", FF_CMD_MAGNITUDE, data); return 0;}/* * Upload the component of an effect dealing with the period, phase and magnitude */static int make_period_modifier(struct iforce* iforce, struct resource* mod_chunk, int no_alloc, __s16 magnitude, __s16 offset, u16 period, u16 phase){ unsigned char data[7]; period = TIME_SCALE(period); if (!no_alloc) { down(&iforce->mem_mutex); if (allocate_resource(&(iforce->device_memory), mod_chunk, 0x0c, iforce->device_memory.start, iforce->device_memory.end, 2L, NULL, NULL)) { up(&iforce->mem_mutex); return -ENOMEM; } up(&iforce->mem_mutex); } data[0] = LO(mod_chunk->start); data[1] = HI(mod_chunk->start); data[2] = HIFIX80(magnitude); data[3] = HIFIX80(offset); data[4] = HI(phase); data[5] = LO(period); data[6] = HI(period); iforce_send_packet(iforce, FF_CMD_PERIOD, data); return 0;}/* * Uploads the part of an effect setting the envelope of the force */static int make_envelope_modifier(struct iforce* iforce, struct resource* mod_chunk, int no_alloc, u16 attack_duration, __s16 initial_level, u16 fade_duration, __s16 final_level){ unsigned char data[8]; attack_duration = TIME_SCALE(attack_duration); fade_duration = TIME_SCALE(fade_duration); if (!no_alloc) { down(&iforce->mem_mutex); if (allocate_resource(&(iforce->device_memory), mod_chunk, 0x0e, iforce->device_memory.start, iforce->device_memory.end, 2L, NULL, NULL)) { up(&iforce->mem_mutex); return -ENOMEM; } up(&iforce->mem_mutex); } data[0] = LO(mod_chunk->start); data[1] = HI(mod_chunk->start); data[2] = LO(attack_duration); data[3] = HI(attack_duration); data[4] = HI(initial_level); data[5] = LO(fade_duration); data[6] = HI(fade_duration); data[7] = HI(final_level); iforce_send_packet(iforce, FF_CMD_ENVELOPE, data); return 0;}/* * Component of spring, friction, inertia... effects */static int make_condition_modifier(struct iforce* iforce, struct resource* mod_chunk, int no_alloc, __u16 rsat, __u16 lsat, __s16 rk, __s16 lk, u16 db, __s16 center){ unsigned char data[10]; if (!no_alloc) { down(&iforce->mem_mutex); if (allocate_resource(&(iforce->device_memory), mod_chunk, 8, iforce->device_memory.start, iforce->device_memory.end, 2L, NULL, NULL)) { up(&iforce->mem_mutex); return -ENOMEM; } up(&iforce->mem_mutex); } data[0] = LO(mod_chunk->start); data[1] = HI(mod_chunk->start); data[2] = (100*rk)>>15; /* Dangerous: the sign is extended by gcc on plateforms providing an arith shift */ data[3] = (100*lk)>>15; /* This code is incorrect on cpus lacking arith shift */ center = (500*center)>>15; data[4] = LO(center); data[5] = HI(center); db = (1000*db)>>16; data[6] = LO(db); data[7] = HI(db); data[8] = (100*rsat)>>16; data[9] = (100*lsat)>>16; iforce_send_packet(iforce, FF_CMD_CONDITION, data); iforce_dump_packet("condition", FF_CMD_CONDITION, data); return 0;}static unsigned char find_button(struct iforce *iforce, signed short button){ int i; for (i = 1; iforce->type->btn[i] >= 0; i++) if (iforce->type->btn[i] == button) return i + 1; return 0;}/* * Analyse the changes in an effect, and tell if we need to send an condition * parameter packet */static int need_condition_modifier(struct iforce* iforce, struct ff_effect* new){ int id = new->id; struct ff_effect* old = &iforce->core_effects[id].effect; int ret=0; int i; if (new->type != FF_SPRING && new->type != FF_FRICTION) { printk(KERN_WARNING "iforce.c: bad effect type in need_condition_modifier\n"); return FALSE; } for(i=0; i<2; i++) { ret |= old->u.condition[i].right_saturation != new->u.condition[i].right_saturation || old->u.condition[i].left_saturation != new->u.condition[i].left_saturation || old->u.condition[i].right_coeff != new->u.condition[i].right_coeff || old->u.condition[i].left_coeff != new->u.condition[i].left_coeff || old->u.condition[i].deadband != new->u.condition[i].deadband || old->u.condition[i].center != new->u.condition[i].center; } return ret;}/* * Analyse the changes in an effect, and tell if we need to send a magnitude * parameter packet */static int need_magnitude_modifier(struct iforce* iforce, struct ff_effect* effect){ int id = effect->id; struct ff_effect* old = &iforce->core_effects[id].effect; if (effect->type != FF_CONSTANT) { printk(KERN_WARNING "iforce.c: bad effect type in need_envelope_modifier\n"); return FALSE; } return (old->u.constant.level != effect->u.constant.level);}/* * Analyse the changes in an effect, and tell if we need to send an envelope * parameter packet */static int need_envelope_modifier(struct iforce* iforce, struct ff_effect* effect){ int id = effect->id; struct ff_effect* old = &iforce->core_effects[id].effect; switch (effect->type) { case FF_CONSTANT: if (old->u.constant.envelope.attack_length != effect->u.constant.envelope.attack_length || old->u.constant.envelope.attack_level != effect->u.constant.envelope.attack_level || old->u.constant.envelope.fade_length != effect->u.constant.envelope.fade_length || old->u.constant.envelope.fade_level != effect->u.constant.envelope.fade_level) return TRUE; break; case FF_PERIODIC: if (old->u.periodic.envelope.attack_length != effect->u.periodic.envelope.attack_length || old->u.periodic.envelope.attack_level != effect->u.periodic.envelope.attack_level || old->u.periodic.envelope.fade_length != effect->u.periodic.envelope.fade_length || old->u.periodic.envelope.fade_level != effect->u.periodic.envelope.fade_level) return TRUE; break; default: printk(KERN_WARNING "iforce.c: bad effect type in need_envelope_modifier\n"); } return FALSE;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -