Skip to content

Commit

Permalink
SWITCH: remove dual panel touch remnants from Vita
Browse files Browse the repository at this point in the history
  • Loading branch information
rsn8887 committed Feb 15, 2024
1 parent 74cfff3 commit 9b1ff3a
Show file tree
Hide file tree
Showing 2 changed files with 92 additions and 112 deletions.
197 changes: 89 additions & 108 deletions backends/events/switchsdl/switchsdl-events.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,22 +36,18 @@
#include "common/config-manager.h"

SwitchEventSource::SwitchEventSource() {
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;
_finger[port][i].timeLastDown = 0;
_finger[port][i].lastX = 0;
_finger[port][i].lastY = 0;
_finger[port][i].lastDownX = 0;
_finger[port][i].lastDownY = 0;
}
_multiFingerDragging[port] = DRAG_NONE;
for (int i = 0; i < MAX_NUM_FINGERS; i++) {
_finger[i].id = -1;
_finger[i].timeLastDown = 0;
_finger[i].lastX = 0;
_finger[i].lastY = 0;
_finger[i].lastDownX = 0;
_finger[i].lastDownY = 0;
}
_multiFingerDragging = DRAG_NONE;

for (int port = 0; port < SCE_TOUCH_PORT_MAX_NUM; port++) {
for (int i = 0; i < 2; i++) {
_simulatedClickStartTime[port][i] = 0;
}
for (int i = 0; i < 2; i++) {
_simulatedClickStartTime[i] = 0;
}
}

