forked from geode-sdk/android-launcher
my attempt 2
This commit is contained in:
4 files changed
+355
No files matched your search
@@ -22,6 +22,7 @@
|
|||||||
<uses-permission android:name="android.permission.RECORD_AUDIO" />
|
<uses-permission android:name="android.permission.RECORD_AUDIO" />
|
||||||
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES"/>
|
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES"/>
|
||||||
<uses-permission android:name="android.permission.VIBRATE" />
|
<uses-permission android:name="android.permission.VIBRATE" />
|
||||||
|
<uses-permission android:name="android.permission.LIGHTS" />
|
||||||
|
|
||||||
<uses-feature
|
<uses-feature
|
||||||
android:name="android.hardware.wifi"
|
android:name="android.hardware.wifi"
|
||||||
@@ -29,6 +30,9 @@
|
|||||||
<uses-feature
|
<uses-feature
|
||||||
android:glEsVersion="0x00020000"
|
android:glEsVersion="0x00020000"
|
||||||
android:required="true" />
|
android:required="true" />
|
||||||
|
<uses-feature
|
||||||
|
android:name="android.hardware.gamepad"
|
||||||
|
android:required="false" />
|
||||||
|
|
||||||
<application
|
<application
|
||||||
android:allowBackup="true"
|
android:allowBackup="true"
|
||||||
|
|||||||
@@ -592,6 +592,10 @@ class GeometryDashActivity : AppCompatActivity(), Cocos2dxHelper.Cocos2dxHelperL
|
|||||||
mGLSurfaceView?.sendInternalTimestampEvents = true
|
mGLSurfaceView?.sendInternalTimestampEvents = true
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
GeodeUtils.CAPABILITY_CONTROLLER_DATA -> {
|
||||||
|
mGLSurfaceView?.enableControllerEvents()
|
||||||
|
true
|
||||||
|
}
|
||||||
else -> false
|
else -> false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,9 @@ import android.content.ClipboardManager
|
|||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.content.pm.PackageManager
|
import android.content.pm.PackageManager
|
||||||
|
import android.hardware.lights.Light
|
||||||
|
import android.hardware.lights.LightState
|
||||||
|
import android.hardware.lights.LightsRequest
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.os.Environment
|
import android.os.Environment
|
||||||
@@ -16,6 +19,7 @@ import android.os.VibratorManager
|
|||||||
import android.provider.DocumentsContract
|
import android.provider.DocumentsContract
|
||||||
import android.provider.Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION
|
import android.provider.Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
|
import android.view.InputDevice
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.activity.result.ActivityResultLauncher
|
import androidx.activity.result.ActivityResultLauncher
|
||||||
import androidx.activity.result.contract.ActivityResultContracts
|
import androidx.activity.result.contract.ActivityResultContracts
|
||||||
@@ -547,6 +551,7 @@ object GeodeUtils {
|
|||||||
const val CAPABILITY_EXTENDED_INPUT = "extended_input"
|
const val CAPABILITY_EXTENDED_INPUT = "extended_input"
|
||||||
const val CAPABILITY_TIMESTAMP_INPUT = "timestamp_inputs"
|
const val CAPABILITY_TIMESTAMP_INPUT = "timestamp_inputs"
|
||||||
const val CAPABILITY_INTERNAL_CALLBACKS = "internal_callbacks_v1"
|
const val CAPABILITY_INTERNAL_CALLBACKS = "internal_callbacks_v1"
|
||||||
|
const val CAPABILITY_CONTROLLER_DATA = "controller_data"
|
||||||
|
|
||||||
private var capabilityListener: WeakReference<CapabilityListener?> = WeakReference(null)
|
private var capabilityListener: WeakReference<CapabilityListener?> = WeakReference(null)
|
||||||
|
|
||||||
@@ -576,6 +581,188 @@ object GeodeUtils {
|
|||||||
.launchUrl(activity, url.toUri())
|
.launchUrl(activity, url.toUri())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines if any gamepad or joystick input devices are connected.
|
||||||
|
* This is useful during start, but tracking inputDeviceAdded events is better during runtime.
|
||||||
|
*/
|
||||||
|
@JvmStatic
|
||||||
|
fun controllersConnected(): Int {
|
||||||
|
val deviceIds = InputDevice.getDeviceIds()
|
||||||
|
return deviceIds.count {
|
||||||
|
InputDevice.getDevice(it)?.run {
|
||||||
|
sources and InputDevice.SOURCE_GAMEPAD == InputDevice.SOURCE_GAMEPAD || sources and InputDevice.SOURCE_JOYSTICK == InputDevice.SOURCE_JOYSTICK
|
||||||
|
} ?: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
fun getConnectedDevices(): IntArray = InputDevice.getDeviceIds()
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
fun getDevice(deviceId: Int): InputDevice? = InputDevice.getDevice(deviceId)
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
fun getDeviceBatteryCapacity(deviceId: Int): Float {
|
||||||
|
val device = InputDevice.getDevice(deviceId) ?: return 0.0f
|
||||||
|
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
||||||
|
device.batteryState.capacity
|
||||||
|
} else {
|
||||||
|
0.0f
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
fun deviceHasBattery(deviceId: Int): Boolean {
|
||||||
|
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
val device = InputDevice.getDevice(deviceId) ?: return false
|
||||||
|
return device.batteryState.isPresent
|
||||||
|
}
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
fun getDeviceBatteryStatus(deviceId: Int): Int {
|
||||||
|
val device = InputDevice.getDevice(deviceId) ?: return 0
|
||||||
|
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
||||||
|
device.batteryState.status
|
||||||
|
} else {
|
||||||
|
0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
fun getDeviceLightsCount(deviceId: Int): Int {
|
||||||
|
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S) {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
val device = InputDevice.getDevice(deviceId) ?: return 0
|
||||||
|
val lightsManager = device.lightsManager
|
||||||
|
|
||||||
|
return lightsManager.lights.size
|
||||||
|
}
|
||||||
|
|
||||||
|
// this is based on paddleboat's api
|
||||||
|
@JvmStatic
|
||||||
|
fun getLightType(deviceId: Int): Int {
|
||||||
|
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S) {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
val device = InputDevice.getDevice(deviceId) ?: return 0
|
||||||
|
val lightsManager = device.lightsManager
|
||||||
|
|
||||||
|
var flags = 0
|
||||||
|
lightsManager.lights.forEach { light ->
|
||||||
|
if (light.type == Light.LIGHT_TYPE_PLAYER_ID) {
|
||||||
|
flags = flags or 1
|
||||||
|
} else if (light.hasRgbControl()) {
|
||||||
|
flags = flags or 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return flags
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the color for a device.
|
||||||
|
* @return false if the given device does not exist or setting lights was otherwise unsuccessful
|
||||||
|
*/
|
||||||
|
@JvmStatic
|
||||||
|
fun setDeviceLightColor(deviceId: Int, color: Int, type: Int): Boolean {
|
||||||
|
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
val device = InputDevice.getDevice(deviceId) ?: return false
|
||||||
|
val lightsManager = device.lightsManager
|
||||||
|
|
||||||
|
val lights = lightsManager.lights
|
||||||
|
if (lights.isEmpty()) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
val actedLights = lights.count { light ->
|
||||||
|
val state = LightState.Builder()
|
||||||
|
|
||||||
|
if (light.type == Light.LIGHT_TYPE_PLAYER_ID && (type and 1 == 1)) {
|
||||||
|
state.setPlayerId(color)
|
||||||
|
} else if (light.hasRgbControl() && (type and 2 == 2)) {
|
||||||
|
state.setColor(color)
|
||||||
|
} else {
|
||||||
|
return@count false
|
||||||
|
}
|
||||||
|
|
||||||
|
val request = LightsRequest.Builder()
|
||||||
|
.addLight(light, state.build())
|
||||||
|
.build()
|
||||||
|
|
||||||
|
lightsManager.openSession()
|
||||||
|
.requestLights(request)
|
||||||
|
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
return actedLights > 0
|
||||||
|
}
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
fun getDeviceHapticsCount(deviceId: Int): Int {
|
||||||
|
val device = InputDevice.getDevice(deviceId) ?: return 0
|
||||||
|
|
||||||
|
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S) {
|
||||||
|
return if (device.vibrator.hasVibrator()) 1 else 0
|
||||||
|
}
|
||||||
|
|
||||||
|
val vibratorManager = device.vibratorManager
|
||||||
|
val vibratorIds = vibratorManager.vibratorIds
|
||||||
|
return vibratorIds.size
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun performVibration(vibrator: Vibrator?, durationMs: Long, intensity: Int) {
|
||||||
|
vibrator?.apply {
|
||||||
|
if (intensity == 0) {
|
||||||
|
cancel()
|
||||||
|
} else {
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||||
|
val vibrationEffect = VibrationEffect.createOneShot(durationMs, intensity)
|
||||||
|
vibrate(vibrationEffect)
|
||||||
|
} else {
|
||||||
|
vibrate(durationMs)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Vibrates a given device. Set motorIdx == -1 to vibrate all available motors on a device.
|
||||||
|
*/
|
||||||
|
@JvmStatic
|
||||||
|
fun vibrateDevice(deviceId: Int, durationMs: Long, intensity: Int, motorIdx: Int): Boolean {
|
||||||
|
val device = InputDevice.getDevice(deviceId) ?: return false
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
||||||
|
val vibratorManager = device.vibratorManager
|
||||||
|
val vibratorIds = vibratorManager.vibratorIds
|
||||||
|
|
||||||
|
if (motorIdx == -1) {
|
||||||
|
vibratorIds.forEach {
|
||||||
|
val vibrator = vibratorManager.getVibrator(it)
|
||||||
|
performVibration(vibrator, durationMs, intensity)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
val deviceId = vibratorIds.getOrNull(motorIdx) ?: return false
|
||||||
|
val vibrator = vibratorManager.getVibrator(deviceId)
|
||||||
|
performVibration(vibrator, durationMs, intensity)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
val vibrator = device.vibrator
|
||||||
|
performVibration(vibrator, durationMs, intensity)
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
external fun nativeKeyUp(keyCode: Int, modifiers: Int)
|
external fun nativeKeyUp(keyCode: Int, modifiers: Int)
|
||||||
external fun nativeKeyDown(keyCode: Int, modifiers: Int, isRepeating: Boolean)
|
external fun nativeKeyDown(keyCode: Int, modifiers: Int, isRepeating: Boolean)
|
||||||
external fun nativeActionScroll(scrollX: Float, scrollY: Float)
|
external fun nativeActionScroll(scrollX: Float, scrollY: Float)
|
||||||
@@ -588,4 +775,15 @@ object GeodeUtils {
|
|||||||
*/
|
*/
|
||||||
external fun setNextInputTimestamp(timestamp: Long)
|
external fun setNextInputTimestamp(timestamp: Long)
|
||||||
external fun setNextInputTimestampInternal(timestamp: Long)
|
external fun setNextInputTimestampInternal(timestamp: Long)
|
||||||
|
|
||||||
|
external fun setNextInputDevice(deviceId: Int, eventSource: Int)
|
||||||
|
external fun inputDeviceAdded(deviceId: Int)
|
||||||
|
external fun inputDeviceChanged(deviceId: Int)
|
||||||
|
external fun inputDeviceRemoved(deviceId: Int)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends all batched joystick events. The final position in each array represents the current position of that axis.
|
||||||
|
* Have fun!
|
||||||
|
*/
|
||||||
|
external fun onJoystickEvent(leftX: FloatArray, leftY: FloatArray, rightX: FloatArray, rightY: FloatArray, hatX: FloatArray, hatY: FloatArray, leftTrigger: FloatArray, rightTrigger: FloatArray)
|
||||||
}
|
}
|
||||||
@@ -2,12 +2,14 @@ package org.cocos2dx.lib
|
|||||||
|
|
||||||
import android.app.Activity
|
import android.app.Activity
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
import android.hardware.input.InputManager
|
||||||
import android.opengl.GLSurfaceView
|
import android.opengl.GLSurfaceView
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.os.Handler
|
import android.os.Handler
|
||||||
import android.os.Looper
|
import android.os.Looper
|
||||||
import android.os.Message
|
import android.os.Message
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
|
import android.view.InputDevice
|
||||||
import android.view.KeyEvent
|
import android.view.KeyEvent
|
||||||
import android.view.MotionEvent
|
import android.view.MotionEvent
|
||||||
import android.view.Surface
|
import android.view.Surface
|
||||||
@@ -16,6 +18,7 @@ import androidx.annotation.RequiresApi
|
|||||||
import androidx.appcompat.widget.AppCompatEditText
|
import androidx.appcompat.widget.AppCompatEditText
|
||||||
import com.customRobTop.BaseRobTopActivity
|
import com.customRobTop.BaseRobTopActivity
|
||||||
import com.geode.launcher.utils.GeodeUtils
|
import com.geode.launcher.utils.GeodeUtils
|
||||||
|
import kotlin.math.abs
|
||||||
|
|
||||||
private const val HANDLER_OPEN_IME_KEYBOARD = 2
|
private const val HANDLER_OPEN_IME_KEYBOARD = 2
|
||||||
private const val HANDLER_CLOSE_IME_KEYBOARD = 3
|
private const val HANDLER_CLOSE_IME_KEYBOARD = 3
|
||||||
@@ -58,6 +61,8 @@ class Cocos2dxGLSurfaceView(context: Context) : GLSurfaceView(context) {
|
|||||||
var sendTimestampEvents = false
|
var sendTimestampEvents = false
|
||||||
var sendInternalTimestampEvents = false
|
var sendInternalTimestampEvents = false
|
||||||
var manualBackEvents = false
|
var manualBackEvents = false
|
||||||
|
var controllerEventsEnabled = false
|
||||||
|
private set
|
||||||
|
|
||||||
var cocos2dxEditText: AppCompatEditText? = null
|
var cocos2dxEditText: AppCompatEditText? = null
|
||||||
set(value) {
|
set(value) {
|
||||||
@@ -159,6 +164,16 @@ class Cocos2dxGLSurfaceView(context: Context) : GLSurfaceView(context) {
|
|||||||
GeodeUtils.setNextInputTimestampInternal(timestamp)
|
GeodeUtils.setNextInputTimestampInternal(timestamp)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun sendNextEventDetails(event: KeyEvent) {
|
||||||
|
if (controllerEventsEnabled)
|
||||||
|
GeodeUtils.setNextInputDevice(event.deviceId, event.source)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun sendNextEventDetails(event: MotionEvent) {
|
||||||
|
if (controllerEventsEnabled)
|
||||||
|
GeodeUtils.setNextInputDevice(event.deviceId, event.source)
|
||||||
|
}
|
||||||
|
|
||||||
override fun onTouchEvent(motionEvent: MotionEvent): Boolean {
|
override fun onTouchEvent(motionEvent: MotionEvent): Boolean {
|
||||||
val pointerNumber = motionEvent.pointerCount
|
val pointerNumber = motionEvent.pointerCount
|
||||||
val ids = IntArray(pointerNumber)
|
val ids = IntArray(pointerNumber)
|
||||||
@@ -178,6 +193,7 @@ class Cocos2dxGLSurfaceView(context: Context) : GLSurfaceView(context) {
|
|||||||
val xDown = xs[0]
|
val xDown = xs[0]
|
||||||
val f = ys[0]
|
val f = ys[0]
|
||||||
queueEvent {
|
queueEvent {
|
||||||
|
sendNextEventDetails(motionEvent)
|
||||||
sendNextEventTimestamp(timestamp)
|
sendNextEventTimestamp(timestamp)
|
||||||
cocos2dxRenderer.handleActionDown(idDown, xDown, f)
|
cocos2dxRenderer.handleActionDown(idDown, xDown, f)
|
||||||
}
|
}
|
||||||
@@ -188,6 +204,7 @@ class Cocos2dxGLSurfaceView(context: Context) : GLSurfaceView(context) {
|
|||||||
val f2 = xs[0]
|
val f2 = xs[0]
|
||||||
val f3 = ys[0]
|
val f3 = ys[0]
|
||||||
queueEvent {
|
queueEvent {
|
||||||
|
sendNextEventDetails(motionEvent)
|
||||||
sendNextEventTimestamp(timestamp)
|
sendNextEventTimestamp(timestamp)
|
||||||
cocos2dxRenderer.handleActionUp(idUp, f2, f3)
|
cocos2dxRenderer.handleActionUp(idUp, f2, f3)
|
||||||
}
|
}
|
||||||
@@ -195,6 +212,7 @@ class Cocos2dxGLSurfaceView(context: Context) : GLSurfaceView(context) {
|
|||||||
}
|
}
|
||||||
MotionEvent.ACTION_MOVE -> {
|
MotionEvent.ACTION_MOVE -> {
|
||||||
queueEvent {
|
queueEvent {
|
||||||
|
sendNextEventDetails(motionEvent)
|
||||||
sendNextEventTimestamp(timestamp)
|
sendNextEventTimestamp(timestamp)
|
||||||
cocos2dxRenderer.handleActionMove(ids, xs, ys)
|
cocos2dxRenderer.handleActionMove(ids, xs, ys)
|
||||||
}
|
}
|
||||||
@@ -202,6 +220,7 @@ class Cocos2dxGLSurfaceView(context: Context) : GLSurfaceView(context) {
|
|||||||
}
|
}
|
||||||
MotionEvent.ACTION_CANCEL -> {
|
MotionEvent.ACTION_CANCEL -> {
|
||||||
queueEvent {
|
queueEvent {
|
||||||
|
sendNextEventDetails(motionEvent)
|
||||||
sendNextEventTimestamp(timestamp)
|
sendNextEventTimestamp(timestamp)
|
||||||
cocos2dxRenderer.handleActionCancel(ids, xs, ys)
|
cocos2dxRenderer.handleActionCancel(ids, xs, ys)
|
||||||
}
|
}
|
||||||
@@ -213,6 +232,7 @@ class Cocos2dxGLSurfaceView(context: Context) : GLSurfaceView(context) {
|
|||||||
val xPointerDown = motionEvent.getX(indexPointerDown)
|
val xPointerDown = motionEvent.getX(indexPointerDown)
|
||||||
val y = motionEvent.getY(indexPointerDown)
|
val y = motionEvent.getY(indexPointerDown)
|
||||||
queueEvent {
|
queueEvent {
|
||||||
|
sendNextEventDetails(motionEvent)
|
||||||
sendNextEventTimestamp(timestamp)
|
sendNextEventTimestamp(timestamp)
|
||||||
cocos2dxRenderer.handleActionDown(idPointerDown, xPointerDown, y)
|
cocos2dxRenderer.handleActionDown(idPointerDown, xPointerDown, y)
|
||||||
}
|
}
|
||||||
@@ -224,6 +244,7 @@ class Cocos2dxGLSurfaceView(context: Context) : GLSurfaceView(context) {
|
|||||||
val xPointerUp = motionEvent.getX(indexPointUp)
|
val xPointerUp = motionEvent.getX(indexPointUp)
|
||||||
val y2 = motionEvent.getY(indexPointUp)
|
val y2 = motionEvent.getY(indexPointUp)
|
||||||
queueEvent {
|
queueEvent {
|
||||||
|
sendNextEventDetails(motionEvent)
|
||||||
sendNextEventTimestamp(timestamp)
|
sendNextEventTimestamp(timestamp)
|
||||||
cocos2dxRenderer.handleActionUp(idPointerUp, xPointerUp, y2)
|
cocos2dxRenderer.handleActionUp(idPointerUp, xPointerUp, y2)
|
||||||
}
|
}
|
||||||
@@ -273,6 +294,9 @@ class Cocos2dxGLSurfaceView(context: Context) : GLSurfaceView(context) {
|
|||||||
} else {
|
} else {
|
||||||
val currentTime = System.nanoTime()
|
val currentTime = System.nanoTime()
|
||||||
queueEvent {
|
queueEvent {
|
||||||
|
if (controllerEventsEnabled)
|
||||||
|
GeodeUtils.setNextInputDevice(-1, InputDevice.SOURCE_ANY)
|
||||||
|
|
||||||
sendNextEventTimestamp(currentTime)
|
sendNextEventTimestamp(currentTime)
|
||||||
GeodeUtils.nativeKeyDown(KeyEvent.KEYCODE_BACK, 0, false)
|
GeodeUtils.nativeKeyDown(KeyEvent.KEYCODE_BACK, 0, false)
|
||||||
}
|
}
|
||||||
@@ -295,6 +319,7 @@ class Cocos2dxGLSurfaceView(context: Context) : GLSurfaceView(context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
queueEvent {
|
queueEvent {
|
||||||
|
sendNextEventDetails(event)
|
||||||
sendNextEventTimestamp(event.eventTime * MS_TO_NS)
|
sendNextEventTimestamp(event.eventTime * MS_TO_NS)
|
||||||
GeodeUtils.nativeKeyDown(keyCode, event.modifiers, event.repeatCount != 0)
|
GeodeUtils.nativeKeyDown(keyCode, event.modifiers, event.repeatCount != 0)
|
||||||
}
|
}
|
||||||
@@ -318,6 +343,7 @@ class Cocos2dxGLSurfaceView(context: Context) : GLSurfaceView(context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
queueEvent {
|
queueEvent {
|
||||||
|
sendNextEventDetails(event)
|
||||||
sendNextEventTimestamp(event.eventTime * MS_TO_NS)
|
sendNextEventTimestamp(event.eventTime * MS_TO_NS)
|
||||||
GeodeUtils.nativeKeyUp(keyCode, event.modifiers)
|
GeodeUtils.nativeKeyUp(keyCode, event.modifiers)
|
||||||
}
|
}
|
||||||
@@ -327,6 +353,65 @@ class Cocos2dxGLSurfaceView(context: Context) : GLSurfaceView(context) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// i'm lazy.
|
||||||
|
// https://developer.android.com/develop/ui/views/touch-and-input/game-controllers/controller-input
|
||||||
|
private fun getCenteredAxis(
|
||||||
|
event: MotionEvent,
|
||||||
|
device: InputDevice,
|
||||||
|
axis: Int,
|
||||||
|
historyPos: Int
|
||||||
|
): Float {
|
||||||
|
device.getMotionRange(axis, event.source)?.apply {
|
||||||
|
val value: Float = if (historyPos < 0) {
|
||||||
|
event.getAxisValue(axis)
|
||||||
|
} else {
|
||||||
|
event.getHistoricalAxisValue(axis, historyPos)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (abs(value) > flat) {
|
||||||
|
return value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0.0f
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getJoystickMotion(event: MotionEvent, axisHorizontal: Int, axisVertical: Int): Pair<FloatArray, FloatArray> {
|
||||||
|
val positionChangesX = ArrayList<Float>()
|
||||||
|
val positionChangesY = ArrayList<Float>()
|
||||||
|
|
||||||
|
val inputDevice = event.device
|
||||||
|
|
||||||
|
(0 until event.historySize).forEach { i ->
|
||||||
|
val x = getCenteredAxis(event, inputDevice, axisHorizontal, i)
|
||||||
|
val y = getCenteredAxis(event, inputDevice, axisVertical, i)
|
||||||
|
positionChangesX.add(x)
|
||||||
|
positionChangesY.add(y)
|
||||||
|
}
|
||||||
|
|
||||||
|
val x = getCenteredAxis(event, inputDevice, axisHorizontal, -1)
|
||||||
|
val y = getCenteredAxis(event, inputDevice, axisVertical, -1)
|
||||||
|
positionChangesX.add(x)
|
||||||
|
positionChangesY.add(y)
|
||||||
|
|
||||||
|
return Pair(positionChangesX.toFloatArray(), positionChangesY.toFloatArray())
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getJoystickMotion(event: MotionEvent, axis: Int): FloatArray {
|
||||||
|
val positionChanges = ArrayList<Float>()
|
||||||
|
|
||||||
|
val inputDevice = event.device
|
||||||
|
|
||||||
|
(0 until event.historySize).forEach { i ->
|
||||||
|
val x = getCenteredAxis(event, inputDevice, axis, i)
|
||||||
|
positionChanges.add(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
val x = getCenteredAxis(event, inputDevice, axis, -1)
|
||||||
|
positionChanges.add(x)
|
||||||
|
|
||||||
|
return positionChanges.toFloatArray()
|
||||||
|
}
|
||||||
|
|
||||||
override fun onGenericMotionEvent(event: MotionEvent?): Boolean {
|
override fun onGenericMotionEvent(event: MotionEvent?): Boolean {
|
||||||
if (!useKeyboardEvents) {
|
if (!useKeyboardEvents) {
|
||||||
return super.onGenericMotionEvent(event)
|
return super.onGenericMotionEvent(event)
|
||||||
@@ -339,6 +424,7 @@ class Cocos2dxGLSurfaceView(context: Context) : GLSurfaceView(context) {
|
|||||||
event.eventTimeNanos else event.eventTime * MS_TO_NS
|
event.eventTimeNanos else event.eventTime * MS_TO_NS
|
||||||
|
|
||||||
queueEvent {
|
queueEvent {
|
||||||
|
sendNextEventDetails(event)
|
||||||
sendNextEventTimestamp(timestamp)
|
sendNextEventTimestamp(timestamp)
|
||||||
GeodeUtils.nativeActionScroll(scrollX, scrollY)
|
GeodeUtils.nativeActionScroll(scrollX, scrollY)
|
||||||
}
|
}
|
||||||
@@ -346,6 +432,33 @@ class Cocos2dxGLSurfaceView(context: Context) : GLSurfaceView(context) {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (controllerEventsEnabled && event?.action == MotionEvent.ACTION_MOVE && event.source and InputDevice.SOURCE_JOYSTICK == InputDevice.SOURCE_JOYSTICK) {
|
||||||
|
val (motionLeftX, motionLeftY) = getJoystickMotion(event, MotionEvent.AXIS_X, MotionEvent.AXIS_Y)
|
||||||
|
val (motionRightX, motionRightY) = getJoystickMotion(event, MotionEvent.AXIS_Z, MotionEvent.AXIS_RZ)
|
||||||
|
val (motionDPadX, motionDPadY) = getJoystickMotion(event, MotionEvent.AXIS_HAT_X, MotionEvent.AXIS_HAT_Y)
|
||||||
|
|
||||||
|
val motionLTrigger = getJoystickMotion(event, MotionEvent.AXIS_LTRIGGER)
|
||||||
|
val motionRTrigger = getJoystickMotion(event, MotionEvent.AXIS_RTRIGGER)
|
||||||
|
|
||||||
|
// i'm sure this is great for performance
|
||||||
|
val timestamp = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
|
||||||
|
event.eventTimeNanos else event.eventTime * MS_TO_NS
|
||||||
|
|
||||||
|
queueEvent {
|
||||||
|
sendNextEventDetails(event)
|
||||||
|
sendNextEventTimestamp(timestamp)
|
||||||
|
|
||||||
|
GeodeUtils.onJoystickEvent(
|
||||||
|
motionLeftX, motionLeftY,
|
||||||
|
motionRightX, motionRightY,
|
||||||
|
motionDPadX, motionDPadY,
|
||||||
|
motionLTrigger, motionRTrigger
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
return super.onGenericMotionEvent(event)
|
return super.onGenericMotionEvent(event)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -365,4 +478,40 @@ class Cocos2dxGLSurfaceView(context: Context) : GLSurfaceView(context) {
|
|||||||
fun deleteBackward() {
|
fun deleteBackward() {
|
||||||
queueEvent { cocos2dxRenderer.handleDeleteBackward() }
|
queueEvent { cocos2dxRenderer.handleDeleteBackward() }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun enableControllerEvents() {
|
||||||
|
if (controllerEventsEnabled) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
controllerEventsEnabled = true
|
||||||
|
|
||||||
|
val inputManager = context.getSystemService(Context.INPUT_SERVICE) as InputManager
|
||||||
|
inputManager.registerInputDeviceListener(InputListener, null)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun disableControllerEvents() {
|
||||||
|
if (!controllerEventsEnabled) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
controllerEventsEnabled = true
|
||||||
|
|
||||||
|
val inputManager = context.getSystemService(Context.INPUT_SERVICE) as InputManager
|
||||||
|
inputManager.unregisterInputDeviceListener(InputListener)
|
||||||
|
}
|
||||||
|
|
||||||
|
object InputListener : InputManager.InputDeviceListener {
|
||||||
|
override fun onInputDeviceAdded(deviceId: Int) {
|
||||||
|
GeodeUtils.inputDeviceAdded(deviceId)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onInputDeviceChanged(deviceId: Int) {
|
||||||
|
GeodeUtils.inputDeviceChanged(deviceId)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onInputDeviceRemoved(deviceId: Int) {
|
||||||
|
GeodeUtils.inputDeviceRemoved(deviceId)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Reference in new issue
Block a user