[RFC 4/11] Linux FF: Linux effect parameter: periodic effect's phase
Elias Vanderstuyft
elias.vds at gmail.com
Tue Mar 4 13:20:01 CST 2014
a) Periodic phase is not implemented conform most efficient
implementations of linux FF-devices:
phase should be related to time, not to angle:
- HW interface example: In /drivers/input/joystick/iforce/iforce-ff.c :
make_period_modifier(...): "iforce_send_packet(iforce,
FF_CMD_PERIOD, data)" where data[4] = HI(phase);
make_core(...): "iforce_send_packet(iforce, FF_CMD_EFFECT,
data)" where data[4] = HI(duration);
=> Conclusion: phase likely to be related to time, not to angle
- SW kernel interface example, which is going to be used for all
memless FF devices in the future:
(http://permalink.gmane.org/gmane.linux.kernel/1620326) in
ff-memless-next.c:149 :
mlnxeff->playback_time = effect->u.periodic.phase
- SW interface example: SDL2-2.0.1/src/haptic/linux/SDL_syshaptic.c:640
There is also written on /include/uapi/linux/input.h:1058 :
"@phase: 'horizontal' shift"
where 'horizontal' most likely means time dimension, not phase
of the waveform.
=> To be sure, I asked this at
http://www.mail-archive.com/[email protected]/msg08459.html,
but didn't receive any answer yet.
So change the following in dinput/effect_linuxinput.c:259 :
tsp->lOffset = (This->effect.u.periodic.offset / 33) * 10;
tsp->dwPhase = (This->effect.u.periodic.phase / 33) * 36;
tsp->dwPeriod = (This->effect.u.periodic.period * 1000);
to :
tsp->lOffset = (This->effect.u.periodic.offset / 33) * 10;
if (!This->effect.u.periodic.period) {
/* Avoid division by zero period, set tsp->dwPhase
arbitrarily to zero. */
tsp->dwPhase = 0;
} else
tsp->dwPhase = (((int)This->effect.u.periodic.phase *
36000) / This->effect.u.periodic.period) % 36000;
tsp->dwPeriod = (This->effect.u.periodic.period * 1000);
and change the following in dinput/effect_linuxinput.c:486 :
This->effect.u.periodic.offset = (tsp->lOffset / 10) * 32;
This->effect.u.periodic.phase = (tsp->dwPhase / 9) * 8; /* ==
(/ 36 * 32) */
This->effect.u.periodic.period = tsp->dwPeriod / 1000;
to :
This->effect.u.periodic.offset = (tsp->lOffset / 10) * 32;
This->effect.u.periodic.period = tsp->dwPeriod / 1000;
This->effect.u.periodic.phase = ((int)(tsp->dwPhase % 36000) *
This->effect.u.periodic.period) / 36000;
Elias
-------------- next part --------------
///////////////////////////// Linux effect parameter: periodic effect's phase /////////////////////////////
a) Periodic phase is not implemented conform most efficient implementations of linux FF-devices:
phase should be related to time, not to angle:
- HW interface example: In /drivers/input/joystick/iforce/iforce-ff.c :
make_period_modifier(...): "iforce_send_packet(iforce, FF_CMD_PERIOD, data)" where data[4] = HI(phase);
make_core(...): "iforce_send_packet(iforce, FF_CMD_EFFECT, data)" where data[4] = HI(duration);
=> Conclusion: phase likely to be related to time, not to angle
- SW kernel interface example, which is going to be used for all memless FF devices in the future:
(http://permalink.gmane.org/gmane.linux.kernel/1620326) in ff-memless-next.c:149 :
mlnxeff->playback_time = effect->u.periodic.phase
- SW interface example: SDL2-2.0.1/src/haptic/linux/SDL_syshaptic.c:640
There is also written on /include/uapi/linux/input.h:1058 :
"@phase: 'horizontal' shift"
where 'horizontal' most likely means time dimension, not phase of the waveform.
=> To be sure, I asked this at http://www.mail-archive.com/[email protected]/msg08459.html,
but didn't receive any answer yet.
So change the following in dinput/effect_linuxinput.c:259 :
tsp->lOffset = (This->effect.u.periodic.offset / 33) * 10;
tsp->dwPhase = (This->effect.u.periodic.phase / 33) * 36;
tsp->dwPeriod = (This->effect.u.periodic.period * 1000);
to :
tsp->lOffset = (This->effect.u.periodic.offset / 33) * 10;
if (!This->effect.u.periodic.period) {
/* Avoid division by zero period, set tsp->dwPhase arbitrarily to zero. */
tsp->dwPhase = 0;
} else
tsp->dwPhase = (((int)This->effect.u.periodic.phase * 36000) / This->effect.u.periodic.period) % 36000;
tsp->dwPeriod = (This->effect.u.periodic.period * 1000);
and change the following in dinput/effect_linuxinput.c:486 :
This->effect.u.periodic.offset = (tsp->lOffset / 10) * 32;
This->effect.u.periodic.phase = (tsp->dwPhase / 9) * 8; /* == (/ 36 * 32) */
This->effect.u.periodic.period = tsp->dwPeriod / 1000;
to :
This->effect.u.periodic.offset = (tsp->lOffset / 10) * 32;
This->effect.u.periodic.period = tsp->dwPeriod / 1000;
This->effect.u.periodic.phase = ((int)(tsp->dwPhase % 36000) * This->effect.u.periodic.period) / 36000;
More information about the wine-devel
mailing list