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
This commit is contained in:
Stephan Aßmus
2008-11-02 19:43:08 +00:00
parent 9db8c2f7bd
commit eab5a0f231
2 changed files with 62 additions and 38 deletions
@@ -176,43 +176,62 @@ make_small(float value)
void void
get_raw_movement(movement_maker *move, uint32 posX, uint32 posY) get_raw_movement(movement_maker *move, uint32 posX, uint32 posY)
{ {
int16 i; int diff;
float meanXOld = 0, meanYOld = 0; float xDelta, yDelta;
float meanX = 0, meanY = 0; const float acceleration = 0.7;
// calculate mean if (move->movementStarted) {
for (i = 0; i < move->n_points; i++) { move->movementStarted = false;
meanXOld += move->historyX[i]; // init delta tracking
meanYOld += move->historyY[i]; move->previousX = posX;
} move->previousY = posY;
if (move->n_points == 0) { // deltas are automatically reset
meanXOld = posX;
meanYOld = posY;
} else {
meanXOld = meanXOld / move->n_points;
meanYOld = meanYOld / move->n_points;
} }
meanX = (meanXOld + posX) / 2; // accumulate delta and store current pos, reset if pos did not change
meanY = (meanYOld + posY) / 2; 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 diff = posY - move->previousY;
for (i = 0; i < HISTORY_SIZE - 1; i++) { // lessen the effect of small diffs
move->historyX[i] = move->historyX[i + 1]; if ((diff > -3 && diff < -1) || (diff > 1 && diff < 3))
move->historyY[i] = move->historyY[i + 1]; diff /= 2;
} if (diff == 0)
move->historyX[HISTORY_SIZE - 1] = meanX; move->deltaSumY = 0.0;
move->historyY[HISTORY_SIZE - 1] = meanY; else
move->deltaSumY += diff;
if (move->n_points < HISTORY_SIZE) { move->previousX = posX;
move->n_points++; move->previousY = posY;
move->xDelta = 0;
move->yDelta = 0; // compute current delta and reset accumulated delta if
return; // 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); if (yDelta > 1.0) {
move->yDelta = make_small((meanY - meanYOld) / 16); 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_movement(movement_maker *move, uint32 posX, uint32 posY)
{ {
get_raw_movement(move, posX, 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->xDelta = move->xDelta * move->speed;
move->yDelta = move->yDelta * 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); get_raw_movement(move, posX, posY);
compute_acceleration(move, move->scroll_acceleration); compute_acceleration(move, move->scroll_acceleration);
move->scrolling_x+= move->xDelta; move->scrolling_x += move->xDelta;
move->scrolling_y+= move->yDelta; move->scrolling_y += move->yDelta;
stepsX = make_small(move->scrolling_x / move->scrolling_xStep); stepsX = make_small(move->scrolling_x / move->scrolling_xStep);
stepsY = make_small(move->scrolling_y / move->scrolling_yStep); stepsY = make_small(move->scrolling_y / move->scrolling_yStep);
@@ -270,7 +294,7 @@ start_new_movment(movement_maker *move)
if (move->scrolling_yStep <= 0) if (move->scrolling_yStep <= 0)
move->scrolling_yStep = 1; move->scrolling_yStep = 1;
move->n_points = 0; move->movementStarted = true;
move->scrolling_x = 0; move->scrolling_x = 0;
move->scrolling_y = 0; move->scrolling_y = 0;
} }
@@ -4,8 +4,6 @@
#include <OS.h> #include <OS.h>
#define HISTORY_SIZE 1
float floorf(float x); float floorf(float x);
float ceilf(float x); float ceilf(float x);
float sqrtf(float x); float sqrtf(float x);
@@ -24,9 +22,11 @@ typedef struct {
int32 scrolling_yStep; int32 scrolling_yStep;
int32 scroll_acceleration; int32 scroll_acceleration;
uint8 n_points; bool movementStarted;
float historyX[HISTORY_SIZE]; uint32 previousX;
float historyY[HISTORY_SIZE]; uint32 previousY;
int32 deltaSumX;
int32 deltaSumY;
} movement_maker; } movement_maker;