From 5cc7b470505f6cf9ddfe31f82872c5d9a1eb7ac1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=A4rkl?= Date: Mon, 16 Sep 2019 19:56:55 +0200 Subject: [PATCH] Android DPad Input --- android/app/src/main/cpp/chiaki-jni.c | 31 +++++++++++++++- .../java/com/metallic/chiaki/StreamSession.kt | 31 ++++++++++++++++ .../java/com/metallic/chiaki/lib/Chiaki.kt | 36 +++++++++++++++++++ .../metallic/chiaki/stream/StreamActivity.kt | 9 ++++- 4 files changed, 105 insertions(+), 2 deletions(-) diff --git a/android/app/src/main/cpp/chiaki-jni.c b/android/app/src/main/cpp/chiaki-jni.c index 53355f2..ad448e3 100644 --- a/android/app/src/main/cpp/chiaki-jni.c +++ b/android/app/src/main/cpp/chiaki-jni.c @@ -104,6 +104,13 @@ typedef struct android_chiaki_session_t jclass java_session_class; jmethodID java_session_event_login_pin_request_meth; jmethodID java_session_event_quit_meth; + jfieldID java_controller_state_buttons; + jfieldID java_controller_state_l2_state; + jfieldID java_controller_state_r2_state; + jfieldID java_controller_state_left_x; + jfieldID java_controller_state_left_y; + jfieldID java_controller_state_right_x; + jfieldID java_controller_state_right_y; AndroidChiakiVideoDecoder video_decoder; } AndroidChiakiSession; @@ -200,7 +207,6 @@ JNIEXPORT void JNICALL Java_com_metallic_chiaki_lib_ChiakiNative_sessionCreate(J memcpy(connect_info.morning, bytes, sizeof(connect_info.morning)); E->ReleaseByteArrayElements(env, morning_array, bytes, JNI_ABORT); - connect_info.video_profile.width = (unsigned int)E->GetIntField(env, connect_video_profile_obj, E->GetFieldID(env, connect_video_profile_class, "width", "I")); connect_info.video_profile.height = (unsigned int)E->GetIntField(env, connect_video_profile_obj, E->GetFieldID(env, connect_video_profile_class, "height", "I")); connect_info.video_profile.max_fps = (unsigned int)E->GetIntField(env, connect_video_profile_obj, E->GetFieldID(env, connect_video_profile_class, "maxFPS", "I")); @@ -230,6 +236,15 @@ JNIEXPORT void JNICALL Java_com_metallic_chiaki_lib_ChiakiNative_sessionCreate(J session->java_session_event_login_pin_request_meth = E->GetMethodID(env, session->java_session_class, "eventLoginPinRequest", "(Z)V"); session->java_session_event_quit_meth = E->GetMethodID(env, session->java_session_class, "eventQuit", "(ILjava/lang/String;)V"); + jclass controller_state_class = E->FindClass(env, "com/metallic/chiaki/lib/ControllerState"); + session->java_controller_state_buttons = E->GetFieldID(env, controller_state_class, "buttons", "I"); + session->java_controller_state_l2_state = E->GetFieldID(env, controller_state_class, "l2_state", "B"); + session->java_controller_state_r2_state = E->GetFieldID(env, controller_state_class, "r2_state", "B"); + session->java_controller_state_left_x = E->GetFieldID(env, controller_state_class, "left_x", "S"); + session->java_controller_state_left_y = E->GetFieldID(env, controller_state_class, "left_y", "S"); + session->java_controller_state_right_x = E->GetFieldID(env, controller_state_class, "right_x", "S"); + session->java_controller_state_right_y = E->GetFieldID(env, controller_state_class, "right_y", "S"); + 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); @@ -277,3 +292,17 @@ JNIEXPORT void JNICALL Java_com_metallic_chiaki_lib_ChiakiNative_sessionSetSurfa AndroidChiakiSession *session = (AndroidChiakiSession *)ptr; android_chiaki_video_decoder_set_surface(&session->video_decoder, env, surface); } + +JNIEXPORT void JNICALL Java_com_metallic_chiaki_lib_ChiakiNative_sessionSetControllerState(JNIEnv *env, jobject obj, jlong ptr, jobject controller_state_java) +{ + AndroidChiakiSession *session = (AndroidChiakiSession *)ptr; + ChiakiControllerState controller_state = { 0 }; + controller_state.buttons = (uint32_t)E->GetIntField(env, controller_state_java, session->java_controller_state_buttons); + controller_state.l2_state = (uint8_t)E->GetByteField(env, controller_state_java, session->java_controller_state_l2_state); + controller_state.r2_state = (uint8_t)E->GetByteField(env, controller_state_java, session->java_controller_state_r2_state); + controller_state.left_x = (int16_t)E->GetShortField(env, controller_state_java, session->java_controller_state_left_x); + 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); + chiaki_session_set_controller_state(&session->session, &controller_state); +} \ No newline at end of file diff --git a/android/app/src/main/java/com/metallic/chiaki/StreamSession.kt b/android/app/src/main/java/com/metallic/chiaki/StreamSession.kt index 44c024b..e30cf2f 100644 --- a/android/app/src/main/java/com/metallic/chiaki/StreamSession.kt +++ b/android/app/src/main/java/com/metallic/chiaki/StreamSession.kt @@ -18,6 +18,8 @@ package com.metallic.chiaki import android.graphics.SurfaceTexture +import android.util.Log +import android.view.KeyEvent import android.view.Surface import android.view.TextureView import androidx.lifecycle.LiveData @@ -38,6 +40,9 @@ class StreamSession(val connectInfo: ConnectInfo) private val _state = MutableLiveData(StreamStateIdle) val state: LiveData get() = _state + @ExperimentalUnsignedTypes + private val controllerState = ControllerState() + var surfaceTexture: SurfaceTexture? = null init @@ -96,4 +101,30 @@ class StreamSession(val connectInfo: ConnectInfo) if(surfaceTexture != null) textureView.surfaceTexture = surfaceTexture } + + @ExperimentalUnsignedTypes + fun dispatchKeyEvent(event: KeyEvent): Boolean + { + val buttonMask: UInt = when(event.keyCode) + { + KeyEvent.KEYCODE_DPAD_LEFT -> ControllerState.BUTTON_DPAD_LEFT + KeyEvent.KEYCODE_DPAD_RIGHT -> ControllerState.BUTTON_DPAD_RIGHT + KeyEvent.KEYCODE_DPAD_UP -> ControllerState.BUTTON_DPAD_UP + KeyEvent.KEYCODE_DPAD_DOWN -> ControllerState.BUTTON_DPAD_DOWN + else -> return false + } + + controllerState.buttons = controllerState.buttons.run { + when(event.action) + { + KeyEvent.ACTION_DOWN -> this or buttonMask + KeyEvent.ACTION_UP -> this and buttonMask.inv() + else -> this + } + } + + session?.setControllerState(controllerState) + + return true + } } \ No newline at end of file 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 8a0ffc9..1c74de3 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 @@ -39,6 +39,7 @@ class ChiakiNative @JvmStatic external fun sessionStop(ptr: Long): Int @JvmStatic external fun sessionJoin(ptr: Long): Int @JvmStatic external fun sessionSetSurface(ptr: Long, surface: Surface) + @JvmStatic external fun sessionSetControllerState(ptr: Long, controllerState: ControllerState) } } @@ -48,6 +49,36 @@ class ErrorCode(val value: Int) var isSuccess = value == 0 } +data class ControllerState @ExperimentalUnsignedTypes constructor( + var buttons: UInt = 0U, + var l2_state: UByte = 0U, + var r2_state: UByte = 0U, + var left_x: Short = 0, + var left_y: Short = 0, + var right_x: Short = 0, + var right_y: Short = 0 +){ + 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_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_DOWN = (1 shl 7).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_SHARE = (1 shl 13).toUInt() + val BUTTON_TOUCHPAD = (1 shl 14).toUInt() + val BUTTON_PS = (1 shl 15).toUInt() + } +} + class QuitReason(val value: Int) { override fun toString() = ChiakiNative.quitReasonToString(value) @@ -110,4 +141,9 @@ class Session(connectInfo: ConnectInfo) { ChiakiNative.sessionSetSurface(nativePtr, surface) } + + fun setControllerState(controllerState: ControllerState) + { + ChiakiNative.sessionSetControllerState(nativePtr, controllerState) + } } \ No newline at end of file diff --git a/android/app/src/main/java/com/metallic/chiaki/stream/StreamActivity.kt b/android/app/src/main/java/com/metallic/chiaki/stream/StreamActivity.kt index 13b67b3..dde8408 100644 --- a/android/app/src/main/java/com/metallic/chiaki/stream/StreamActivity.kt +++ b/android/app/src/main/java/com/metallic/chiaki/stream/StreamActivity.kt @@ -20,6 +20,7 @@ package com.metallic.chiaki.stream import android.graphics.Matrix import android.os.Bundle import android.util.Log +import android.view.KeyEvent import android.view.View import androidx.appcompat.app.AppCompatActivity import androidx.lifecycle.Observer @@ -80,7 +81,6 @@ class StreamActivity : AppCompatActivity() private fun hideSystemUI() { - Log.i("StreamActivity", "HIDE!!!!!!!!!!") window.decorView.systemUiVisibility = (View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY or View.SYSTEM_UI_FLAG_LAYOUT_STABLE or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION @@ -118,4 +118,11 @@ class StreamActivity : AppCompatActivity() textureView.setTransform(it) } } + + override fun dispatchKeyEvent(event: KeyEvent): Boolean + { + if(viewModel.session.dispatchKeyEvent(event)) + return true + return super.dispatchKeyEvent(event) + } }