Skip to content

Commit

Permalink
query_touch_device() function basically works!
Browse files Browse the repository at this point in the history
* Double tap and hold if Talkback is running for now, will improve later. Also get_touch_devices() and get_touch_device_name functions are wrapped.
* Includes documentation and quick test, though uint64[]@ get_touch_devices() and string get_touch_device_name(uint64) still need docs.
* Updates SDL3, including windev and droidev packages.
  • Loading branch information
samtupy committed Sep 14, 2024
1 parent 332b0c5 commit 1ffcc4b
Show file tree
Hide file tree
Showing 7 changed files with 128 additions and 26 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/**
Check what fingers are in contact with a touch device and where they are on the screen, if any.
vector[]@ query_touch_device(uint64 device_id = 0);
## Arguments:
* uint64 device_id = 0: The device to query, 0 for the last device that received input.
## Returns:
touch_finger[]@: An array of structures containing touch coordinates and pressure (see remarks).
## Remarks:
Each structure in the returned array represents a finger, thus the length of the array indicates how many fingers are touching the device.
Touch_finger objects contain only 4 properties. Int64 id is a unique identifier of the finger that will remain the same as long as the finger touches the devices, float x and float y contain the coordinates of the finger on the device, and the float pressure property indicates how much force or pressure the finger is being applied to the device with.
Usage of this structure other than to receive touch input is not endorsed by the NVGT developers and may lead to unexpected results, most notably creating a touch_finger instance manually will likely set it's properties to random uninitialized memory on the stack. You have been warned.
*/

