SDL: N3DS: Use SDL_Touch instead of the Joystick touch.

From 266014faa74fb33cc2dd3a8e7c5c536097d66c9e Mon Sep 17 00:00:00 2001
From: Pierre Wendling <[EMAIL REDACTED]>
Date: Sun, 18 Sep 2022 13:38:26 -0400
Subject: [PATCH] N3DS: Use SDL_Touch instead of the Joystick touch.

---
 src/joystick/n3ds/SDL_sysjoystick.c | 30 -----------
 src/video/n3ds/SDL_n3dsevents.c     |  6 ++-
 src/video/n3ds/SDL_n3dstouch.c      | 84 +++++++++++++++++++++++++++++
 src/video/n3ds/SDL_n3dstouch.h      | 31 +++++++++++
 src/video/n3ds/SDL_n3dsvideo.c      |  3 ++
 5 files changed, 122 insertions(+), 32 deletions(-)
 create mode 100644 src/video/n3ds/SDL_n3dstouch.c
 create mode 100644 src/video/n3ds/SDL_n3dstouch.h

diff --git a/src/joystick/n3ds/SDL_sysjoystick.c b/src/joystick/n3ds/SDL_sysjoystick.c
index f65626290644..3f2d5a262d7c 100644
--- a/src/joystick/n3ds/SDL_sysjoystick.c
+++ b/src/joystick/n3ds/SDL_sysjoystick.c
@@ -45,15 +45,6 @@
 */
 #define CORRECTION_FACTOR_Y -CORRECTION_FACTOR_X
 
-/*
-  Factors used to convert touchscreen coordinates to
-  SDL's 0-1 values. Note that the N3DS's screen is
-  internally in a portrait disposition so the
-  GSP_SCREEN constants are flipped.
-*/
-#define TOUCHPAD_SCALE_X 1.0f / GSP_SCREEN_HEIGHT_BOTTOM
-#define TOUCHPAD_SCALE_Y 1.0f / GSP_SCREEN_WIDTH
-
 typedef struct N3DSJoystickState
 {
     u32 kDown;
@@ -67,7 +58,6 @@ typedef struct N3DSJoystickState
 SDL_FORCE_INLINE void UpdateAxis(SDL_Joystick *joystick, N3DSJoystickState *previous_state);
 SDL_FORCE_INLINE void UpdateButtons(SDL_Joystick *joystick, N3DSJoystickState *previous_state);
 SDL_FORCE_INLINE void UpdateSensors(SDL_Joystick *joystick, N3DSJoystickState *previous_state);
-SDL_FORCE_INLINE void UpdateTouch(SDL_Joystick *joystick);
 
 static N3DSJoystickState current_state;
 static SDL_bool sensors_enabled = SDL_FALSE;
@@ -116,7 +106,6 @@ N3DS_JoystickOpen(SDL_Joystick *joystick, int device_index)
 
     SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_ACCEL, 0.0f);
     SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_GYRO, 0.0f);
-    SDL_PrivateJoystickAddTouchpad(joystick, 1);
 
     return 0;
 }
@@ -132,11 +121,9 @@ static void
 N3DS_JoystickUpdate(SDL_Joystick *joystick)
 {
     N3DSJoystickState previous_state = current_state;
-    hidScanInput();
 
     UpdateAxis(joystick, &previous_state);
     UpdateButtons(joystick, &previous_state);
-    UpdateTouch(joystick);
 
     if (sensors_enabled) {
         UpdateSensors(joystick, &previous_state);
@@ -197,23 +184,6 @@ UpdateButtons(SDL_Joystick *joystick, N3DSJoystickState *previous_state)
     }
 }
 
