From eab5a0f231ec75dc112f79e30e768f4f296f2848 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stephan=20A=C3=9Fmus?= Date: Sun, 2 Nov 2008 19:43:08 +0000 Subject: [PATCH] Experimented with the way the absolute touchpad coordinates are translated into relative mouse movements. Removed the "history" and replaced it with a method to accumulate the deltas. Very small deltas are somewhat suppressed, but still accumulate. Overall, this improves the touchpad sensitivity for small movements without introducing unwanted jitter. This also keeps the direction of slightly "non-straight" movements better. I also changed the scale somewhat so that the acceleration does not feel too little anymore. These are the remaining problems I have: * Tap-clicks are sometimes not recognized * releasing the finger from the pad (which is pressure sensitive) sometimes still injects unwanted mouse movement, which may be possible to be supressed when looking at the pressure change and recognizing the release. * scrolling has changed a bit due to my changes and feels a bit too sensitive now Please check it out if you like (ps2_dev.c:105) and tell me what you think. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@28468 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- .../kernel/bus_managers/ps2/movement_maker.c | 90 ++++++++++++------- .../kernel/bus_managers/ps2/movement_maker.h | 10 +-- 2 files changed, 62 insertions(+), 38 deletions(-) diff --git a/src/add-ons/kernel/bus_managers/ps2/movement_maker.c b/src/add-ons/kernel/bus_managers/ps2/movement_maker.c index 99714d200c..3729648ce9 100644 --- a/src/add-ons/kernel/bus_managers/ps2/movement_maker.c +++ b/src/add-ons/kernel/bus_managers/ps2/movement_maker.c @@ -176,43 +176,62 @@ make_small(float value) void get_raw_movement(movement_maker *move, uint32 posX, uint32 posY) { - int16 i; - float meanXOld = 0, meanYOld = 0; - float meanX = 0, meanY = 0; + int diff; + float xDelta, yDelta; + const float acceleration = 0.7; - // calculate mean - for (i = 0; i < move->n_points; i++) { - meanXOld += move->historyX[i]; - meanYOld += move->historyY[i]; - } - if (move->n_points == 0) { - meanXOld = posX; - meanYOld = posY; - } else { - meanXOld = meanXOld / move->n_points; - meanYOld = meanYOld / move->n_points; + if (move->movementStarted) { + move->movementStarted = false; + // init delta tracking + move->previousX = posX; + move->previousY = posY; + // deltas are automatically reset } - meanX = (meanXOld + posX) / 2; - meanY = (meanYOld + posY) / 2; + // accumulate delta and store current pos, reset if pos did not change + diff = posX - move->previousX; + // lessen the effect of small diffs + if ((diff > -3 && diff < -1) || (diff > 1 && diff < 3)) + diff /= 2; + if (diff == 0) + move->deltaSumX = 0.0; + else + move->deltaSumX += diff; - // fill history - for (i = 0; i < HISTORY_SIZE - 1; i++) { - move->historyX[i] = move->historyX[i + 1]; - move->historyY[i] = move->historyY[i + 1]; - } - move->historyX[HISTORY_SIZE - 1] = meanX; - move->historyY[HISTORY_SIZE - 1] = meanY; + diff = posY - move->previousY; + // lessen the effect of small diffs + if ((diff > -3 && diff < -1) || (diff > 1 && diff < 3)) + diff /= 2; + if (diff == 0) + move->deltaSumY = 0.0; + else + move->deltaSumY += diff; - if (move->n_points < HISTORY_SIZE) { - move->n_points++; - move->xDelta = 0; - move->yDelta = 0; - return; + move->previousX = posX; + move->previousY = posY; + + // compute current delta and reset accumulated delta if + // abs() is greater than 1 + xDelta = move->deltaSumX / 10.0; + yDelta = move->deltaSumY / 10.0; + if (xDelta > 1.0) { + move->deltaSumX = 0.0; + xDelta = 1.0 + (xDelta - 1.0) * acceleration; + } else if (xDelta < -1.0) { + move->deltaSumX = 0.0; + xDelta = -1.0 + (xDelta + 1.0) * acceleration; } - move->xDelta = make_small((meanX - meanXOld) / 16); - move->yDelta = make_small((meanY - meanYOld) / 16); + if (yDelta > 1.0) { + move->deltaSumY = 0.0; + yDelta = 1.0 + (yDelta - 1.0) * acceleration; + } else if (yDelta < -1.0) { + move->deltaSumY = 0.0; + yDelta = -1.0 + (yDelta + 1.0) * acceleration; + } + + move->xDelta = make_small(xDelta); + move->yDelta = make_small(yDelta); } @@ -235,6 +254,11 @@ void get_movement(movement_maker *move, uint32 posX, uint32 posY) { get_raw_movement(move, posX, posY); + + INFO("SYN: pos: %lu x %lu, delta: %ld x %ld, sums: %ld x %ld\n", + posX, posY, move->xDelta, move->yDelta, + move->deltaSumX, move->deltaSumY); + move->xDelta = move->xDelta * move->speed; move->yDelta = move->yDelta * move->speed; } @@ -248,8 +272,8 @@ get_scrolling(movement_maker *move, uint32 posX, uint32 posY) get_raw_movement(move, posX, posY); compute_acceleration(move, move->scroll_acceleration); - move->scrolling_x+= move->xDelta; - move->scrolling_y+= move->yDelta; + move->scrolling_x += move->xDelta; + move->scrolling_y += move->yDelta; stepsX = make_small(move->scrolling_x / move->scrolling_xStep); stepsY = make_small(move->scrolling_y / move->scrolling_yStep); @@ -270,7 +294,7 @@ start_new_movment(movement_maker *move) if (move->scrolling_yStep <= 0) move->scrolling_yStep = 1; - move->n_points = 0; + move->movementStarted = true; move->scrolling_x = 0; move->scrolling_y = 0; } diff --git a/src/add-ons/kernel/bus_managers/ps2/movement_maker.h b/src/add-ons/kernel/bus_managers/ps2/movement_maker.h index 0417755a7d..a9dd6c4030 100644 --- a/src/add-ons/kernel/bus_managers/ps2/movement_maker.h +++ b/src/add-ons/kernel/bus_managers/ps2/movement_maker.h @@ -4,8 +4,6 @@ #include -#define HISTORY_SIZE 1 - float floorf(float x); float ceilf(float x); float sqrtf(float x); @@ -24,9 +22,11 @@ typedef struct { int32 scrolling_yStep; int32 scroll_acceleration; - uint8 n_points; - float historyX[HISTORY_SIZE]; - float historyY[HISTORY_SIZE]; + bool movementStarted; + uint32 previousX; + uint32 previousY; + int32 deltaSumX; + int32 deltaSumY; } movement_maker;