From 2a4b67b58e4c2d9ec01f10db7fcc0a681c1ff6e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=A4rkl?= Date: Mon, 11 Jan 2021 20:13:43 +0100 Subject: [PATCH] Complete ControllerState in JNI --- android/app/src/main/cpp/chiaki-jni.c | 58 ++++++++++ .../java/com/metallic/chiaki/lib/Chiaki.kt | 103 ++++++++++++++++-- 2 files changed, 152 insertions(+), 9 deletions(-) diff --git a/android/app/src/main/cpp/chiaki-jni.c b/android/app/src/main/cpp/chiaki-jni.c index 49229f5..72b6af4 100644 --- a/android/app/src/main/cpp/chiaki-jni.c +++ b/android/app/src/main/cpp/chiaki-jni.c @@ -140,6 +140,20 @@ typedef struct android_chiaki_session_t jfieldID java_controller_state_left_y; jfieldID java_controller_state_right_x; jfieldID java_controller_state_right_y; + jfieldID java_controller_state_touches; + jfieldID java_controller_state_gyro_x; + jfieldID java_controller_state_gyro_y; + jfieldID java_controller_state_gyro_z; + jfieldID java_controller_state_accel_x; + jfieldID java_controller_state_accel_y; + jfieldID java_controller_state_accel_z; + jfieldID java_controller_state_orient_x; + jfieldID java_controller_state_orient_y; + jfieldID java_controller_state_orient_z; + jfieldID java_controller_state_orient_w; + jfieldID java_controller_touch_x; + jfieldID java_controller_touch_y; + jfieldID java_controller_touch_id; AndroidChiakiVideoDecoder video_decoder; AndroidChiakiAudioDecoder audio_decoder; @@ -305,6 +319,22 @@ JNIEXPORT void JNICALL JNI_FCN(sessionCreate)(JNIEnv *env, jobject obj, jobject session->java_controller_state_left_y = E->GetFieldID(env, controller_state_class, "leftY", "S"); session->java_controller_state_right_x = E->GetFieldID(env, controller_state_class, "rightX", "S"); session->java_controller_state_right_y = E->GetFieldID(env, controller_state_class, "rightY", "S"); + session->java_controller_state_touches = E->GetFieldID(env, controller_state_class, "touches", "[L"BASE_PACKAGE"/ControllerTouch;"); + session->java_controller_state_gyro_x = E->GetFieldID(env, controller_state_class, "gyroX", "F"); + session->java_controller_state_gyro_y = E->GetFieldID(env, controller_state_class, "gyroY", "F"); + session->java_controller_state_gyro_z = E->GetFieldID(env, controller_state_class, "gyroZ", "F"); + session->java_controller_state_accel_x = E->GetFieldID(env, controller_state_class, "accelX", "F"); + session->java_controller_state_accel_y = E->GetFieldID(env, controller_state_class, "accelY", "F"); + session->java_controller_state_accel_z = E->GetFieldID(env, controller_state_class, "accelZ", "F"); + session->java_controller_state_orient_x = E->GetFieldID(env, controller_state_class, "orientX", "F"); + session->java_controller_state_orient_y = E->GetFieldID(env, controller_state_class, "orientY", "F"); + session->java_controller_state_orient_z = E->GetFieldID(env, controller_state_class, "orientZ", "F"); + session->java_controller_state_orient_w = E->GetFieldID(env, controller_state_class, "orientW", "F"); + + jclass controller_touch_class = E->FindClass(env, BASE_PACKAGE"/ControllerTouch"); + session->java_controller_touch_x = E->GetFieldID(env, controller_touch_class, "x", "S"); + session->java_controller_touch_y = E->GetFieldID(env, controller_touch_class, "y", "S"); + session->java_controller_touch_id = E->GetFieldID(env, controller_touch_class, "id", "B"); chiaki_session_set_event_cb(&session->session, android_chiaki_event_cb, session); chiaki_session_set_video_sample_cb(&session->session, android_chiaki_video_decoder_video_sample, &session->video_decoder); @@ -382,6 +412,34 @@ JNIEXPORT void JNICALL JNI_FCN(sessionSetControllerState)(JNIEnv *env, jobject o controller_state.left_y = (int16_t)E->GetShortField(env, controller_state_java, session->java_controller_state_left_y); controller_state.right_x = (int16_t)E->GetShortField(env, controller_state_java, session->java_controller_state_right_x); controller_state.right_y = (int16_t)E->GetShortField(env, controller_state_java, session->java_controller_state_right_y); + jobjectArray touch_array = E->GetObjectField(env, controller_state_java, session->java_controller_state_touches); + size_t touch_array_len = (size_t)E->GetArrayLength(env, touch_array); + for(size_t i = 0; i < CHIAKI_CONTROLLER_TOUCHES_MAX; i++) + { + if(i < touch_array_len) + { + jobject touch = E->GetObjectArrayElement(env, touch_array, i); + controller_state.touches[i].x = (uint16_t)E->GetShortField(env, touch, session->java_controller_touch_x); + controller_state.touches[i].y = (uint16_t)E->GetShortField(env, touch, session->java_controller_touch_y); + controller_state.touches[i].id = (int8_t)E->GetByteField(env, touch, session->java_controller_touch_id); + } + else + { + controller_state.touches[i].x = 0; + controller_state.touches[i].y = 0; + controller_state.touches[i].id = -1; + } + } + controller_state.gyro_x = E->GetFloatField(env, controller_state_java, session->java_controller_state_gyro_x); + controller_state.gyro_y = E->GetFloatField(env, controller_state_java, session->java_controller_state_gyro_y); + controller_state.gyro_z = E->GetFloatField(env, controller_state_java, session->java_controller_state_gyro_z); + controller_state.accel_x = E->GetFloatField(env, controller_state_java, session->java_controller_state_accel_x); + controller_state.accel_y = E->GetFloatField(env, controller_state_java, session->java_controller_state_accel_y); + controller_state.accel_z = E->GetFloatField(env, controller_state_java, session->java_controller_state_accel_z); + controller_state.orient_x = E->GetFloatField(env, controller_state_java, session->java_controller_state_orient_x); + controller_state.orient_y = E->GetFloatField(env, controller_state_java, session->java_controller_state_orient_y); + controller_state.orient_z = E->GetFloatField(env, controller_state_java, session->java_controller_state_orient_z); + controller_state.orient_w = E->GetFloatField(env, controller_state_java, session->java_controller_state_orient_w); chiaki_session_set_controller_state(&session->session, &controller_state); } diff --git a/android/app/src/main/java/com/metallic/chiaki/lib/Chiaki.kt b/android/app/src/main/java/com/metallic/chiaki/lib/Chiaki.kt index d638cb2..0700a7c 100644 --- a/android/app/src/main/java/com/metallic/chiaki/lib/Chiaki.kt +++ b/android/app/src/main/java/com/metallic/chiaki/lib/Chiaki.kt @@ -150,6 +150,14 @@ class ChiakiLog(val levelMask: Int, val callback: (level: Int, text: String) -> private fun maxAbs(a: Short, b: Short) = if(abs(a.toInt()) > abs(b.toInt())) a else b +private val CONTROLLER_TOUCHES_MAX = 2 // must be the same as CHIAKI_CONTROLLER_TOUCHES_MAX + +data class ControllerTouch( + val x: UShort = 0U, + val y: UShort = 0U, + val id: Byte = -1 // -1 = up +) + data class ControllerState constructor( var buttons: UInt = 0U, var l2State: UByte = 0U, @@ -157,25 +165,37 @@ data class ControllerState constructor( var leftX: Short = 0, var leftY: Short = 0, var rightX: Short = 0, - var rightY: Short = 0 + var rightY: Short = 0, + private var touchIdNext: UByte = 0U, + var touches: Array = arrayOf(ControllerTouch(), ControllerTouch()), + var gyroX: Float = 0.0f, + var gyroY: Float = 0.0f, + var gyroZ: Float = 0.0f, + var accelX: Float = 0.0f, + var accelY: Float = 1.0f, + var accelZ: Float = 0.0f, + var orientX: Float = 0.0f, + var orientY: Float = 0.0f, + var orientZ: Float = 0.0f, + var orientW: Float = 1.0f ){ companion object { val BUTTON_CROSS = (1 shl 0).toUInt() val BUTTON_MOON = (1 shl 1).toUInt() - val BUTTON_BOX = (1 shl 2).toUInt() - val BUTTON_PYRAMID = (1 shl 3).toUInt() + val BUTTON_BOX = (1 shl 2).toUInt() + val BUTTON_PYRAMID = (1 shl 3).toUInt() val BUTTON_DPAD_LEFT = (1 shl 4).toUInt() val BUTTON_DPAD_RIGHT = (1 shl 5).toUInt() - val BUTTON_DPAD_UP = (1 shl 6).toUInt() + val BUTTON_DPAD_UP = (1 shl 6).toUInt() val BUTTON_DPAD_DOWN = (1 shl 7).toUInt() - val BUTTON_L1 = (1 shl 8).toUInt() - val BUTTON_R1 = (1 shl 9).toUInt() + val BUTTON_L1 = (1 shl 8).toUInt() + val BUTTON_R1 = (1 shl 9).toUInt() val BUTTON_L3 = (1 shl 10).toUInt() val BUTTON_R3 = (1 shl 11).toUInt() - val BUTTON_OPTIONS = (1 shl 12).toUInt() + val BUTTON_OPTIONS = (1 shl 12).toUInt() val BUTTON_SHARE = (1 shl 13).toUInt() - val BUTTON_TOUCHPAD = (1 shl 14).toUInt() + val BUTTON_TOUCHPAD = (1 shl 14).toUInt() val BUTTON_PS = (1 shl 15).toUInt() } @@ -186,8 +206,73 @@ data class ControllerState constructor( leftX = maxAbs(leftX, o.leftX), leftY = maxAbs(leftY, o.leftY), rightX = maxAbs(rightX, o.rightX), - rightY = maxAbs(rightY, o.rightY) + rightY = maxAbs(rightY, o.rightY), + touches = touches.zip(o.touches) { a, b -> if(a.id >= 0) a else b }.toTypedArray(), + gyroX = gyroX, + gyroY = gyroY, + gyroZ = gyroZ, + accelX = accelX, + accelY = accelY, + accelZ = accelZ, + orientX = orientX, + orientY = orientY, + orientZ = orientZ, + orientW = orientW ) + + override fun equals(other: Any?): Boolean + { + if(this === other) return true + if(javaClass != other?.javaClass) return false + + other as ControllerState + + if(buttons != other.buttons) return false + if(l2State != other.l2State) return false + if(r2State != other.r2State) return false + if(leftX != other.leftX) return false + if(leftY != other.leftY) return false + if(rightX != other.rightX) return false + if(rightY != other.rightY) return false + if(touchIdNext != other.touchIdNext) return false + if(!touches.contentEquals(other.touches)) return false + if(gyroX != other.gyroX) return false + if(gyroY != other.gyroY) return false + if(gyroZ != other.gyroZ) return false + if(accelX != other.accelX) return false + if(accelY != other.accelY) return false + if(accelZ != other.accelZ) return false + if(orientX != other.orientX) return false + if(orientY != other.orientY) return false + if(orientZ != other.orientZ) return false + if(orientW != other.orientW) return false + + return true + } + + override fun hashCode(): Int + { + var result = buttons.hashCode() + result = 31 * result + l2State.hashCode() + result = 31 * result + r2State.hashCode() + result = 31 * result + leftX + result = 31 * result + leftY + result = 31 * result + rightX + result = 31 * result + rightY + result = 31 * result + touchIdNext.hashCode() + result = 31 * result + touches.contentHashCode() + result = 31 * result + gyroX.hashCode() + result = 31 * result + gyroY.hashCode() + result = 31 * result + gyroZ.hashCode() + result = 31 * result + accelX.hashCode() + result = 31 * result + accelY.hashCode() + result = 31 * result + accelZ.hashCode() + result = 31 * result + orientX.hashCode() + result = 31 * result + orientY.hashCode() + result = 31 * result + orientZ.hashCode() + result = 31 * result + orientW.hashCode() + return result + } } class QuitReason(val value: Int)