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

View File

@ -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;
}

View File

@ -4,8 +4,6 @@
#include <OS.h>
#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;