Improved force feedback print output, release updates

This commit is contained in:
Ingo Ruhnke 2009-01-17 06:31:14 +01:00
parent 82af020325
commit ade5823276
5 changed files with 91 additions and 73 deletions

7
NEWS
View file

@ -1,13 +1,16 @@
xboxdrv 0.4.3 - (??/Jan/2009) xboxdrv 0.4.3 - (17/Jan/2009)
============================= =============================
* added support for X11 keysym in --ui-buttonmap * added support for X11 keysym in --ui-buttonmap
* added --ui-clear and void mappings to unmap buttons and axis * added --ui-clear and 'void' mappings to unmap buttons and axis
* fixed LED handling for wireless gamepads * fixed LED handling for wireless gamepads
* Thrustmaster Firestorm Dual Power support * Thrustmaster Firestorm Dual Power support
* added --name option to set device name * added --name option to set device name
* added JS_${NUM} name to address joystick buttons by number instead * added JS_${NUM} name to address joystick buttons by number instead
of name of name
* fixed issue with multiple wireless controller
* some preparation for rumble (prints FF events)
xboxdrv 0.4.2 - (11/Jan/2009) xboxdrv 0.4.2 - (11/Jan/2009)
============================= =============================

15
README
View file

@ -653,8 +653,19 @@ Force feedback is provided via the standard kernel ff interface:
[[ Known bugs ]] [[ Known bugs ]]
---------------- ----------------
X11 keysyms might not work correctly in '--ui-buttonmap a=XK_Down' X11 keysyms might not work correctly in '--ui-buttonmap a=XK_Foobar'
when Down is mapped to multiple keycodes in the keymap. when Foobar is mapped to multiple keycodes in the keymap.
Workaround: Use KEY_ instead or cleanup your keymap
Force feedback support is brittle, if you Ctrl-c the driver in the
wrong moment you will end up with a dead uninterruptable process and
basically have to reboot. This looks might a kernel issue and not a
xboxdrv one.
Workaround: Kill the app that uses xboxdrv before xboxdrv itself.
# EOF # # EOF #

39
TODO
View file

