diff options
-rw-r--r-- | backends/events/psp2sdl/psp2sdl-events.cpp | 152 | ||||
-rw-r--r-- | backends/events/psp2sdl/psp2sdl-events.h | 14 |
2 files changed, 127 insertions, 39 deletions
diff --git a/backends/events/psp2sdl/psp2sdl-events.cpp b/backends/events/psp2sdl/psp2sdl-events.cpp index 0c0df37015..d48df8efef 100644 --- a/backends/events/psp2sdl/psp2sdl-events.cpp +++ b/backends/events/psp2sdl/psp2sdl-events.cpp @@ -38,10 +38,11 @@ #include "math.h" PSP2EventSource::PSP2EventSource() { - for (int i = 0; i < SCE_TOUCH_PORT_MAX_NUM; i++) { - for (int j = 0; j < MAX_NUM_FINGERS; j++) { - _finger[i][j].id = -1; + for (int port = 0; port < SCE_TOUCH_PORT_MAX_NUM; port++) { + for (int i = 0; i < MAX_NUM_FINGERS; i++) { + _finger[port][i].id = -1; } + _multiFingerDragging[port] = false; } } @@ -85,18 +86,22 @@ void PSP2EventSource::preprocessFingerDown(SDL_Event *event) { // id (for multitouch) SDL_FingerID id = event->tfinger.fingerId; - // find out how many fingers were down before this event - int numFingersDown = 0; - for (int i = 0; i < MAX_NUM_FINGERS; i++) { - if (_finger[port][i].id >= 0) { - numFingersDown++; - } + int x = _km.x / MULTIPLIER; + int y = _km.y / MULTIPLIER; + + if (port == 0) { + convertTouchXYToGameXY(event->tfinger.x, event->tfinger.y, &x, &y); } + // we need the timestamps to decide later if the user performed a short tap (click) + // or a long tap (drag) + // we also need the last coordinates for each finger to keep track of dragging for (int i = 0; i < MAX_NUM_FINGERS; i++) { if (_finger[port][i].id == -1) { _finger[port][i].id = id; _finger[port][i].timeLastDown = event->tfinger.timestamp; + _finger[port][i].lastX = x; + _finger[port][i].lastY = y; break; } } @@ -126,28 +131,37 @@ void PSP2EventSource::preprocessFingerUp(SDL_Event *event) { for (int i = 0; i < MAX_NUM_FINGERS; i++) { if (_finger[port][i].id == id) { _finger[port][i].id = -1; - if ((event->tfinger.timestamp - _finger[port][i].timeLastDown) <= 250) { - // short (<250 ms) tap is interpreted as right/left mouse click depending on # fingers already down - if (numFingersDown == 2 || numFingersDown == 1) { - Uint8 simulatedButton = 0; - if (numFingersDown == 2) { - simulatedButton = SDL_BUTTON_RIGHT; - } else if (numFingersDown == 1) { - simulatedButton = SDL_BUTTON_LEFT; + if (!_multiFingerDragging[port]) { + if ((event->tfinger.timestamp - _finger[port][i].timeLastDown) <= MAX_TAP_TIME) { + // short (<MAX_TAP_TIME ms) tap is interpreted as right/left mouse click depending on # fingers already down + if (numFingersDown == 2 || numFingersDown == 1) { + Uint8 simulatedButton = 0; + if (numFingersDown == 2) { + simulatedButton = SDL_BUTTON_RIGHT; + } else if (numFingersDown == 1) { + simulatedButton = SDL_BUTTON_LEFT; + } + + event->type = SDL_MOUSEBUTTONDOWN; + event->button.button = simulatedButton; + event->button.x = x; + event->button.y = y; + + SDL_Event ev; + ev.type = SDL_MOUSEBUTTONUP; + ev.button.button = simulatedButton; + ev.button.x = x; + ev.button.y = y; + SDL_PushEvent(&ev); } - - event->type = SDL_MOUSEBUTTONDOWN; - event->button.button = simulatedButton; - event->button.x = x; - event->button.y = y; - - SDL_Event ev; - ev.type = SDL_MOUSEBUTTONUP; - ev.button.button = simulatedButton; - ev.button.x = x; - ev.button.y = y; - SDL_PushEvent(&ev); } + } else if (numFingersDown == 1) { + // when dragging, and the last finger is lifted, the drag is over + event->type = SDL_MOUSEBUTTONUP; + event->button.button = SDL_BUTTON_LEFT; + event->button.x = x; + event->button.y = y; + _multiFingerDragging[port] = false; } } } @@ -156,6 +170,8 @@ void PSP2EventSource::preprocessFingerUp(SDL_Event *event) { void PSP2EventSource::preprocessFingerMotion(SDL_Event *event) { // front (0) or back (1) panel SDL_TouchID port = event->tfinger.touchId; + // id (for multitouch) + SDL_FingerID id = event->tfinger.fingerId; // find out how many fingers were down before this event int numFingersDown = 0; @@ -165,14 +181,13 @@ void PSP2EventSource::preprocessFingerMotion(SDL_Event *event) { } } - if (numFingersDown == 1) { - + if (numFingersDown >= 1) { int x = _km.x / MULTIPLIER; int y = _km.y / MULTIPLIER; if (port == 0) { convertTouchXYToGameXY(event->tfinger.x, event->tfinger.y, &x, &y); - } else { + } else { // for relative mode, use the pointer speed setting float speedFactor = 1.0; @@ -232,9 +247,76 @@ void PSP2EventSource::preprocessFingerMotion(SDL_Event *event) { y = 0; } - event->type = SDL_MOUSEMOTION; - event->motion.x = x; - event->motion.y = y; + // update the current finger's coordinates so we can track it later + for (int i = 0; i < MAX_NUM_FINGERS; i++) { + if (_finger[port][i].id == id) { + _finger[port][i].lastX = x; + _finger[port][i].lastY = y; + } + } + + // Check if we are starting a two-finger drag and push mouse button if neccessary + if (numFingersDown >= 2) { + if (!_multiFingerDragging[port]) { + // only start a multi-finger drag if at least two fingers have been down long enough + int numFingersDownLong = 0; + for (int i = 0; i < MAX_NUM_FINGERS; i++) { + if (_finger[port][i].id >= 0) { + if (event->tfinger.timestamp - _finger[port][i].timeLastDown > MAX_TAP_TIME) { + numFingersDownLong++; + } + } + } + if (numFingersDownLong >= 2) { + // starting drag, so push mouse down at current location (back) + // or location of "oldest" finger (front) + int mouseDownX = x; + int mouseDownY = y; + if (port == 0) { + for (int i = 0; i < MAX_NUM_FINGERS; i++) { + if (_finger[port][i].id == id) { + for (int j = 0; j < MAX_NUM_FINGERS; j++) { + if (_finger[port][j].id >= 0 && (i != j) ) { + if (_finger[port][j].timeLastDown < _finger[port][i].timeLastDown) { + mouseDownX = _finger[port][j].lastX; + mouseDownY = _finger[port][j].lastY; + } + } + } + } + } + } + SDL_Event ev; + ev.type = SDL_MOUSEBUTTONDOWN; + ev.button.button = SDL_BUTTON_LEFT; + ev.button.x = mouseDownX; + ev.button.y = mouseDownY; + SDL_PushEvent(&ev); + _multiFingerDragging[port] = true; + } + } + } + + //check if this is the "oldest" finger down (or the only finger down), otherwise it will not affect mouse motion + bool updatePointer = true; + if (numFingersDown > 1) { + for (int i = 0; i < MAX_NUM_FINGERS; i++) { + if (_finger[port][i].id == id) { + for (int j = 0; j < MAX_NUM_FINGERS; j++) { + if (_finger[port][j].id >= 0 && (i != j) ) { + if (_finger[port][j].timeLastDown < _finger[port][i].timeLastDown) { + updatePointer = false; + } + } + } + } + } + } + if (updatePointer) { + event->type = SDL_MOUSEMOTION; + event->motion.x = x; + event->motion.y = y; + } } } diff --git a/backends/events/psp2sdl/psp2sdl-events.h b/backends/events/psp2sdl/psp2sdl-events.h index 42101fefe9..eee862d7c7 100644 --- a/backends/events/psp2sdl/psp2sdl-events.h +++ b/backends/events/psp2sdl/psp2sdl-events.h @@ -35,21 +35,27 @@ public: protected: void preprocessEvents(SDL_Event *event) override; private: + + enum { + MAX_NUM_FINGERS = 3, // number of fingers to track per panel + MAX_TAP_TIME = 250, // taps longer than this will not result in mouse click events + }; // track three fingers per panel + typedef struct { int id; // -1: no touch int timeLastDown; + int lastX; // last known screen coordinates + int lastY; // last known screen coordinates } Touch; - enum { - MAX_NUM_FINGERS = 3, - }; // track three fingers per panel Touch _finger[SCE_TOUCH_PORT_MAX_NUM][MAX_NUM_FINGERS]; // keep track of finger status + bool _multiFingerDragging[SCE_TOUCH_PORT_MAX_NUM]; // keep track whether we are currently drag-and-dropping + void preprocessFingerDown(SDL_Event *event); void preprocessFingerUp(SDL_Event *event); void preprocessFingerMotion(SDL_Event *event); void convertTouchXYToGameXY(float touchX, float touchY, int *gameX, int *gameY); - SceTouchPanelInfo panelInfo; }; #endif /* BACKEND_EVENTS_PSP2_H */ |