// Example:
void main() {
// Report the number of fingers touching the device.
show_window("touch example");
tts_voice tts;
int prev_finger_count = 0;
tts.speak("ready", true);
while (!key_pressed(KEY_ESCAPE) and !key_pressed(KEY_AC_BACK)) {
wait(5);
touch_finger[]@ fingers = query_touch_device(); // This will query the last device that was touched.
if (fingers.length() != prev_finger_count) {
tts.speak(fingers.length() + (fingers.length() != 1? " fingers" : " finger"), true);
prev_finger_count = fingers.length();
}
}
}
22 changes: 11 additions & 11 deletions jni/src/main/java/org/libsdl/app/SDLActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ public static void debugSource(int sources, String prefix) {
| InputDevice.SOURCE_CLASS_POSITION
| InputDevice.SOURCE_CLASS_TRACKBALL);
if (s2 != 0) cls += "Some_Unkown";
if (s2 != 0) cls += "Some_Unknown";
s2 = s_copy & InputDevice.SOURCE_ANY; // keep source only, no class;
Expand Down Expand Up @@ -162,7 +162,7 @@ public static void debugSource(int sources, String prefix) {
if (s == FLAG_TAINTED) src += " FLAG_TAINTED";
s2 &= ~FLAG_TAINTED;
if (s2 != 0) src += " Some_Unkown";
if (s2 != 0) src += " Some_Unknown";
Log.v(TAG, prefix + "int=" + s_copy + " CLASS={" + cls + " } source(s):" + src);
}
Expand Down Expand Up @@ -1473,11 +1473,11 @@ public static boolean handleKeyEvent(View v, int keyCode, KeyEvent event, InputC
if (SDLControllerManager.isDeviceSDLJoystick(deviceId)) {
// Note that we process events with specific key codes here
if (event.getAction() == KeyEvent.ACTION_DOWN) {
if (SDLControllerManager.onNativePadDown(deviceId, keyCode) == 0) {
if (SDLControllerManager.onNativePadDown(deviceId, keyCode)) {
return true;
}
} else if (event.getAction() == KeyEvent.ACTION_UP) {
if (SDLControllerManager.onNativePadUp(deviceId, keyCode) == 0) {
if (SDLControllerManager.onNativePadUp(deviceId, keyCode)) {
return true;
}
}
Expand Down Expand Up @@ -1951,7 +1951,7 @@ public void onRequestPermissionsResult(int requestCode, String[] permissions, in
/**
* This method is called by SDL using JNI.
*/
public static int openURL(String url)
public static boolean openURL(String url)
{
try {
Intent i = new Intent(Intent.ACTION_VIEW);
Expand All @@ -1967,18 +1967,18 @@ public static int openURL(String url)

mSingleton.startActivity(i);
} catch (Exception ex) {
return -1;
return false;
}
return 0;
return true;
}

/**
* This method is called by SDL using JNI.
*/
public static int showToast(String message, int duration, int gravity, int xOffset, int yOffset)
public static boolean showToast(String message, int duration, int gravity, int xOffset, int yOffset)
{
if(null == mSingleton) {
return - 1;
return false;
}

try
Expand Down Expand Up @@ -2013,9 +2013,9 @@ public void run() {
}
mSingleton.runOnUiThread(new OneShotTask(message, duration, gravity, xOffset, yOffset));
} catch(Exception ex) {
return -1;
return false;
}
return 0;
return true;
}

/**
Expand Down
18 changes: 9 additions & 9 deletions jni/src/main/java/org/libsdl/app/SDLControllerManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,15 @@ public class SDLControllerManager

public static native int nativeSetupJNI();

public static native int nativeAddJoystick(int device_id, String name, String desc,
int vendor_id, int product_id,
int button_mask,
int naxes, int axis_mask, int nhats, boolean can_rumble);
public static native int nativeRemoveJoystick(int device_id);
public static native int nativeAddHaptic(int device_id, String name);
public static native int nativeRemoveHaptic(int device_id);
public static native int onNativePadDown(int device_id, int keycode);
public static native int onNativePadUp(int device_id, int keycode);
public static native void nativeAddJoystick(int device_id, String name, String desc,
int vendor_id, int product_id,
int button_mask,
int naxes, int axis_mask, int nhats, boolean can_rumble);
public static native void nativeRemoveJoystick(int device_id);
public static native void nativeAddHaptic(int device_id, String name);
public static native void nativeRemoveHaptic(int device_id);
public static native boolean onNativePadDown(int device_id, int keycode);
public static native boolean onNativePadUp(int device_id, int keycode);
public static native void onNativeJoy(int device_id, int axis,
float value);
public static native void onNativeHat(int device_id, int hat_id,
Expand Down
5 changes: 2 additions & 3 deletions src/UI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ int message_box(const std::string& title, const std::string& text, const std::ve
}
SDL_MessageBoxData box = {mb_flags, g_WindowHandle, title.c_str(), text.c_str(), int(sdlbuttons.size()), sdlbuttons.data(), NULL};
int ret;
if (SDL_ShowMessageBox(&box, &ret) != 0) return 0; // failure.
if (!SDL_ShowMessageBox(&box, &ret)) return -1;
return ret;
}
int message_box_script(const std::string& title, const std::string& text, CScriptArray* buttons, unsigned int flags) {
Expand Down Expand Up @@ -289,8 +289,7 @@ std::string get_window_text() {
}
void* get_window_os_handle() { return reinterpret_cast<void*>(g_OSWindowHandle); }
void handle_sdl_event(SDL_Event* evt) {
if (evt->type == SDL_EVENT_KEY_DOWN || evt->type == SDL_EVENT_KEY_UP || evt->type == SDL_EVENT_TEXT_INPUT || evt->type == SDL_EVENT_MOUSE_MOTION || evt->type == SDL_EVENT_MOUSE_BUTTON_DOWN || evt->type == SDL_EVENT_MOUSE_BUTTON_UP || evt->type == SDL_EVENT_MOUSE_WHEEL)
InputEvent(evt);
if (InputEvent(evt)) return;
else if (evt->type == SDL_EVENT_WINDOW_FOCUS_LOST)
lost_window_focus();
else if (evt->type == SDL_EVENT_WINDOW_FOCUS_GAINED)
Expand Down
55 changes: 53 additions & 2 deletions src/input.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,15 @@
#include <obfuscate.h>
#include <sstream>
#include <string>
#include "angelscript.h"
#include "input.h"
#include "misc_functions.h"
#include "nvgt.h"

static unsigned char g_KeysPressed[512];
static unsigned char g_KeysRepeating[512];
static unsigned char g_KeysForced[512];
static const unsigned char* g_KeysDown = NULL;
static const SDL_bool* g_KeysDown = NULL;
static int g_KeysDownArrayLen = 0;
static unsigned char g_KeysReleased[512];
static unsigned char g_MouseButtonsPressed[32];
Expand All @@ -38,6 +39,7 @@ float g_MouseX = 0, g_MouseY = 0, g_MouseZ = 0;
float g_MouseAbsX = 0, g_MouseAbsY = 0, g_MouseAbsZ = 0;
float g_MousePrevX = 0, g_MousePrevY = 0, g_MousePrevZ = 0;
bool g_KeyboardStateChange = false;
SDL_TouchID g_TouchLastDevice = 0;
static asITypeInfo* key_code_array_type = nullptr;
static asITypeInfo* joystick_mapping_array_type = nullptr;
#ifdef _WIN32
Expand All @@ -57,7 +59,7 @@ void InputDestroy() {
SDL_Quit();
g_KeysDown = NULL;
}
void InputEvent(SDL_Event* evt) {
bool InputEvent(SDL_Event* evt) {
if (evt->type == SDL_EVENT_KEY_DOWN) {
if (!evt->key.repeat)
g_KeysPressed[evt->key.scancode] = 1;
Expand All @@ -84,6 +86,9 @@ void InputEvent(SDL_Event* evt) {
g_MouseButtonsReleased[evt->button.button] = 1;
} else if (evt->type == SDL_EVENT_MOUSE_WHEEL)
g_MouseAbsZ += evt->wheel.y;
else if (evt->type == SDL_EVENT_FINGER_DOWN) g_TouchLastDevice = evt->tfinger.touchID;
else return false;
return true;
}

void remove_keyhook();
Expand Down Expand Up @@ -374,7 +379,50 @@ void uninstall_keyhook() {
#endif
}

// Low level touch interface
CScriptArray* get_touch_devices() {
asITypeInfo* array_type = get_array_type("uint64[]");
if (!array_type) return nullptr;
int device_count;
SDL_TouchID* devices = SDL_GetTouchDevices(&device_count);
if (!devices) return nullptr;
CScriptArray* array = CScriptArray::Create(array_type);
if (!array) {
SDL_free(devices);
return nullptr;;
}
array->Reserve(device_count);
for (int i = 0; i < device_count; i++) array->InsertLast(devices + i);
SDL_free(devices);
return array;
}
std::string get_touch_device_name(uint64_t device_id) {
const char* result = SDL_GetTouchDeviceName((SDL_TouchID)device_id);
if (!result) return "";
return result;
}
CScriptArray* query_touch_device(uint64_t device_id) {
asITypeInfo* array_type = get_array_type("touch_finger[]");
if (!array_type) return nullptr;
CScriptArray* array = CScriptArray::Create(array_type);
if (!array) return nullptr;
if (!device_id && g_TouchLastDevice) device_id = g_TouchLastDevice;
if (!device_id) return array;
int finger_count;
SDL_Finger** fingers = SDL_GetTouchFingers(device_id, &finger_count);
if (!fingers) return array;
array->Reserve(finger_count);
for (int i = 0; i < finger_count; i++) array->InsertLast(fingers + i);
SDL_free(fingers);
return array;
}

void RegisterInput(asIScriptEngine* engine) {
engine->RegisterObjectType("touch_finger", sizeof(SDL_Finger), asOBJ_VALUE | asOBJ_POD | asGetTypeTraits<SDL_Finger>());
engine->RegisterObjectProperty("touch_finger", "const uint64 id", asOFFSET(SDL_Finger, id));
engine->RegisterObjectProperty("touch_finger", "const float x", asOFFSET(SDL_Finger, x));
engine->RegisterObjectProperty("touch_finger", "const float y", asOFFSET(SDL_Finger, y));
engine->RegisterObjectProperty("touch_finger", "const float pressure", asOFFSET(SDL_Finger, pressure));
engine->RegisterEnum(_O("key_modifier"));
engine->RegisterEnum(_O("key_code"));
engine->RegisterEnum(_O("joystick_type"));
Expand Down Expand Up @@ -404,6 +452,9 @@ void RegisterInput(asIScriptEngine* engine) {
engine->RegisterGlobalFunction(_O("string get_characters()"), asFUNCTION(get_characters), asCALL_CDECL);
engine->RegisterGlobalFunction(_O("bool install_keyhook(bool=true)"), asFUNCTION(install_keyhook), asCALL_CDECL);
engine->RegisterGlobalFunction(_O("void uninstall_keyhook()"), asFUNCTION(uninstall_keyhook), asCALL_CDECL);
engine->RegisterGlobalFunction(_O("uint64[]@ get_touch_devices()"), asFUNCTION(get_touch_devices), asCALL_CDECL);
engine->RegisterGlobalFunction(_O("string get_touch_device_name(uint64 device_id)"), asFUNCTION(get_touch_device_name), asCALL_CDECL);
engine->RegisterGlobalFunction(_O("touch_finger[]@ query_touch_device(uint64 device_id = 0)"), asFUNCTION(query_touch_device), asCALL_CDECL);
engine->RegisterGlobalProperty(_O("const float MOUSE_X"), &g_MouseX);
engine->RegisterGlobalProperty(_O("const float MOUSE_Y"), &g_MouseY);
engine->RegisterGlobalProperty(_O("const float MOUSE_Z"), &g_MouseZ);
Expand Down
2 changes: 1 addition & 1 deletion src/input.h
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ class joystick : Poco::RefCountedObject {

void InputInit();
void InputDestroy();
void InputEvent(SDL_Event* evt);
bool InputEvent(SDL_Event* evt);
void lost_window_focus();
void regained_window_focus();
void RegisterInput(asIScriptEngine* engine);
23 changes: 23 additions & 0 deletions test/interact/lowlevel_touch.nvgt
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// NonVisual Gaming Toolkit (NVGT)
// Copyright (C) 2022-2024 Sam Tupy
// License: zlib (see license.md in the root of the NVGT distribution)

void main() {
show_window("touch test");
tts_voice tts;
uint64[]@ devs = get_touch_devices();
if (devs.length() < 1) {
alert("oops", "no touch devices available");
return;
}
int prev_finger_count = 0;
tts.speak("ready", true);
while (!key_pressed(KEY_ESCAPE) and !key_pressed(KEY_AC_BACK)) {
wait(5);
touch_finger[]@ fingers = query_touch_device();
if (fingers.length() != prev_finger_count) {
tts.speak(fingers.length() + " fingers", true);
prev_finger_count = fingers.length();
}
}
}

0 comments on commit 1ffcc4b

Please sign in to comment.