Added special meaning to a REL repeat value of -1, it means that the event will be send on each update(), thus leading to syncronized REL events, fixing the jitter issues with the old code

This commit is contained in:
Ingo Ruhnke 2011-03-09 08:15:25 +01:00
parent 935fd6db17
commit 03e8abc0ed
6 changed files with 70 additions and 31 deletions

40
TODO
View file

@ -42,7 +42,36 @@ $ dput my-ppa ../xboxdrv_0.7.3-1~lucid1_source.changes
Stuff to do before 0.7.3 release:
=================================
== Daemon ==
* check how daemon reacts on suspend
- suspending the computer leads to LIBUSB_ERROR_IO, unplugging the
controller leads to LIBUSB_ERROR_OTHER
-> couldn't be replicated, both give LIBUSB_ERROR_OTHER
- errno is set to EBUSY
- the device handle can't be reused, device has to be reallocated
- integrate this with the "keep backlog of devices currently in use"
* do something with stdout/stderr when its run in --detach mode
== Other ==
* mouse emulation is very jaggy (try painting in Gimp), caused by
REL_X and REL_Y being send independently, while they should be
synced up, this is a side-effect of the deadzone, without deadzone,
no jaggies
-> UInput::send_rel_repetitive() needs to syncronize all REL events
with the same repeat interval whenever a new event comes in
send_val = value * time_count / repeat;
time_count = 0;
-> add a repeat timeout 0 that sends on each update
* multiple ControllerThread lead to UInput::update() being called
multiple times, as UInputMessageProcessor does call the update()
which is wrong
== Unsolved/WontFix ==
@ -64,7 +93,6 @@ Stuff to do before 0.7.3 release:
results in confusing behaviour
* glib/D-Bus causes crash/exit when USBController::get_name() returns an invalid unicode string?!
* move sigint/sigterm handling out of main.cpp and into xboxdrv_daemon.cpp (needs to use gmain_quit())
@ -79,16 +107,6 @@ Stuff to do before 0.7.3 release:
-> figure out how exactly device names are choosen (first free or
are there other means? need to take special axes/buttons into account)
== Daemon ==
* check how daemon reacts on suspend
- suspending the computer leads to LIBUSB_ERROR_IO, unplugging the
controller leads to LIBUSB_ERROR_OTHER
-> couldn't be replicated, both give LIBUSB_ERROR_OTHER
- errno is set to EBUSY
- the device handle can't be reused, device has to be reallocated
- integrate this with the "keep backlog of devices currently in use"
== Daemon ==

View file

@ -9,7 +9,6 @@
# button.
[xboxdrv]
deadzone=4000 # to avoid cursor jitter we use a deadzone
trigger-as-zaxis=true # both triggers acts as single axis
dpad-as-button=true # easier to map the dpad as buttons
@ -19,10 +18,10 @@ dpad-as-button=true # easier to map the dpad as buttons
-trigger=trigger
[ui-axismap]
x1=REL_X:15:20
y1=REL_Y:15:20
y2=REL_WHEEL:5:100
x2=REL_HWHEEL:5:100
x1^dead:4000 = REL_X:750:-1
y1^dead:4000 = REL_Y:750:-1
y2^dead:8000 = REL_WHEEL:5:100
x2^dead:8000 = REL_HWHEEL:5:100
trigger=REL_WHEEL:5:100
[ui-buttonmap]

View file

@ -193,7 +193,7 @@ RelAxisEventHandler::from_string(const std::string& str)
break;
case 1:
ev->m_value = boost::lexical_cast<int>(*i);
ev->m_value = boost::lexical_cast<float>(*i);
break;
case 2:
@ -216,14 +216,18 @@ RelAxisEventHandler::from_string(const std::string& str)
RelAxisEventHandler::RelAxisEventHandler() :
m_code(UIEvent::invalid()),
m_value(5),
m_repeat(10)
m_repeat(10),
m_stick_value(0.0f),
m_rest_value(0.0f)
{
}
RelAxisEventHandler::RelAxisEventHandler(int device_id, int code, int repeat, float value) :
m_code(UIEvent::create(device_id, EV_REL, code)),
m_value(value),
m_repeat(repeat)
m_repeat(repeat),
m_stick_value(0.0f),
m_rest_value(0.0f)
{
}
@ -237,23 +241,38 @@ RelAxisEventHandler::init(UInput& uinput, int slot, bool extra_devices)
void
RelAxisEventHandler::send(UInput& uinput, int value)
{
float value_f;
if (value < 0)
value_f = static_cast<float>(value) / static_cast<float>(-m_min);
m_stick_value = value / static_cast<float>(-m_min);
else
value_f = static_cast<float>(value) / static_cast<float>(m_max);
m_stick_value = value / static_cast<float>(m_max);
float v = m_value * value_f;
if (m_repeat != -1)
{
// regular old style sending of REL events
float v = m_value * m_stick_value;
if (v == 0)
uinput.send_rel_repetitive(m_code, v, -1);
else
uinput.send_rel_repetitive(m_code, v, m_repeat);
if (v == 0)
uinput.send_rel_repetitive(m_code, v, -1);
else
uinput.send_rel_repetitive(m_code, v, m_repeat);
}
}
void
RelAxisEventHandler::update(UInput& uinput, int msec_delta)
{
if (m_repeat == -1 && m_stick_value != 0.0f)
{
// new and improved REL style event sending
float rel_value = m_stick_value * m_value * static_cast<float>(msec_delta) / 1000.0f;
// keep track of the rest that we lose when converting to integer
rel_value += m_rest_value;
m_rest_value = rel_value - truncf(rel_value);
uinput.send_rel(m_code.get_device_id(), m_code.code, static_cast<int>(rel_value));
}
}
std::string

View file

@ -100,8 +100,11 @@ public:
private:
UIEvent m_code;
float m_value; // FIXME: Why is this float?
int m_repeat;
float m_value;
int m_repeat;
float m_stick_value;
float m_rest_value;
};
class AbsAxisEventHandler : public AxisEventHandler

View file

@ -359,7 +359,7 @@ UInput::send_key(uint32_t device_id, int ev_code, bool value)
}
void
Uinput::send_rel(uint32_t device_id, int ev_code, bool value)
UInput::send_rel(uint32_t device_id, int ev_code, int value)
{
assert(ev_code != -1);
get_uinput(device_id)->send(EV_REL, ev_code, value);

View file

@ -100,7 +100,7 @@ public:
void send(uint32_t device_id, int ev_type, int ev_code, int value);
void send_abs(uint32_t device_id, int ev_code, int value);
void send_key(uint32_t device_id, int ev_code, bool value);
void send_rel(uint32_t device_id, int ev_code, bool value);
void send_rel(uint32_t device_id, int ev_code, int value);
void send_rel_repetitive(const UIEvent& code, float value, int repeat_interval);
/** should be called to single that all events of the current frame