-SDL_FORCE_INLINE void
-UpdateTouch(SDL_Joystick *joystick)
-{
-    touchPosition touch;
-    Uint8 state;
-    hidTouchRead(&touch);
-    state = (touch.px == 0 && touch.py == 0) ? SDL_RELEASED : SDL_PRESSED;
-
-    SDL_PrivateJoystickTouchpad(joystick,
-                                0,
-                                0,
-                                state,
-                                touch.px * TOUCHPAD_SCALE_X,
-                                touch.py * TOUCHPAD_SCALE_Y,
-                                state == SDL_PRESSED ? 1.0f : 0.0f);
-}
-
 SDL_FORCE_INLINE void
 UpdateSensors(SDL_Joystick *joystick, N3DSJoystickState *previous_state)
 {
diff --git a/src/video/n3ds/SDL_n3dsevents.c b/src/video/n3ds/SDL_n3dsevents.c
index f54d68ee735b..6b2126b1b237 100644
--- a/src/video/n3ds/SDL_n3dsevents.c
+++ b/src/video/n3ds/SDL_n3dsevents.c
@@ -22,16 +22,18 @@
 
 #ifdef SDL_VIDEO_DRIVER_N3DS
 
-/* Pumping the events for the Home and Power buttons. */
-
 #include <3ds.h>
 
 #include "../../events/SDL_events_c.h"
 #include "SDL_n3dsevents_c.h"
+#include "SDL_n3dstouch.h"
 
 void
 N3DS_PumpEvents(_THIS)
 {
+    hidScanInput();
+    N3DS_PollTouch();
+
     if (!aptMainLoop()) {
         SDL_Event ev;
         ev.type = SDL_QUIT;
diff --git a/src/video/n3ds/SDL_n3dstouch.c b/src/video/n3ds/SDL_n3dstouch.c
new file mode 100644
index 000000000000..fca0ae30f9a9
--- /dev/null
+++ b/src/video/n3ds/SDL_n3dstouch.c
@@ -0,0 +1,84 @@
+/*
+  Simple DirectMedia Layer
+  Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
+
+  This software is provided 'as-is', without any express or implied
+  warranty.  In no event will the authors be held liable for any damages
+  arising from the use of this software.
+
+  Permission is granted to anyone to use this software for any purpose,
+  including commercial applications, and to alter it and redistribute it
+  freely, subject to the following restrictions:
+
+  1. The origin of this software must not be misrepresented; you must not
+     claim that you wrote the original software. If you use this software
+     in a product, an acknowledgment in the product documentation would be
+     appreciated but is not required.
+  2. Altered source versions must be plainly marked as such, and must not be
+     misrepresented as being the original software.
+  3. This notice may not be removed or altered from any source distribution.
+*/
+
+#include "../../SDL_internal.h"
+
+#ifdef SDL_VIDEO_DRIVER_N3DS
+
+#include <3ds.h>
+
+#include "../../events/SDL_touch_c.h"
+#include "SDL_n3dstouch.h"
+
+#define N3DS_TOUCH_ID 0
+
+/*
+  Factors used to convert touchscreen coordinates to
+  SDL's 0-1 values. Note that the N3DS's screen is
+  internally in a portrait disposition so the
+  GSP_SCREEN constants are flipped.
+*/
+#define TOUCHSCREEN_SCALE_X 1.0f / GSP_SCREEN_HEIGHT_BOTTOM
+#define TOUCHSCREEN_SCALE_Y 1.0f / GSP_SCREEN_WIDTH
+
+void
+N3DS_InitTouch(void)
+{
+    SDL_AddTouch(N3DS_TOUCH_ID, SDL_TOUCH_DEVICE_DIRECT, "Touchscreen");
+}
+
+void
+N3DS_QuitTouch(void)
+{
+    SDL_DelTouch(N3DS_TOUCH_ID);
+}
+
+void
+N3DS_PollTouch(void)
+{
+    touchPosition touch;
+    static SDL_bool was_pressed = SDL_FALSE;
+    SDL_bool pressed;
+    hidTouchRead(&touch);
+    pressed = (touch.px != 0 || touch.py != 0);
+
+    if (pressed != was_pressed) {
+        was_pressed = pressed;
+        SDL_SendTouch(N3DS_TOUCH_ID,
+                      0,
+                      NULL,
+                      pressed,
+                      touch.px * TOUCHSCREEN_SCALE_X,
+                      touch.py * TOUCHSCREEN_SCALE_Y,
+                      pressed ? 1.0f : 0.0f);
+    } else if (pressed) {
+        SDL_SendTouchMotion(N3DS_TOUCH_ID,
+                            0,
+                            NULL,
+                            touch.px * TOUCHSCREEN_SCALE_X,
+                            touch.py * TOUCHSCREEN_SCALE_Y,
+                            1.0f);
+    }
+}
+
+#endif /* SDL_VIDEO_DRIVER_N3DS */
+
+/* vi: set sts=4 ts=4 sw=4 expandtab: */
diff --git a/src/video/n3ds/SDL_n3dstouch.h b/src/video/n3ds/SDL_n3dstouch.h
new file mode 100644
index 000000000000..4cc7a053337b
--- /dev/null
+++ b/src/video/n3ds/SDL_n3dstouch.h
@@ -0,0 +1,31 @@
+/*
+  Simple DirectMedia Layer
+  Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
+
+  This software is provided 'as-is', without any express or implied
+  warranty.  In no event will the authors be held liable for any damages
+  arising from the use of this software.
+
+  Permission is granted to anyone to use this software for any purpose,
+  including commercial applications, and to alter it and redistribute it
+  freely, subject to the following restrictions:
+
+  1. The origin of this software must not be misrepresented; you must not
+     claim that you wrote the original software. If you use this software
+     in a product, an acknowledgment in the product documentation would be
+     appreciated but is not required.
+  2. Altered source versions must be plainly marked as such, and must not be
+     misrepresented as being the original software.
+  3. This notice may not be removed or altered from any source distribution.
+*/
+
+#ifndef SDL_n3dstouch_h_
+#define SDL_n3dstouch_h_
+
+void N3DS_InitTouch(void);
+void N3DS_QuitTouch(void);
+void N3DS_PollTouch(void);
+
+#endif /* SDL_n3dstouch_h_ */
+
+/* vi: set sts=4 ts=4 sw=4 expandtab: */
diff --git a/src/video/n3ds/SDL_n3dsvideo.c b/src/video/n3ds/SDL_n3dsvideo.c
index ebcb9de2eec2..cd5e01068c57 100644
--- a/src/video/n3ds/SDL_n3dsvideo.c
+++ b/src/video/n3ds/SDL_n3dsvideo.c
@@ -26,6 +26,7 @@
 #include "SDL_n3dsevents_c.h"
 #include "SDL_n3dsframebuffer_c.h"
 #include "SDL_n3dsswkb.h"
+#include "SDL_n3dstouch.h"
 #include "SDL_n3dsvideo.h"
 
 #define N3DSVID_DRIVER_NAME "n3ds"
@@ -97,6 +98,7 @@ N3DS_VideoInit(_THIS)
     AddN3DSDisplay(GFX_TOP);
     AddN3DSDisplay(GFX_BOTTOM);
 
+    N3DS_InitTouch();
     N3DS_SwkbInit();
 
     return 0;
@@ -136,6 +138,7 @@ static void
 N3DS_VideoQuit(_THIS)
 {
     N3DS_SwkbQuit();
+    N3DS_QuitTouch();
     return;
 }