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 --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
* Thrustmaster Firestorm Dual Power support
* added --name option to set device name
* added JS_${NUM} name to address joystick buttons by number instead
of name
* fixed issue with multiple wireless controller
* some preparation for rumble (prints FF events)
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 ]]
----------------
X11 keysyms might not work correctly in '--ui-buttonmap a=XK_Down'
when Down is mapped to multiple keycodes in the keymap.
X11 keysyms might not work correctly in '--ui-buttonmap a=XK_Foobar'
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 #

39
TODO
View file

@ -5,6 +5,16 @@ Pre Release Testing:
* --dpad-only check that X/Y act properly
* --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:
===============================
@ -17,12 +27,6 @@ Stuff to do before 0.5 release:
* 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
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
3) if not, then use different one, seems to be just 1 or 2
* implement basic rumble force feedback support
1) move force feedback code from uinput into LinuxUinput
fixme:dinput:joy_polldev joystick cannot handle type 21 event (code 0) <- 21 == EV_FF (status report?)
- see ff-memless for effect emulation on rumble
- 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
isn't enough, KEY_SPACE might be)
http://www.immersion.com/developer/downloads/ImmFundamentals/HTML/
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
* add support for LED messages (can this be used by anything?)

View file

@ -29,90 +29,89 @@
#include "evdev_helper.hpp"
#include "linux_uinput.hpp"
std::ostream& operator<<(std::ostream& out, const struct ff_envelope& envelope)
{
out << "attack_length: " << envelope.attack_length
<< " attack_level: " << envelope.attack_level
<< " fade_length: " << envelope.fade_length
<< " fade_level: " << envelope.fade_level;
out << "Envelope(attack_length:" << envelope.attack_length
<< ", attack_level:" << envelope.attack_level
<< ", fade_length:" << envelope.fade_length
<< ", fade_level:" << envelope.fade_level << ")";
return out;
}
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;
}
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;
}
std::ostream& operator<<(std::ostream& out, const struct ff_effect& effect)
{
std::cout << "Effect(";
switch (effect.type)
{
case FF_CONSTANT:
out << "FF_CONSTANT "
<< "level: " << effect.u.constant.level
<< " envelope: { " << effect.u.constant.envelope << " }";
out << "FF_CONSTANT("
<< "level:" << effect.u.constant.level
<< ", envelope:" << effect.u.constant.envelope << ")";
break;
case FF_PERIODIC:
out << "FF_PERIODIC"
<< " waveform: " << effect.u.periodic.waveform
<< " period: " << effect.u.periodic.period
<< " magnitude: " << effect.u.periodic.magnitude
<< " offset: " << effect.u.periodic.offset
<< " phase: " << effect.u.periodic.phase
<< " envelope: { " << effect.u.periodic.envelope << " }";
out << "FF_PERIODIC("
<< ", waveform:" << effect.u.periodic.waveform
<< ", period:" << effect.u.periodic.period
<< ", magnitude:" << effect.u.periodic.magnitude
<< ", offset:" << effect.u.periodic.offset
<< ", phase:" << effect.u.periodic.phase
<< ", envelope:" << effect.u.periodic.envelope << ")";
break;
case FF_RAMP:
out << "FF_RAMP "
<< "start_level: " << effect.u.ramp.start_level
<< "end_level: " << effect.u.ramp.end_level
<< "envelope: { " << effect.u.ramp.envelope << " }";
out << "FF_RAMP("
<< "start_level:" << effect.u.ramp.start_level
<< ", end_level:" << effect.u.ramp.end_level
<< ", envelope:" << effect.u.ramp.envelope << ")";
break;
case FF_SPRING:
out << "FF_SPRING";
out << "FF_SPRING()";
break;
case FF_FRICTION:
out << "FF_FRICTION";
out << "FF_FRICTION()";
break;
case FF_DAMPER:
out << "FF_DAMPER";
out << "FF_DAMPER()";
break;
case FF_RUMBLE:
out << "FF_RUMBLE: "
<< "strong_magnitude: " << effect.u.rumble.strong_magnitude
<< " weak_magnitude: " << effect.u.rumble.weak_magnitude;
out << "FF_RUMBLE("
<< "strong_magnitude:" << effect.u.rumble.strong_magnitude
<< ", weak_magnitude:" << effect.u.rumble.weak_magnitude << ")";
break;
case FF_INERTIA:
out << "FF_INERTIA";
out << "FF_INERTIA()";
break;
case FF_CUSTOM:
out << "FF_CUSTOM";
out << "FF_CUSTOM()";
break;
default:
out << "FF_<unknown>";
out << "FF_<unknown>()";
break;
}
out << "\n";
out << "direction: " << effect.direction << "\n";
out << "replay: " << effect.replay << "\n";
out << "trigger: " << effect.trigger << "\n";
out << ", direction:" << effect.direction
<< ", replay:" << effect.replay
<< ", trigger:" << effect.trigger << ")";
return out;
}
@ -306,7 +305,7 @@ LinuxUinput::update(float delta)
}
else if (ret == sizeof(ev))
{ // 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)
{
@ -319,7 +318,7 @@ LinuxUinput::update(float delta)
break;
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;
case EV_UINPUT:
@ -337,12 +336,11 @@ LinuxUinput::update(float delta)
ioctl(fd, UI_BEGIN_FF_UPLOAD, &upload);
std::cout << "XXX FF_UPLOAD: rumble upload:"
<< " effect_id: " << upload.effect.id
<< " effect_type: " << upload.effect.type
<< std::endl;
std::cout << "EFFECT: " << upload.effect << std::endl;
std::cout << "FF_UPLOAD("
<< "effect_id:" << upload.effect.id
<< ", effect_type:" << upload.effect.type
<< ",\n " << upload.effect
<< ")" << std::endl;
upload.retval = 0;
ioctl(fd, UI_END_FF_UPLOAD, &upload);
@ -361,7 +359,7 @@ LinuxUinput::update(float delta)
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;
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;
break;
}
std::cout << "--------------------------------" << std::endl;
}
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
// do rumble
get_joystick_uinput()->add_ff(FF_RUMBLE);
//get_joystick_uinput()->add_ff(FF_PERIODIC);
// More stuff, only for testing
//get_joystick_uinput()->add_ff(FF_CONSTANT);
//get_joystick_uinput()->add_ff(FF_SPRING);
//get_joystick_uinput()->add_ff(FF_FRICTION);
//get_joystick_uinput()->add_ff(FF_DAMPER);
//get_joystick_uinput()->add_ff(FF_INERTIA);
//get_joystick_uinput()->add_ff(FF_RAMP);
get_joystick_uinput()->add_ff(FF_PERIODIC);
get_joystick_uinput()->add_ff(FF_CONSTANT);
get_joystick_uinput()->add_ff(FF_SPRING);
get_joystick_uinput()->add_ff(FF_FRICTION);
get_joystick_uinput()->add_ff(FF_DAMPER);
get_joystick_uinput()->add_ff(FF_INERTIA);
get_joystick_uinput()->add_ff(FF_RAMP);
get_joystick_uinput()->add_ff(FF_SINE);
}
if (cfg.dpad_only)