Expand All @@ -68,79 +64,68 @@ void SwitchEventSource::preprocessEvents(SDL_Event *event) {
// right mouse click: second finger short tap while first finger is still down
// pointer motion: single finger drag
if (event->type == SDL_FINGERDOWN || event->type == SDL_FINGERUP || event->type == SDL_FINGERMOTION) {
// front (0) or back (1) panel
SDL_TouchID port = event->tfinger.touchId;
//debug(0, "touch: %li\n", port);
if (port < SCE_TOUCH_PORT_MAX_NUM && port >= 0) {
// touchpad_mouse_mode off: use only front panel for direct touch control of pointer
// touchpad_mouse_mode on: also enable rear touch with indirect touch control
// where the finger can be somewhere else than the pointer and still move it
if (port == 0 || ConfMan.getBool("touchpad_mouse_mode")) {
switch (event->type) {
case SDL_FINGERDOWN:
//debug(0, "down[%li]: %i %i", event->tfinger.fingerId, (int) event->tfinger.x, (int) event->tfinger.y);
preprocessFingerDown(event);
break;
case SDL_FINGERUP:
//debug(0, "up[%li]: %i %i", event->tfinger.fingerId, (int) event->tfinger.x, (int) event->tfinger.y);
preprocessFingerUp(event);
break;
case SDL_FINGERMOTION:
//debug(0, "mov[%li]: %i %i", event->tfinger.fingerId, (int) event->tfinger.x, (int) event->tfinger.y);
preprocessFingerMotion(event);
break;
}
}
// touchpad_mouse_mode off: use direct touch control of pointer
// touchpad_mouse_mode on: use indirect touch control
// where the finger can be somewhere else than the pointer and still move it
switch (event->type) {
case SDL_FINGERDOWN:
//debug(0, "down[%li]: %i %i", event->tfinger.fingerId, (int) event->tfinger.x, (int) event->tfinger.y);
preprocessFingerDown(event);
break;
case SDL_FINGERUP:
//debug(0, "up[%li]: %i %i", event->tfinger.fingerId, (int) event->tfinger.x, (int) event->tfinger.y);
preprocessFingerUp(event);
break;
case SDL_FINGERMOTION:
//debug(0, "mov[%li]: %i %i", event->tfinger.fingerId, (int) event->tfinger.x, (int) event->tfinger.y);
preprocessFingerMotion(event);
break;
}
}
}

void SwitchEventSource::preprocessFingerDown(SDL_Event *event) {
// front (0) or back (1) panel
SDL_TouchID port = event->tfinger.touchId;
// id (for multitouch)
SDL_FingerID id = event->tfinger.fingerId;

int x = _mouseX;
int y = _mouseY;

if (port == 0 && !ConfMan.getBool("touchpad_mouse_mode")) {
if (!ConfMan.getBool("touchpad_mouse_mode")) {
convertTouchXYToGameXY(event->tfinger.x, event->tfinger.y, &x, &y);
}

// make sure each finger is not reported down multiple times
for (int i = 0; i < MAX_NUM_FINGERS; i++) {
if (_finger[port][i].id == id) {
_finger[port][i].id = -1;
if (_finger[i].id == id) {
_finger[i].id = -1;
}
}

// 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].lastDownX = event->tfinger.x;
_finger[port][i].lastDownY = event->tfinger.y;
_finger[port][i].lastX = x;
_finger[port][i].lastY = y;
if (_finger[i].id == -1) {
_finger[i].id = id;
_finger[i].timeLastDown = event->tfinger.timestamp;
_finger[i].lastDownX = event->tfinger.x;
_finger[i].lastDownY = event->tfinger.y;
_finger[i].lastX = x;
_finger[i].lastY = y;
break;
}
}
}

void SwitchEventSource::preprocessFingerUp(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;
for (int i = 0; i < MAX_NUM_FINGERS; i++) {
if (_finger[port][i].id >= 0) {
if (_finger[i].id >= 0) {
numFingersDown++;
}
}
Expand All @@ -149,27 +134,27 @@ void SwitchEventSource::preprocessFingerUp(SDL_Event *event) {
int y = _mouseY;

for (int i = 0; i < MAX_NUM_FINGERS; i++) {
if (_finger[port][i].id == id) {
_finger[port][i].id = -1;
if (!_multiFingerDragging[port]) {
if ((event->tfinger.timestamp - _finger[port][i].timeLastDown) <= MAX_TAP_TIME) {
if (_finger[i].id == id) {
_finger[i].id = -1;
if (!_multiFingerDragging) {
if ((event->tfinger.timestamp - _finger[i].timeLastDown) <= MAX_TAP_TIME) {
// short (<MAX_TAP_TIME ms) tap is interpreted as right/left mouse click depending on # fingers already down
// but only if the finger hasn't moved since it was pressed down by more than MAX_TAP_MOTION_DISTANCE pixels
float xrel = ((event->tfinger.x * (float) TOUCHSCREEN_WIDTH) - (_finger[port][i].lastDownX * (float) TOUCHSCREEN_WIDTH));
float yrel = ((event->tfinger.y * (float) TOUCHSCREEN_HEIGHT) - (_finger[port][i].lastDownY * (float) TOUCHSCREEN_HEIGHT));
float xrel = ((event->tfinger.x * (float) TOUCHSCREEN_WIDTH) - (_finger[i].lastDownX * (float) TOUCHSCREEN_WIDTH));
float yrel = ((event->tfinger.y * (float) TOUCHSCREEN_HEIGHT) - (_finger[i].lastDownY * (float) TOUCHSCREEN_HEIGHT));
float maxRSquared = (float) (MAX_TAP_MOTION_DISTANCE * MAX_TAP_MOTION_DISTANCE);
if ((xrel * xrel + yrel * yrel) < maxRSquared) {
if (numFingersDown == 2 || numFingersDown == 1) {
uint8 simulatedButton = 0;
if (numFingersDown == 2) {
simulatedButton = SDL_BUTTON_RIGHT;
// need to raise the button later
_simulatedClickStartTime[port][1] = event->tfinger.timestamp;
_simulatedClickStartTime[1] = event->tfinger.timestamp;
} else if (numFingersDown == 1) {
simulatedButton = SDL_BUTTON_LEFT;
// need to raise the button later
_simulatedClickStartTime[port][0] = event->tfinger.timestamp;
if (port == 0 && !ConfMan.getBool("touchpad_mouse_mode")) {
_simulatedClickStartTime[0] = event->tfinger.timestamp;
if (!ConfMan.getBool("touchpad_mouse_mode")) {
convertTouchXYToGameXY(event->tfinger.x, event->tfinger.y, &x, &y);
}
}
Expand All @@ -183,11 +168,11 @@ void SwitchEventSource::preprocessFingerUp(SDL_Event *event) {
}
} else if (numFingersDown == 1) {
// when dragging, and the last finger is lifted, the drag is over
if (port == 0 && !ConfMan.getBool("touchpad_mouse_mode")) {
if (!ConfMan.getBool("touchpad_mouse_mode")) {
convertTouchXYToGameXY(event->tfinger.x, event->tfinger.y, &x, &y);
}
uint8 simulatedButton = 0;
if (_multiFingerDragging[port] == DRAG_THREE_FINGER)
if (_multiFingerDragging == DRAG_THREE_FINGER)
simulatedButton = SDL_BUTTON_RIGHT;
else {
simulatedButton = SDL_BUTTON_LEFT;
Expand All @@ -196,22 +181,20 @@ void SwitchEventSource::preprocessFingerUp(SDL_Event *event) {
event->button.button = simulatedButton;
event->button.x = x;
event->button.y = y;
_multiFingerDragging[port] = DRAG_NONE;
_multiFingerDragging = DRAG_NONE;
}
}
}
}

void SwitchEventSource::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;
for (int i = 0; i < MAX_NUM_FINGERS; i++) {
if (_finger[port][i].id >= 0) {
if (_finger[i].id >= 0) {
numFingersDown++;
}
}
Expand All @@ -222,7 +205,7 @@ void SwitchEventSource::preprocessFingerMotion(SDL_Event *event) {
int xMax = _graphicsManager->getWindowWidth() - 1;
int yMax = _graphicsManager->getWindowHeight() - 1;

if (port == 0 && !ConfMan.getBool("touchpad_mouse_mode")) {
if (!ConfMan.getBool("touchpad_mouse_mode")) {
convertTouchXYToGameXY(event->tfinger.x, event->tfinger.y, &x, &y);
} else {
// for relative mode, use the pointer speed setting
Expand Down Expand Up @@ -270,39 +253,39 @@ void SwitchEventSource::preprocessFingerMotion(SDL_Event *event) {

// 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;
if (_finger[i].id == id) {
_finger[i].lastX = x;
_finger[i].lastY = y;
}
}

// If we are starting a multi-finger drag, start holding down the mouse button
if (numFingersDown >= 2) {
if (!_multiFingerDragging[port]) {
if (!_multiFingerDragging) {
// 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) {
if (_finger[i].id >= 0) {
if (event->tfinger.timestamp - _finger[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)
// starting drag, so push mouse down at current location
// or location of "oldest" finger depending on mode
int mouseDownX = _mouseX;
int mouseDownY = _mouseY;
if (port == 0 && !ConfMan.getBool("touchpad_mouse_mode")) {
if (!ConfMan.getBool("touchpad_mouse_mode")) {
for (int i = 0; i < MAX_NUM_FINGERS; i++) {
if (_finger[port][i].id == id) {
uint32 earliestTime = _finger[port][i].timeLastDown;
if (_finger[i].id == id) {
uint32 earliestTime = _finger[i].timeLastDown;
for (int j = 0; j < MAX_NUM_FINGERS; j++) {
if (_finger[port][j].id >= 0 && (i != j) ) {
if (_finger[port][j].timeLastDown < earliestTime) {
mouseDownX = _finger[port][j].lastX;
mouseDownY = _finger[port][j].lastY;
earliestTime = _finger[port][j].timeLastDown;
if (_finger[j].id >= 0 && (i != j) ) {
if (_finger[j].timeLastDown < earliestTime) {
mouseDownX = _finger[j].lastX;
mouseDownY = _finger[j].lastY;
earliestTime = _finger[j].timeLastDown;
}
}
}
Expand All @@ -313,10 +296,10 @@ void SwitchEventSource::preprocessFingerMotion(SDL_Event *event) {
uint8 simulatedButton = 0;
if (numFingersDownLong == 2) {
simulatedButton = SDL_BUTTON_LEFT;
_multiFingerDragging[port] = DRAG_TWO_FINGER;
_multiFingerDragging = DRAG_TWO_FINGER;
} else {
simulatedButton = SDL_BUTTON_RIGHT;
_multiFingerDragging[port] = DRAG_THREE_FINGER;
_multiFingerDragging = DRAG_THREE_FINGER;
}
SDL_Event ev;
ev.type = SDL_MOUSEBUTTONDOWN;
Expand All @@ -332,10 +315,10 @@ void SwitchEventSource::preprocessFingerMotion(SDL_Event *event) {
bool updatePointer = true;
if (numFingersDown > 1) {
for (int i = 0; i < MAX_NUM_FINGERS; i++) {
if (_finger[port][i].id == id) {
if (_finger[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) {
if (_finger[j].id >= 0 && (i != j) ) {
if (_finger[j].timeLastDown < _finger[i].timeLastDown) {
updatePointer = false;
}
}
Expand Down Expand Up @@ -380,26 +363,24 @@ void SwitchEventSource::convertTouchXYToGameXY(float touchX, float touchY, int *
}

void SwitchEventSource::finishSimulatedMouseClicks() {
for (int port = 0; port < SCE_TOUCH_PORT_MAX_NUM; port++) {
for (int i = 0; i < 2; i++) {
if (_simulatedClickStartTime[port][i] != 0) {
uint32 currentTime = SDL_GetTicks();
if (currentTime - _simulatedClickStartTime[port][i] >= SIMULATED_CLICK_DURATION) {
int simulatedButton;
if (i == 0) {
simulatedButton = SDL_BUTTON_LEFT;
} else {
simulatedButton = SDL_BUTTON_RIGHT;
}
SDL_Event ev;
ev.type = SDL_MOUSEBUTTONUP;
ev.button.button = simulatedButton;
ev.button.x = _mouseX;
ev.button.y = _mouseY;
SDL_PushEvent(&ev);

_simulatedClickStartTime[port][i] = 0;
for (int i = 0; i < 2; i++) {
if (_simulatedClickStartTime[i] != 0) {
uint32 currentTime = SDL_GetTicks();
if (currentTime - _simulatedClickStartTime[i] >= SIMULATED_CLICK_DURATION) {
int simulatedButton;
if (i == 0) {
simulatedButton = SDL_BUTTON_LEFT;
} else {
simulatedButton = SDL_BUTTON_RIGHT;
}
SDL_Event ev;
ev.type = SDL_MOUSEBUTTONUP;
ev.button.button = simulatedButton;
ev.button.x = _mouseX;
ev.button.y = _mouseY;
SDL_PushEvent(&ev);

_simulatedClickStartTime[i] = 0;
}
}
}
Expand Down
7 changes: 3 additions & 4 deletions backends/events/switchsdl/switchsdl-events.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@

#include "backends/events/sdl/sdl-events.h"

#define SCE_TOUCH_PORT_MAX_NUM 1
#define TOUCHSCREEN_WIDTH 1280
#define TOUCHSCREEN_HEIGHT 720

Expand Down Expand Up @@ -56,17 +55,17 @@ class SwitchEventSource : public SdlEventSource {
float lastDownY; // SDL touch coordinates when last pressed down
} Touch;

Touch _finger[SCE_TOUCH_PORT_MAX_NUM][MAX_NUM_FINGERS]; // keep track of finger status
Touch _finger[MAX_NUM_FINGERS]; // keep track of finger status

typedef enum DraggingType {
DRAG_NONE = 0,
DRAG_TWO_FINGER,
DRAG_THREE_FINGER,
} DraggingType;

DraggingType _multiFingerDragging[SCE_TOUCH_PORT_MAX_NUM]; // keep track whether we are currently drag-and-dropping
DraggingType _multiFingerDragging; // keep track whether we are currently drag-and-dropping

unsigned int _simulatedClickStartTime[SCE_TOUCH_PORT_MAX_NUM][2]; // initiation time of last simulated left or right click (zero if no click)
unsigned int _simulatedClickStartTime[2]; // initiation time of last simulated left or right click (zero if no click)

void preprocessFingerDown(SDL_Event *event);
void preprocessFingerUp(SDL_Event *event);
Expand Down

0 comments on commit 9b1ff3a

Please sign in to comment.