From 391bf2c1ad22dfcfb1e35c210c6077d68c775385 Mon Sep 17 00:00:00 2001 From: rsn8887 Date: Mon, 5 Feb 2018 20:00:27 -0600 Subject: [PATCH] implemented touchpad-style pointer controls Touch controls are configured under 'More Options/Touch' Choices are 'Touch Off', 'Front only', or 'Front and Back.' The default is to use only the front panel. Both panels work the same, using relative touch mode. How far a certain finger motion moves the pointer depends on the Mouse Speed setting, which also affects how fast the analog stick moves the mouse. Touch gestures supported: single short tap - left mouse click single short tap while holding a second finger down - right mouse click single finger drag - move the mouse pointer dual finger drag - drag'n'drop (while left mouse button is held down) --- CMakeLists.txt | 3 +- Readme.txt | 11 + src/gp2x/menu/menu_config.cpp | 5 + src/gp2x/menu/menu_config.h | 1 + src/gp2x/menu/menu_misc.cpp | 78 +++++-- src/gui.cpp | 4 +- src/main.cpp | 10 +- src/od-joy.cpp | 1 + src/psp2/psp2_touch.c | 398 ++++++++++++++++++++++++++++++++++ src/psp2/psp2_touch.h | 50 +++++ src/sdlgfx.cpp | 6 +- 11 files changed, 542 insertions(+), 25 deletions(-) create mode 100644 src/psp2/psp2_touch.c create mode 100644 src/psp2/psp2_touch.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 5b920df..2a1eb43 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -27,6 +27,7 @@ set(SRC_FILES src/psp2/psp2_shader.cpp src/psp2/psp2_input.c src/psp2/psp2-dirent.c + src/psp2/psp2_touch.c src/vkbd/vkbd.cpp src/neon_helper.s src/gp2x/memset.s @@ -120,7 +121,7 @@ set(LDFLAGS ${CMAKE_SOURCE_DIR}/src/psp2/vita-shader-collection/lib/libvitashaders.a SceSysmodule_stub SceDisplay_stub SceGxm_stub SceCtrl_stub ScePgf_stub ScePower_stub SceCommonDialog_stub - SceAudio_stub SceShellSvc_stub SceHid_stub png jpeg z m c + SceAudio_stub SceShellSvc_stub SceHid_stub SceTouch_stub png jpeg z m c ) if (BUILD_DEBUG) diff --git a/Readme.txt b/Readme.txt index e92fa5f..ae20389 100755 --- a/Readme.txt +++ b/Readme.txt @@ -50,6 +50,7 @@ VITA-EXCLUSIVE FEATURES: - Adjustable stereo separation - Bluetooth keyboard and mouse support - Sticky virtual keyboard modifiers: allows keyboard combos like CTRL-C to be entered easily +- Touchpad style pointer controls using the front touch panel and, optional, the rear touch panel. Touch pointer speed can be adjusted with the Mouse Speed option. NOTES: @@ -117,7 +118,17 @@ Square = Backspace Triangle = Toggle shift Circle = Turn off all sticky keys (ctrl, alt, amiga, and shift) +Touch controls: +single short tap = left mouse click +single short tap while holding a second finger down = right mouse click +single finger drag = move the mouse pointer +dual finger drag = drag'n'drop (left mouse button is held down) + CHANGELOG: +1.59 + +- implemented touchpad-style pointer controls. Touch controls are configured under 'More Options/Touch.' Choices are 'Touch Off', 'Front only', or 'Front and Back.' The default is to use only the front panel. Both panels work the same, using relative touch mode. How far a certain finger motion moves the pointer depends on the Mouse Speed setting, which also affects how fast the analog stick moves the mouse. + 1.58 - fix 'movec pcr,d0' not throwing exception on 68020 (fixes WHDload 18.3) diff --git a/src/gp2x/menu/menu_config.cpp b/src/gp2x/menu/menu_config.cpp index d9108f8..0088c8d 100755 --- a/src/gp2x/menu/menu_config.cpp +++ b/src/gp2x/menu/menu_config.cpp @@ -141,6 +141,7 @@ int saveMenu_n_savestate = 0; #ifdef __PSP2__ int mainMenu_shader = 5; int mainMenu_leftStickMouse = 0; +int mainMenu_touchControls = 1; int mainMenu_deadZone = 1000; #endif @@ -310,6 +311,7 @@ void SetDefaultMenuSettings(int general) #ifdef __PSP2__ mainMenu_shader = 5; mainMenu_leftStickMouse = 0; + mainMenu_touchControls = 1; mainMenu_deadZone = 1000; #endif @@ -944,6 +946,8 @@ int saveconfig(int general) fputs(buffer,f); snprintf((char*)buffer, 255, "leftstickmouse=%d\n",mainMenu_leftStickMouse); fputs(buffer,f); + snprintf((char*)buffer, 255, "touchcontrols=%d\n",mainMenu_touchControls); + fputs(buffer,f); snprintf((char*)buffer, 255, "deadzone=%d\n",mainMenu_deadZone); fputs(buffer,f); #endif @@ -1347,6 +1351,7 @@ void loadconfig(int general) #ifdef __PSP2__ fscanf(f,"shader=%d\n",&mainMenu_shader); fscanf(f,"leftstickmouse=%d\n",&mainMenu_leftStickMouse); + fscanf(f,"touchcontrols=%d\n",&mainMenu_touchControls); fscanf(f,"deadzone=%d\n",&mainMenu_deadZone); #endif fscanf(f,"showstatus=%d\n",&mainMenu_showStatus); diff --git a/src/gp2x/menu/menu_config.h b/src/gp2x/menu/menu_config.h index 4f86519..363262e 100755 --- a/src/gp2x/menu/menu_config.h +++ b/src/gp2x/menu/menu_config.h @@ -115,6 +115,7 @@ extern char custom_kickrom[256]; #ifdef __PSP2__ extern int mainMenu_leftStickMouse; +extern int mainMenu_touchControls; extern int mainMenu_shader; extern int mainMenu_deadZone; extern int mainMenu_custom_controlSet; diff --git a/src/gp2x/menu/menu_misc.cpp b/src/gp2x/menu/menu_misc.cpp index bcbb5c7..a8985d6 100755 --- a/src/gp2x/menu/menu_misc.cpp +++ b/src/gp2x/menu/menu_misc.cpp @@ -79,6 +79,7 @@ enum { #endif #ifdef __PSP2__ MENUMISC_DEADZONE, + MENUMISC_TOUCHCONTROLS, #else MENUMISC_TAPDELAY, #endif @@ -383,8 +384,8 @@ static void draw_miscMenu(int c) write_text(tabstop3-8,menuLine,"On"); write_text(tabstop3-5,menuLine,"(can disturb 2nd player)"); - // MENUMISC_LEFTSTICKMOUSE - menuLine+=2; + // MENUMISC_LEFTSTICKMOUSE + menuLine+=2; write_text(leftMargin,menuLine,"Mouse Control"); if (mainMenu_leftStickMouse==0) { @@ -392,8 +393,8 @@ static void draw_miscMenu(int c) write_text_inv(tabstop2,menuLine,"Right Stick"); else write_text(tabstop2,menuLine,"Right Stick "); - } - else if (mainMenu_leftStickMouse==1) + } + else if (mainMenu_leftStickMouse==1) { if ((menuMisc!=MENUMISC_LEFTSTICKMOUSE)||(bb)) write_text_inv(tabstop2,menuLine,"Left Stick"); @@ -453,7 +454,31 @@ static void draw_miscMenu(int c) write_text_inv(tabstop2,menuLine,cpuSpeed); else write_text(tabstop2,menuLine,cpuSpeed); - + + // MENUMISC_TOUCHCONTROLS + write_text(tabstop6-2,menuLine,"Touch"); + if (mainMenu_touchControls==0) + { + if ((menuMisc!=MENUMISC_TOUCHCONTROLS)||(bb)) + write_text_inv(tabstop9-1,menuLine,"Off"); + else + write_text(tabstop9-1,menuLine,"Off "); + } + else if (mainMenu_touchControls==1) + { + if ((menuMisc!=MENUMISC_TOUCHCONTROLS)||(bb)) + write_text_inv(tabstop9-1,menuLine,"Front"); + else + write_text(tabstop9-1,menuLine,"Front "); + } + else if (mainMenu_touchControls==2) + { + if ((menuMisc!=MENUMISC_TOUCHCONTROLS)||(bb)) + write_text_inv(tabstop9-1,menuLine,"Both"); + else + write_text(tabstop9-1,menuLine,"Both "); + } + #else // MENUMISC_TAPDELAY menuLine+=2; @@ -668,31 +693,46 @@ static int key_miscMenu(int *c) mainMenu_CPU_speed=0; } break; - + #ifndef __PSP2__ #ifdef PANDORA - case MENUMISC_PANDORASPEED: + case MENUMISC_PANDORASPEED: if(left) mainMenu_cpuSpeed-=10; else if(right) mainMenu_cpuSpeed+=10; - break; + break; #endif #endif //__PSP2__ #ifdef __PSP2__ - case MENUMISC_LEFTSTICKMOUSE: - if ((left)||(right)) - mainMenu_leftStickMouse = !mainMenu_leftStickMouse; - break; + case MENUMISC_LEFTSTICKMOUSE: + if (left || right) + mainMenu_leftStickMouse = !mainMenu_leftStickMouse; + break; + case MENUMISC_TOUCHCONTROLS: + if (left) + { + if (mainMenu_touchControls>0) + mainMenu_touchControls--; + else + mainMenu_touchControls=2; + } + else if (right) + { + if (mainMenu_touchControls<2) + mainMenu_touchControls++; + else + mainMenu_touchControls=0; + } + break; #endif #ifdef ANDROIDSDL case MENUMISC_ONSCREEN: if ((left)||(right)) - mainMenu_onScreen = !mainMenu_onScreen; - break; + mainMenu_onScreen = !mainMenu_onScreen; + break; #endif - case MENUMISC_CONTROLCFG: if (left) { @@ -724,7 +764,7 @@ static int key_miscMenu(int *c) else mainMenu_joyPort=0; } - break; + break; case MENUMISC_AUTOFIRERATE: if(left) { @@ -756,7 +796,7 @@ static int key_miscMenu(int *c) } else if (right) { - if (mainMenu_customAutofireButton < 6) + if (mainMenu_customAutofireButton < 6) mainMenu_customAutofireButton++; else mainMenu_customAutofireButton=6; @@ -845,8 +885,8 @@ static int key_miscMenu(int *c) break; case MENUMISC_MOUSEEMULATION: if ((left)||(right)) - mainMenu_mouseEmulation = !mainMenu_mouseEmulation; - break; + mainMenu_mouseEmulation = !mainMenu_mouseEmulation; + break; #else case MENUMISC_TAPDELAY: if (left) diff --git a/src/gui.cpp b/src/gui.cpp index f215616..10600e6 100755 --- a/src/gui.cpp +++ b/src/gui.cpp @@ -253,8 +253,8 @@ int gui_init (void) init_kickstart(); #ifdef __PSP2__ - //Lock PS Button to prevent file corruption - sceShellUtilLock(SCE_SHELL_UTIL_LOCK_TYPE_PS_BTN); + //Lock PS Button to prevent file corruption + sceShellUtilLock(SCE_SHELL_UTIL_LOCK_TYPE_PS_BTN); #endif #ifdef USE_UAE4ALL_VKBD diff --git a/src/main.cpp b/src/main.cpp index 497b3fa..fe69e9b 100755 --- a/src/main.cpp +++ b/src/main.cpp @@ -64,6 +64,8 @@ extern SDL_Surface *current_screenshot; #ifdef __PSP2__ //Allow locking PS Button #include +//Touch input +#include "psp2_touch.h" #ifdef DEBUG_UAE4ALL #include #endif @@ -201,6 +203,8 @@ void do_leave_program (void) #ifdef USE_UAE4ALL_VKBD vkbd_quit(); #endif + //De-Initialize touch panels + psp2QuitTouch(); #endif if(current_screenshot != NULL) SDL_FreeSurface(current_screenshot); @@ -239,8 +243,10 @@ void real_main (int argc, char **argv) #endif #ifdef __PSP2__ -//Initialize ShellUtil to allow us to disable "PS" Button (corrupts hdf files) -sceShellUtilInitEvents(0); + //Initialize ShellUtil to allow us to disable "PS" Button (corrupts hdf files) + sceShellUtilInitEvents(0); + //Initialize touch panels + psp2InitTouch(); #endif #ifdef USE_SDL diff --git a/src/od-joy.cpp b/src/od-joy.cpp index 5219b0d..585af0e 100755 --- a/src/od-joy.cpp +++ b/src/od-joy.cpp @@ -56,6 +56,7 @@ extern int rAnalogY; extern int lAnalogX; extern int lAnalogY; extern int mainMenu_leftStickMouse; +extern int mainMenu_touchControls; extern int mainMenu_deadZone; int delay2=0; // for 2nd player non-custom autofire #endif diff --git a/src/psp2/psp2_touch.c b/src/psp2/psp2_touch.c new file mode 100644 index 0000000..052a41e --- /dev/null +++ b/src/psp2/psp2_touch.c @@ -0,0 +1,398 @@ +// +// Created by rsn8887 on 02/05/18. + +#include +#include +#include +#include "psp2_touch.h" +//#include "math.h" + +typedef int bool; +#define false 0; +#define true 1; + +SceTouchData touch_old[SCE_TOUCH_PORT_MAX_NUM]; +SceTouchData touch[SCE_TOUCH_PORT_MAX_NUM]; + +SceTouchPanelInfo panelinfo[SCE_TOUCH_PORT_MAX_NUM]; + +float aAWidth[SCE_TOUCH_PORT_MAX_NUM]; +float aAHeight[SCE_TOUCH_PORT_MAX_NUM]; +float dispWidth[SCE_TOUCH_PORT_MAX_NUM]; +float dispHeight[SCE_TOUCH_PORT_MAX_NUM]; +float forcerange[SCE_TOUCH_PORT_MAX_NUM]; + +extern int mainMenu_touchControls; +extern int lastmx; +extern int lastmy; + +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 + SIMULATED_CLICK_DURATION = 50, // time in ms how long simulated mouse clicks should be +}; // track three fingers per panel + +typedef struct { + int id; // -1: no touch + int timeLastDown; +} Touch; + +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 + +int _simulatedClickStartTime[SCE_TOUCH_PORT_MAX_NUM][2]; // initiation time of last simulated left or right click (zero if no click) + +void psp2InitTouch(void) { + sceTouchSetSamplingState(SCE_TOUCH_PORT_FRONT, SCE_TOUCH_SAMPLING_STATE_START); + sceTouchSetSamplingState(SCE_TOUCH_PORT_BACK, SCE_TOUCH_SAMPLING_STATE_START); + sceTouchEnableTouchForce(SCE_TOUCH_PORT_FRONT); + sceTouchEnableTouchForce(SCE_TOUCH_PORT_BACK); + + SceTouchPanelInfo panelinfo[SCE_TOUCH_PORT_MAX_NUM]; + for(int port = 0; port < SCE_TOUCH_PORT_MAX_NUM; port++) { + sceTouchGetPanelInfo(port, &panelinfo[port]); + aAWidth[port] = (float)(panelinfo[port].maxAaX - panelinfo[port].minAaX); + aAHeight[port] = (float)(panelinfo[port].maxAaY - panelinfo[port].minAaY); + dispWidth[port] = (float)(panelinfo[port].maxDispX - panelinfo[port].minDispX); + dispHeight[port] = (float)(panelinfo[port].maxDispY - panelinfo[port].minDispY); + forcerange[port] = (float)(panelinfo[port].maxForce - panelinfo[port].minForce); + } + + 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; + } + + for (int port = 0; port < SCE_TOUCH_PORT_MAX_NUM; port++) { + for (int i = 0; i < 2; i++) { + _simulatedClickStartTime[port][i] = 0; + } + } +} + +void psp2QuitTouch(void) { + sceTouchDisableTouchForce(SCE_TOUCH_PORT_FRONT); + sceTouchDisableTouchForce(SCE_TOUCH_PORT_BACK); +} + +void psp2PollTouch(void) { + int finger_id = 0; + + memcpy(touch_old, touch, sizeof(touch_old)); + + for(int port = 0; port < SCE_TOUCH_PORT_MAX_NUM; port++) { + if ((port == SCE_TOUCH_PORT_FRONT) || (mainMenu_touchControls == 2 && port == SCE_TOUCH_PORT_BACK)) { + sceTouchPeek(port, &touch[port], 1); + psp2FinishSimulatedMouseClicks(port, touch[port].timeStamp / 1000); + if (touch[port].reportNum > 0) { + for (int i = 0; i < touch[port].reportNum; i++) { + // adjust coordinates and forces to return normalized values + // for the front, screen area is used as a reference (for direct touch) + // e.g. touch_x = 1.0 corresponds to screen_x = 960 + // for the back panel, the active touch area is used as reference + float x = 0; + float y = 0; + psp2ConvertTouchXYToSDLXY(&x, &y, touch[port].report[i].x, touch[port].report[i].y, port); + finger_id = touch[port].report[i].id; + + // Send an initial touch if finger hasn't been down + bool hasBeenDown = false; + int j = 0; + if (touch_old[port].reportNum > 0) { + for (j = 0; j < touch_old[port].reportNum; j++) { + if (touch_old[port].report[j].id == touch[port].report[i].id ) { + hasBeenDown = true; + break; + } + } + } + if (!hasBeenDown) { + TouchEvent ev; + ev.type = FINGERDOWN; + ev.tfinger.timestamp = touch[port].timeStamp / 1000; + ev.tfinger.touchId = port; + ev.tfinger.fingerId = finger_id; + ev.tfinger.x = x; + ev.tfinger.y = y; + psp2ProcessTouchEvent(&ev); + } else { + // If finger moved, send motion event instead + if (touch_old[port].report[j].x != touch[port].report[i].x || + touch_old[port].report[j].y != touch[port].report[i].y) { + float oldx = 0; + float oldy = 0; + psp2ConvertTouchXYToSDLXY(&oldx, &oldy, touch_old[port].report[j].x, touch_old[port].report[j].y, port); + TouchEvent ev; + ev.type = FINGERMOTION; + ev.tfinger.timestamp = touch[port].timeStamp / 1000; + ev.tfinger.touchId = port; + ev.tfinger.fingerId = finger_id; + ev.tfinger.x = x; + ev.tfinger.y = y; + ev.tfinger.dx = x - oldx; + ev.tfinger.dy = y - oldy; + psp2ProcessTouchEvent(&ev); + } + } + } + } + // some fingers might have been let go + if (touch_old[port].reportNum > 0) { + for (int i = 0; i < touch_old[port].reportNum; i++) { + int finger_up = 1; + if (touch[port].reportNum > 0) { + for (int j = 0; j < touch[port].reportNum; j++) { + if (touch[port].report[j].id == touch_old[port].report[i].id ) { + finger_up = 0; + } + } + } + if (finger_up == 1) { + float x = 0; + float y = 0; + psp2ConvertTouchXYToSDLXY(&x, &y, touch_old[port].report[i].x, touch_old[port].report[i].y, port); + finger_id = touch_old[port].report[i].id; + // Finger released from screen + TouchEvent ev; + ev.type = FINGERUP; + ev.tfinger.timestamp = touch[port].timeStamp / 1000; + ev.tfinger.touchId = port; + ev.tfinger.fingerId = finger_id; + ev.tfinger.x = x; + ev.tfinger.y = y; + psp2ProcessTouchEvent(&ev); + } + } + } + } + } +} + +void psp2ConvertTouchXYToSDLXY(float *sdl_x, float *sdl_y, int vita_x, int vita_y, int port) { + float x = 0; + float y = 0; + if (port == SCE_TOUCH_PORT_FRONT) { + x = (vita_x - panelinfo[port].minDispX) / dispWidth[port]; + y = (vita_y - panelinfo[port].minDispY) / dispHeight[port]; + } else { + x = (vita_x - panelinfo[port].minAaX) / aAWidth[port]; + y = (vita_y - panelinfo[port].minAaY) / aAHeight[port]; + } + if (x < 0.0) { + x = 0.0; + } else if (x > 1.0) { + x = 1.0; + } + if (y < 0.0) { + y = 0.0; + } else if (y > 1.0) { + y = 1.0; + } + *sdl_x = x; + *sdl_y = y; +} + +void psp2ProcessTouchEvent(TouchEvent *event) { + // Supported touch gestures: + // left mouse click: single finger short tap + // right mouse click: second finger short tap while first finger is still down + // pointer motion: single finger drag + // drag and drop: dual finger drag + if (event->type == FINGERDOWN || event->type == FINGERUP || event->type == FINGERMOTION) { + // front (0) or back (1) panel + int port = event->tfinger.touchId; + if (port >= 0 && port < SCE_TOUCH_PORT_MAX_NUM) { + switch (event->type) { + case FINGERDOWN: + psp2ProcessFingerDown(event); + break; + case FINGERUP: + psp2ProcessFingerUp(event); + break; + case FINGERMOTION: + psp2ProcessFingerMotion(event); + break; + } + } + } +} + +void psp2ProcessFingerDown(TouchEvent *event) { + // front (0) or back (1) panel + int port = event->tfinger.touchId; + // id (for multitouch) + int id = event->tfinger.fingerId; + + int x = lastmx; + int y = lastmy; + + // 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; + break; + } + } +} + +void psp2ProcessFingerUp(TouchEvent *event) { + // front (0) or back (1) panel + int port = event->tfinger.touchId; + // id (for multitouch) + int 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 = lastmx; + int y = lastmy; + + 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) { + // short (tfinger.timestamp; + } else if (numFingersDown == 1) { + simulatedButton = SDL_BUTTON_LEFT; + // need to raise the button later + _simulatedClickStartTime[port][0] = event->tfinger.timestamp; + } + + SDL_Event ev0; + ev0.type = SDL_MOUSEBUTTONDOWN; + ev0.button.button = simulatedButton; + ev0.button.x = x; + ev0.button.y = y; + SDL_PushEvent(&ev0); + } + } + } else if (numFingersDown == 1) { + // when dragging, and the last finger is lifted, the drag is over + SDL_Event ev0; + ev0.type = SDL_MOUSEBUTTONUP; + ev0.button.button = SDL_BUTTON_LEFT; + ev0.button.x = x; + ev0.button.y = y; + _multiFingerDragging[port] = false; + SDL_PushEvent(&ev0); + } + } + } +} + +void psp2ProcessFingerMotion(TouchEvent *event) { + // front (0) or back (1) panel + int port = event->tfinger.touchId; + // id (for multitouch) + int 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++; + } + } + + if (numFingersDown >= 1) { + int x = lastmx; + int y = lastmy; + int xrel = (int)(event->tfinger.dx * 960.0); + int yrel = (int)(event->tfinger.dy * 544.0); + + x = lastmx + (int)(event->tfinger.dx * 960.0); + y = lastmy + (int)(event->tfinger.dy * 544.0); + + // If we are starting a multi-finger drag, start holding down the mouse button + 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) { + int mouseDownX = x; + int mouseDownY = y; + 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) { + SDL_Event ev0; + ev0.type = SDL_MOUSEMOTION; + ev0.motion.x = x; + ev0.motion.y = y; + ev0.motion.xrel = xrel; + ev0.motion.yrel = yrel; + SDL_PushEvent(&ev0); + } + } +} + +void psp2FinishSimulatedMouseClicks(int port, SceUInt64 currentTime) { + for (int i = 0; i < 2; i++) { + if (_simulatedClickStartTime[port][i] != 0) { + 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 = lastmx; + ev.button.y = lastmy; + SDL_PushEvent(&ev); + + _simulatedClickStartTime[port][i] = 0; + } + } + } +} diff --git a/src/psp2/psp2_touch.h b/src/psp2/psp2_touch.h new file mode 100644 index 0000000..d6a190a --- /dev/null +++ b/src/psp2/psp2_touch.h @@ -0,0 +1,50 @@ +// +// Created by rsn8887 on 02/05/18. + +#ifndef UAE4ALL2_PSP2_TOUCH_H +#define UAE4ALL2_PSP2_TOUCH_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum TouchEventType { + FINGERDOWN, + FINGERUP, + FINGERMOTION, +} TouchEventType; + +typedef struct { + TouchEventType type; + SceUInt64 timestamp; + int touchId; + int fingerId; + float x; + float y; + float dx; + float dy; +} FingerType; + +typedef struct { + TouchEventType type; + FingerType tfinger; +} TouchEvent; + +/* Touch functions */ +void psp2InitTouch(void); +void psp2QuitTouch(void); +void psp2PollTouch(void); +void psp2ProcessTouchEvent(TouchEvent *event); +void psp2ProcessFingerDown(TouchEvent *event); +void psp2ProcessFingerUp(TouchEvent *event); +void psp2ProcessFingerMotion(TouchEvent *event); +void psp2ConvertTouchXYToSDLXY(float *sdl_x, float *sdl_y, int vita_x, int vita_y, int port); +void psp2FinishSimulatedMouseClicks(int port, SceUInt64 currentTime); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/sdlgfx.cpp b/src/sdlgfx.cpp index 1e1f52b..6404af9 100755 --- a/src/sdlgfx.cpp +++ b/src/sdlgfx.cpp @@ -49,6 +49,7 @@ #ifdef __PSP2__ #define SDL_PollEvent PSP2_PollEvent +#include "psp2/psp2_touch.h" #endif bool mouse_state = true; @@ -530,7 +531,10 @@ void handle_events (void) gui_handle_events (); #ifdef __PSP2__ -/* SDL events on PSP2 with all keyboard/mouse inputs for BT keyboard and mouse */ +/* SDL events on PSP2 with all keyboard/mouse inputs for BT keyboard and mouse, and touch */ + if (mainMenu_touchControls) { + psp2PollTouch(); + } while (SDL_PollEvent(&rEvent)) { switch (rEvent.type)