@ -5,6 +5,16 @@ Pre Release Testing:
* --dpad-only check that X/Y act properly * --dpad-only check that X/Y act properly
* --dpad-as-button check buttons are working and no useless axis present * --dpad-as-button check buttons are working and no useless axis present
TAG=0.4.2
git tag ${TAG}
git-archive --format=tar --prefix="xboxdrv-linux-${TAG}/" ${TAG} | bzip2 -c > /tmp/xboxdrv-linux-${TAG}.tar.bz2
git push --tags
Stuff to do before 0.4.3 release:
=================================
* improve force feedback output a little bit
Stuff to do before 0.5 release: Stuff to do before 0.5 release:
=============================== ===============================
@ -17,12 +27,6 @@ Stuff to do before 0.5 release:
* add a way to not create a joystick/event device * add a way to not create a joystick/event device
* report more precisly what devices got created, include device name (HAL has that information)
* display ui-buttonmap in the configuration overview, tricky since we
don't differ between default bindings and user created ones, also
which bindings get used depends on other configuration options
* figure out what jscal does and if it can break stuff * figure out what jscal does and if it can break stuff
1) jscal uses the joystick interface, not the event interface 1) jscal uses the joystick interface, not the event interface
@ -31,24 +35,29 @@ Stuff to do before 0.5 release:
2) check if endpoints are available on start 2) check if endpoints are available on start
3) if not, then use different one, seems to be just 1 or 2 3) if not, then use different one, seems to be just 1 or 2
* implement basic rumble force feedback support * implement basic rumble force feedback support
1) move force feedback code from uinput into LinuxUinput - see ff-memless for effect emulation on rumble
fixme:dinput:joy_polldev joystick cannot handle type 21 event (code 0) <- 21 == EV_FF (status report?)
- handle FF status report - handle FF status report
http://www.immersion.com/developer/downloads/ImmFundamentals/HTML/
fixme:dinput:joy_polldev joystick cannot handle type 21 event (code 0) <- 21 == EV_FF (status report?)
* figure out which devices xorg/hal handles as keyboard (just a button http://www.immersion.com/developer/downloads/ImmFundamentals/HTML/
isn't enough, KEY_SPACE might be)
Later versions: Later versions:
=============== ===============
* figure out which devices xorg/hal handles as keyboard and how to
make it always happen, seems to require two keyboard keys, devices
with only one aren't registered
* display ui-buttonmap in the configuration overview, tricky since we
don't differ between default bindings and user created ones, also
which bindings get used depends on other configuration options
* report more precisly what devices got created, include device name (HAL has that information)
* write a daemon that listens to HAL and automatically starts xboxdrv * write a daemon that listens to HAL and automatically starts xboxdrv
* add support for LED messages (can this be used by anything?) * add support for LED messages (can this be used by anything?)

View file

@ -29,90 +29,89 @@
#include "evdev_helper.hpp" #include "evdev_helper.hpp"
#include "linux_uinput.hpp" #include "linux_uinput.hpp"
std::ostream& operator<<(std::ostream& out, const struct ff_envelope& envelope) std::ostream& operator<<(std::ostream& out, const struct ff_envelope& envelope)
{ {
out << "attack_length: " << envelope.attack_length out << "Envelope(attack_length:" << envelope.attack_length
<< " attack_level: " << envelope.attack_level << ", attack_level:" << envelope.attack_level
<< " fade_length: " << envelope.fade_length << ", fade_length:" << envelope.fade_length
<< " fade_level: " << envelope.fade_level; << ", fade_level:" << envelope.fade_level << ")";
return out; return out;
} }
std::ostream& operator<<(std::ostream& out, const struct ff_replay& replay) std::ostream& operator<<(std::ostream& out, const struct ff_replay& replay)
{ {
out << "length: " << replay.length << " delay: " << replay.delay; out << "Replay(length:" << replay.length << ", delay:" << replay.delay << ")";
return out; return out;
} }
std::ostream& operator<<(std::ostream& out, const struct ff_trigger& trigger) std::ostream& operator<<(std::ostream& out, const struct ff_trigger& trigger)
{ {
out << "button: " << trigger.button << " interval: " << trigger.interval; out << "Trigger(button:" << trigger.button << ", interval:" << trigger.interval << ")";
return out; return out;
} }
std::ostream& operator<<(std::ostream& out, const struct ff_effect& effect) std::ostream& operator<<(std::ostream& out, const struct ff_effect& effect)
{ {
std::cout << "Effect(";
switch (effect.type) switch (effect.type)
{ {
case FF_CONSTANT: case FF_CONSTANT:
out << "FF_CONSTANT " out << "FF_CONSTANT("
<< "level: " << effect.u.constant.level << "level:" << effect.u.constant.level
<< " envelope: { " << effect.u.constant.envelope << " }"; << ", envelope:" << effect.u.constant.envelope << ")";
break; break;
case FF_PERIODIC: case FF_PERIODIC:
out << "FF_PERIODIC" out << "FF_PERIODIC("
<< " waveform: " << effect.u.periodic.waveform << ", waveform:" << effect.u.periodic.waveform
<< " period: " << effect.u.periodic.period << ", period:" << effect.u.periodic.period
<< " magnitude: " << effect.u.periodic.magnitude << ", magnitude:" << effect.u.periodic.magnitude
<< " offset: " << effect.u.periodic.offset << ", offset:" << effect.u.periodic.offset
<< " phase: " << effect.u.periodic.phase << ", phase:" << effect.u.periodic.phase
<< " envelope: { " << effect.u.periodic.envelope << " }"; << ", envelope:" << effect.u.periodic.envelope << ")";
break; break;
case FF_RAMP: case FF_RAMP:
out << "FF_RAMP " out << "FF_RAMP("
<< "start_level: " << effect.u.ramp.start_level << "start_level:" << effect.u.ramp.start_level
<< "end_level: " << effect.u.ramp.end_level << ", end_level:" << effect.u.ramp.end_level
<< "envelope: { " << effect.u.ramp.envelope << " }"; << ", envelope:" << effect.u.ramp.envelope << ")";
break; break;
case FF_SPRING: case FF_SPRING:
out << "FF_SPRING"; out << "FF_SPRING()";
break; break;
case FF_FRICTION: case FF_FRICTION:
out << "FF_FRICTION"; out << "FF_FRICTION()";
break; break;
case FF_DAMPER: case FF_DAMPER:
out << "FF_DAMPER"; out << "FF_DAMPER()";
break; break;
case FF_RUMBLE: case FF_RUMBLE:
out << "FF_RUMBLE: " out << "FF_RUMBLE("
<< "strong_magnitude: " << effect.u.rumble.strong_magnitude << "strong_magnitude:" << effect.u.rumble.strong_magnitude
<< " weak_magnitude: " << effect.u.rumble.weak_magnitude; << ", weak_magnitude:" << effect.u.rumble.weak_magnitude << ")";
break; break;
case FF_INERTIA: case FF_INERTIA:
out << "FF_INERTIA"; out << "FF_INERTIA()";
break; break;
case FF_CUSTOM: case FF_CUSTOM:
out << "FF_CUSTOM"; out << "FF_CUSTOM()";
break; break;
default: default:
out << "FF_<unknown>"; out << "FF_<unknown>()";
break; break;
} }
out << "\n"; out << ", direction:" << effect.direction
out << "direction: " << effect.direction << "\n"; << ", replay:" << effect.replay
out << "replay: " << effect.replay << "\n"; << ", trigger:" << effect.trigger << ")";
out << "trigger: " << effect.trigger << "\n";
return out; return out;
} }
@ -306,7 +305,7 @@ LinuxUinput::update(float delta)
} }
else if (ret == sizeof(ev)) else if (ret == sizeof(ev))
{ // successful read { // successful read
std::cout << "type: " << ev.type << " code: " << ev.code << " value: " << ev.value << std::endl; //std::cout << "type: " << ev.type << " code: " << ev.code << " value: " << ev.value << std::endl;
switch(ev.type) switch(ev.type)
{ {
@ -319,7 +318,7 @@ LinuxUinput::update(float delta)
break; break;
case EV_FF: case EV_FF:
std::cout << "EV_FF: playing effect: effect_id = " << ev.code << " value: " << ev.value << std::endl; std::cout << "FFPlay(effect_id:" << ev.code << ", value:" << ev.value << ")" << std::endl;
break; break;
case EV_UINPUT: case EV_UINPUT:
@ -337,12 +336,11 @@ LinuxUinput::update(float delta)
ioctl(fd, UI_BEGIN_FF_UPLOAD, &upload); ioctl(fd, UI_BEGIN_FF_UPLOAD, &upload);
std::cout << "XXX FF_UPLOAD: rumble upload:" std::cout << "FF_UPLOAD("
<< " effect_id: " << upload.effect.id << "effect_id:" << upload.effect.id
<< " effect_type: " << upload.effect.type << ", effect_type:" << upload.effect.type
<< std::endl; << ",\n " << upload.effect
std::cout << "EFFECT: " << upload.effect << std::endl; << ")" << std::endl;
upload.retval = 0; upload.retval = 0;
ioctl(fd, UI_END_FF_UPLOAD, &upload); ioctl(fd, UI_END_FF_UPLOAD, &upload);
@ -361,7 +359,7 @@ LinuxUinput::update(float delta)
ioctl(fd, UI_BEGIN_FF_ERASE, &erase); ioctl(fd, UI_BEGIN_FF_ERASE, &erase);
std::cout << "FF_ERASE: rumble erase: effect_id = " << erase.effect_id << std::endl; std::cout << "FF_ERASE(effect_id:" << erase.effect_id << ")" << std::endl;
erase.retval = 0; erase.retval = 0;
ioctl(fd, UI_END_FF_ERASE, &erase); ioctl(fd, UI_END_FF_ERASE, &erase);
@ -378,7 +376,6 @@ LinuxUinput::update(float delta)
std::cout << "Unhandled event type read: " << ev.type << std::endl; std::cout << "Unhandled event type read: " << ev.type << std::endl;
break; break;
} }
std::cout << "--------------------------------" << std::endl;
} }
else else
{ {

View file

@ -386,16 +386,14 @@ uInput::setup_xbox360_gamepad(GamepadType type)
// Not sure how much we should support, for the moment we only // Not sure how much we should support, for the moment we only
// do rumble // do rumble
get_joystick_uinput()->add_ff(FF_RUMBLE); get_joystick_uinput()->add_ff(FF_RUMBLE);
get_joystick_uinput()->add_ff(FF_PERIODIC);
//get_joystick_uinput()->add_ff(FF_PERIODIC); get_joystick_uinput()->add_ff(FF_CONSTANT);
get_joystick_uinput()->add_ff(FF_SPRING);
// More stuff, only for testing get_joystick_uinput()->add_ff(FF_FRICTION);
//get_joystick_uinput()->add_ff(FF_CONSTANT); get_joystick_uinput()->add_ff(FF_DAMPER);
//get_joystick_uinput()->add_ff(FF_SPRING); get_joystick_uinput()->add_ff(FF_INERTIA);
//get_joystick_uinput()->add_ff(FF_FRICTION); get_joystick_uinput()->add_ff(FF_RAMP);
//get_joystick_uinput()->add_ff(FF_DAMPER); get_joystick_uinput()->add_ff(FF_SINE);
//get_joystick_uinput()->add_ff(FF_INERTIA);
//get_joystick_uinput()->add_ff(FF_RAMP);
} }
if (cfg.dpad_only) if (cfg.dpad_only)