mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-07-24 07:44:46 +02:00
111 lines
2.7 KiB
C++
111 lines
2.7 KiB
C++
// Unfinished.
|
|
// TODO:
|
|
// Zoom gesture a la http://www.zdnet.com/blog/burnette/how-to-use-multi-touch-in-android-2-part-6-implementing-the-pinch-zoom-gesture/1847
|
|
|
|
#include "base/logging.h"
|
|
#include "base/timeutil.h"
|
|
#include "input/gesture_detector.h"
|
|
|
|
|
|
const float estimatedInertiaDamping = 0.75f;
|
|
|
|
GestureDetector::GestureDetector()
|
|
: active_(0),
|
|
estimatedInertiaX_(0.0f),
|
|
estimatedInertiaY_(0.0f) {
|
|
memset(pointers, 0, sizeof(pointers));
|
|
}
|
|
|
|
TouchInput GestureDetector::Update(const TouchInput &touch, const Bounds &bounds) {
|
|
// Mouse / 1-finger-touch control.
|
|
Pointer &p = pointers[touch.id];
|
|
if ((touch.flags & TOUCH_DOWN) && bounds.Contains(touch.x, touch.y)) {
|
|
p.down = true;
|
|
p.downTime = time_now_d();
|
|
p.downX = touch.x;
|
|
p.downY = touch.y;
|
|
p.lastX = touch.x;
|
|
p.lastY = touch.y;
|
|
p.distanceX = 0.0f;
|
|
p.distanceY = 0.0f;
|
|
estimatedInertiaX_ = 0.0f;
|
|
estimatedInertiaY_ = 0.0f;
|
|
} else if (touch.flags & TOUCH_UP) {
|
|
p.down = false;
|
|
} else {
|
|
p.distanceX += fabsf(touch.x - p.lastX);
|
|
p.distanceY += fabsf(touch.y - p.lastY);
|
|
|
|
estimatedInertiaX_ += touch.x - p.lastX;
|
|
estimatedInertiaY_ += touch.y - p.lastY;
|
|
estimatedInertiaX_ *= estimatedInertiaDamping;
|
|
estimatedInertiaY_ *= estimatedInertiaDamping;
|
|
|
|
p.lastX = touch.x;
|
|
p.lastY = touch.y;
|
|
}
|
|
|
|
if (touch.id == 0 && p.distanceY > p.distanceX) {
|
|
if (p.down) {
|
|
double timeDown = time_now_d() - p.downTime;
|
|
if (!active_ && p.distanceY * timeDown > 3) {
|
|
active_ |= GESTURE_DRAG_VERTICAL;
|
|
// Kill the drag
|
|
TouchInput inp2 = touch;
|
|
inp2.flags = TOUCH_UP | TOUCH_CANCEL;
|
|
return inp2;
|
|
}
|
|
} else {
|
|
active_ = 0;
|
|
}
|
|
}
|
|
|
|
if (touch.id == 0 && p.distanceX > p.distanceY) {
|
|
if (p.down) {
|
|
double timeDown = time_now_d() - p.downTime;
|
|
if (!active_ && p.distanceX * timeDown > 3) {
|
|
active_ |= GESTURE_DRAG_HORIZONTAL;
|
|
// Kill the drag
|
|
TouchInput inp2 = touch;
|
|
inp2.flags = TOUCH_UP | TOUCH_CANCEL;
|
|
return inp2;
|
|
}
|
|
} else {
|
|
active_ = 0;
|
|
}
|
|
}
|
|
|
|
return touch;
|
|
}
|
|
|
|
void GestureDetector::UpdateFrame() {
|
|
estimatedInertiaX_ *= estimatedInertiaDamping;
|
|
estimatedInertiaY_ *= estimatedInertiaDamping;
|
|
}
|
|
|
|
bool GestureDetector::IsGestureActive(Gesture gesture) const {
|
|
return (active_ & gesture) != 0;
|
|
}
|
|
|
|
bool GestureDetector::GetGestureInfo(Gesture gesture, float info[4]) const {
|
|
if (!(active_ & gesture)) {
|
|
memset(info, 0, sizeof(float) * 4);
|
|
return false;
|
|
}
|
|
|
|
memset(info, 0, sizeof(float) * 4);
|
|
|
|
switch (gesture) {
|
|
case GESTURE_DRAG_HORIZONTAL:
|
|
info[0] = pointers[0].lastX - pointers[0].downX;
|
|
info[1] = estimatedInertiaX_;
|
|
return true;
|
|
case GESTURE_DRAG_VERTICAL:
|
|
info[0] = pointers[0].lastY - pointers[0].downY;
|
|
info[1] = estimatedInertiaY_;
|
|
return true;
|
|
default:
|
|
return false;
|
|
}
|
|
}
|