mirror of
https://github.com/skyline-emu/skyline.git
synced 2024-12-29 17:35:29 +03:00
Add HID touch attribute and index reporting
Adds missing parameter TouchAttribute and emulates correctly the touch point index. Both changes are necessary on Voez to keep track of each finger.
This commit is contained in:
parent
80c8fb8791
commit
7aa6a5c4ca
@ -6,13 +6,27 @@
|
|||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
|
||||||
namespace skyline::input {
|
namespace skyline::input {
|
||||||
|
/**
|
||||||
|
* @brief Indicates if touch point has started or ended
|
||||||
|
* @url https://switchbrew.org/wiki/HID_services#TouchAttribute
|
||||||
|
*/
|
||||||
|
union TouchAttribute {
|
||||||
|
u32 raw{};
|
||||||
|
struct {
|
||||||
|
bool start : 1;
|
||||||
|
bool end : 1;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
static_assert(sizeof(TouchAttribute) == 0x4);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief A descriptor for a single point on the touch screen
|
* @brief A descriptor for a single point on the touch screen
|
||||||
* @url https://switchbrew.org/wiki/HID_Shared_Memory#TouchScreenStateData
|
* @url https://switchbrew.org/wiki/HID_Shared_Memory#TouchScreenStateData
|
||||||
*/
|
*/
|
||||||
struct TouchScreenStateData {
|
struct TouchScreenStateData {
|
||||||
u64 timestamp; //!< The timestamp in samples
|
u64 timestamp; //!< The timestamp in samples
|
||||||
u32 _pad0_;
|
|
||||||
|
TouchAttribute attribute;
|
||||||
|
|
||||||
u32 index; //!< The index of this touch
|
u32 index; //!< The index of this touch
|
||||||
|
|
||||||
|
@ -15,21 +15,23 @@ namespace skyline::input {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TouchManager::SetState(const span<TouchScreenPoint> &points) {
|
void TouchManager::SetState(span<TouchScreenPoint> touchPoints) {
|
||||||
if (!activated)
|
if (!activated)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const auto &lastEntry{section.entries[section.header.currentEntry]};
|
const auto &lastEntry{section.entries[section.header.currentEntry]};
|
||||||
auto entryIndex{(section.header.currentEntry != constant::HidEntryCount - 1) ? section.header.currentEntry + 1 : 0};
|
auto entryIndex{(section.header.currentEntry != constant::HidEntryCount - 1) ? section.header.currentEntry + 1 : 0};
|
||||||
auto &entry{section.entries[entryIndex]};
|
auto &entry{section.entries[entryIndex]};
|
||||||
|
touchPoints = touchPoints.first(std::min(touchPoints.size(), entry.data.size()));
|
||||||
entry.globalTimestamp = lastEntry.globalTimestamp + 1;
|
entry.globalTimestamp = lastEntry.globalTimestamp + 1;
|
||||||
entry.localTimestamp = lastEntry.localTimestamp + 1;
|
entry.localTimestamp = lastEntry.localTimestamp + 1;
|
||||||
entry.touchCount = points.size();
|
entry.touchCount = touchPoints.size();
|
||||||
|
|
||||||
for (size_t i{}; i < points.size(); i++) {
|
for (size_t i{}; i < touchPoints.size(); i++) {
|
||||||
const auto &host{points[i]};
|
const auto &host{touchPoints[i]};
|
||||||
auto &guest{entry.data[i]};
|
auto &guest{entry.data[i]};
|
||||||
guest.index = static_cast<u32>(i);
|
guest.attribute.raw = static_cast<u32>(host.attribute);
|
||||||
|
guest.index = static_cast<u32>(host.id);
|
||||||
guest.positionX = static_cast<u32>(host.x);
|
guest.positionX = static_cast<u32>(host.x);
|
||||||
guest.positionY = static_cast<u32>(host.y);
|
guest.positionY = static_cast<u32>(host.y);
|
||||||
guest.minorAxis = static_cast<u32>(host.minor);
|
guest.minorAxis = static_cast<u32>(host.minor);
|
||||||
@ -37,6 +39,10 @@ namespace skyline::input {
|
|||||||
guest.angle = host.angle;
|
guest.angle = host.angle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Clear unused touch points
|
||||||
|
for (size_t i{touchPoints.size()}; i < entry.data.size(); i++)
|
||||||
|
entry.data[i] = {};
|
||||||
|
|
||||||
section.header.timestamp = util::GetTimeTicks();
|
section.header.timestamp = util::GetTimeTicks();
|
||||||
section.header.entryCount = std::min(static_cast<u8>(section.header.entryCount + 1), constant::HidEntryCount);
|
section.header.entryCount = std::min(static_cast<u8>(section.header.entryCount + 1), constant::HidEntryCount);
|
||||||
section.header.maxEntry = section.header.entryCount;
|
section.header.maxEntry = section.header.entryCount;
|
||||||
|
@ -13,6 +13,8 @@ namespace skyline::input {
|
|||||||
* @note This structure corresponds to TouchScreenStateData, see that for details
|
* @note This structure corresponds to TouchScreenStateData, see that for details
|
||||||
*/
|
*/
|
||||||
struct TouchScreenPoint {
|
struct TouchScreenPoint {
|
||||||
|
jint attribute;
|
||||||
|
jint id;
|
||||||
jint x;
|
jint x;
|
||||||
jint y;
|
jint y;
|
||||||
jint minor;
|
jint minor;
|
||||||
@ -37,6 +39,6 @@ namespace skyline::input {
|
|||||||
|
|
||||||
void Activate();
|
void Activate();
|
||||||
|
|
||||||
void SetState(const span<TouchScreenPoint> &points);
|
void SetState(span<TouchScreenPoint> touchPoints);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -467,8 +467,8 @@ class EmulationActivity : AppCompatActivity(), SurfaceHolder.Callback, View.OnTo
|
|||||||
|
|
||||||
@SuppressLint("ClickableViewAccessibility")
|
@SuppressLint("ClickableViewAccessibility")
|
||||||
override fun onTouch(view : View, event : MotionEvent) : Boolean {
|
override fun onTouch(view : View, event : MotionEvent) : Boolean {
|
||||||
val count = if (event.action != MotionEvent.ACTION_UP && event.action != MotionEvent.ACTION_CANCEL) event.pointerCount else 0
|
val count = event.pointerCount
|
||||||
val points = IntArray(count * 5) // This is an array of skyline::input::TouchScreenPoint in C++ as that allows for efficient transfer of values to it
|
val points = IntArray(count * 7) // This is an array of skyline::input::TouchScreenPoint in C++ as that allows for efficient transfer of values to it
|
||||||
var offset = 0
|
var offset = 0
|
||||||
for (index in 0 until count) {
|
for (index in 0 until count) {
|
||||||
val pointer = MotionEvent.PointerCoords()
|
val pointer = MotionEvent.PointerCoords()
|
||||||
@ -477,6 +477,14 @@ class EmulationActivity : AppCompatActivity(), SurfaceHolder.Callback, View.OnTo
|
|||||||
val x = 0f.coerceAtLeast(pointer.x * 1280 / view.width).toInt()
|
val x = 0f.coerceAtLeast(pointer.x * 1280 / view.width).toInt()
|
||||||
val y = 0f.coerceAtLeast(pointer.y * 720 / view.height).toInt()
|
val y = 0f.coerceAtLeast(pointer.y * 720 / view.height).toInt()
|
||||||
|
|
||||||
|
val attribute = when (event.action) {
|
||||||
|
MotionEvent.ACTION_DOWN -> 1
|
||||||
|
MotionEvent.ACTION_UP -> 2
|
||||||
|
else -> 0
|
||||||
|
}
|
||||||
|
|
||||||
|
points[offset++] = attribute
|
||||||
|
points[offset++] = event.getPointerId(index)
|
||||||
points[offset++] = x
|
points[offset++] = x
|
||||||
points[offset++] = y
|
points[offset++] = y
|
||||||
points[offset++] = pointer.touchMinor.toInt()
|
points[offset++] = pointer.touchMinor.toInt()
|
||||||
|
Loading…
Reference in New Issue
Block a user