mirror of
https://github.com/skyline-emu/skyline.git
synced 2024-12-28 09:55: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"
|
||||
|
||||
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
|
||||
* @url https://switchbrew.org/wiki/HID_Shared_Memory#TouchScreenStateData
|
||||
*/
|
||||
struct TouchScreenStateData {
|
||||
u64 timestamp; //!< The timestamp in samples
|
||||
u32 _pad0_;
|
||||
|
||||
TouchAttribute attribute;
|
||||
|
||||
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)
|
||||
return;
|
||||
|
||||
const auto &lastEntry{section.entries[section.header.currentEntry]};
|
||||
auto entryIndex{(section.header.currentEntry != constant::HidEntryCount - 1) ? section.header.currentEntry + 1 : 0};
|
||||
auto &entry{section.entries[entryIndex]};
|
||||
touchPoints = touchPoints.first(std::min(touchPoints.size(), entry.data.size()));
|
||||
entry.globalTimestamp = lastEntry.globalTimestamp + 1;
|
||||
entry.localTimestamp = lastEntry.localTimestamp + 1;
|
||||
entry.touchCount = points.size();
|
||||
entry.touchCount = touchPoints.size();
|
||||
|
||||
for (size_t i{}; i < points.size(); i++) {
|
||||
const auto &host{points[i]};
|
||||
for (size_t i{}; i < touchPoints.size(); i++) {
|
||||
const auto &host{touchPoints[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.positionY = static_cast<u32>(host.y);
|
||||
guest.minorAxis = static_cast<u32>(host.minor);
|
||||
@ -37,6 +39,10 @@ namespace skyline::input {
|
||||
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.entryCount = std::min(static_cast<u8>(section.header.entryCount + 1), constant::HidEntryCount);
|
||||
section.header.maxEntry = section.header.entryCount;
|
||||
|
@ -13,6 +13,8 @@ namespace skyline::input {
|
||||
* @note This structure corresponds to TouchScreenStateData, see that for details
|
||||
*/
|
||||
struct TouchScreenPoint {
|
||||
jint attribute;
|
||||
jint id;
|
||||
jint x;
|
||||
jint y;
|
||||
jint minor;
|
||||
@ -37,6 +39,6 @@ namespace skyline::input {
|
||||
|
||||
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")
|
||||
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 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 count = event.pointerCount
|
||||
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
|
||||
for (index in 0 until count) {
|
||||
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 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++] = y
|
||||
points[offset++] = pointer.touchMinor.toInt()
|
||||
|
Loading…
Reference in New Issue
Block a user