Enhancements
Implements fat touch detection for playing on mobile phones. Allows using the whole screen as touch area when not using touch air mode. Optimize codes to lower minimum required SDK version to 17.pull/1/head
parent
84b95e9610
commit
fb4e41b40e
|
@ -9,7 +9,7 @@ android {
|
||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
applicationId "com.github.brokenithm"
|
applicationId "com.github.brokenithm"
|
||||||
minSdkVersion 23
|
minSdkVersion 17
|
||||||
targetSdkVersion 30
|
targetSdkVersion 30
|
||||||
versionCode 10100
|
versionCode 10100
|
||||||
versionName "1.1.0"
|
versionName "1.1.0"
|
||||||
|
|
|
@ -43,11 +43,13 @@ class MainActivity : AppCompatActivity() {
|
||||||
private val numOfGaps = 16
|
private val numOfGaps = 16
|
||||||
private val buttonWidthToGap = 7.428571f
|
private val buttonWidthToGap = 7.428571f
|
||||||
private val numOfAirBlock = 6
|
private val numOfAirBlock = 6
|
||||||
|
private val fatTouchSizeThreshold = 0.034f
|
||||||
|
private val extraFatTouchSizeThreshold = 0.041f
|
||||||
private var mCurrentDelay = 0f
|
private var mCurrentDelay = 0f
|
||||||
|
|
||||||
// Buttons
|
// Buttons
|
||||||
private var mCurrentAirHeight = 6
|
private var mCurrentAirHeight = 6
|
||||||
private var mLastButtons = mutableSetOf<Int>()
|
private var mLastButtons = HashSet<Int>()
|
||||||
private var mTestButton = false
|
private var mTestButton = false
|
||||||
private var mServiceButton = false
|
private var mServiceButton = false
|
||||||
private data class InputEvent(val keys: MutableSet<Int>? = null, val airHeight : Int = 6, val testButton: Boolean = false, val serviceButton: Boolean = false)
|
private data class InputEvent(val keys: MutableSet<Int>? = null, val airHeight : Int = 6, val testButton: Boolean = false, val serviceButton: Boolean = false)
|
||||||
|
@ -194,9 +196,12 @@ class MainActivity : AppCompatActivity() {
|
||||||
textExpand.callOnClick()
|
textExpand.callOnClick()
|
||||||
view ?: return@setOnTouchListener view.performClick()
|
view ?: return@setOnTouchListener view.performClick()
|
||||||
event ?: return@setOnTouchListener view.performClick()
|
event ?: return@setOnTouchListener view.performClick()
|
||||||
|
val currentAirAreaHeight = if (mAirSource != 3) 0f else airAreaHeight
|
||||||
|
val currentButtonAreaHeight = if (mAirSource != 3) 0f else buttonAreaHeight
|
||||||
val totalTouches = event.pointerCount
|
val totalTouches = event.pointerCount
|
||||||
val touchedButtons = mutableSetOf<Int>()
|
val touchedButtons = HashSet<Int>()
|
||||||
var thisAirHeight = 6
|
var thisAirHeight = 6
|
||||||
|
var maxTouchedSize = 0f
|
||||||
if (event.action != KeyEvent.ACTION_UP && event.action != MotionEvent.ACTION_CANCEL) {
|
if (event.action != KeyEvent.ACTION_UP && event.action != MotionEvent.ACTION_CANCEL) {
|
||||||
var ignoredIndex = -1
|
var ignoredIndex = -1
|
||||||
if (event.actionMasked == MotionEvent.ACTION_POINTER_UP)
|
if (event.actionMasked == MotionEvent.ACTION_POINTER_UP)
|
||||||
|
@ -207,14 +212,14 @@ class MainActivity : AppCompatActivity() {
|
||||||
val x = event.getX(i) + view.left
|
val x = event.getX(i) + view.left
|
||||||
val y = event.getY(i) + view.top
|
val y = event.getY(i) + view.top
|
||||||
when(y) {
|
when(y) {
|
||||||
in 0f..airAreaHeight -> {
|
in 0f..currentAirAreaHeight -> {
|
||||||
thisAirHeight = 0
|
thisAirHeight = 0
|
||||||
}
|
}
|
||||||
in airAreaHeight..buttonAreaHeight -> {
|
in currentAirAreaHeight..currentButtonAreaHeight -> {
|
||||||
val curAir = ((y - airAreaHeight) / airBlockHeight).toInt()
|
val curAir = ((y - airAreaHeight) / airBlockHeight).toInt()
|
||||||
thisAirHeight = if(mSimpleAir) 0 else thisAirHeight.coerceAtMost(curAir)
|
thisAirHeight = if(mSimpleAir) 0 else thisAirHeight.coerceAtMost(curAir)
|
||||||
}
|
}
|
||||||
in buttonAreaHeight..windowHeight.toFloat() -> {
|
in currentButtonAreaHeight..windowHeight.toFloat() -> {
|
||||||
//val centerButton = (x / buttonBlockWidth).toInt() + 1
|
//val centerButton = (x / buttonBlockWidth).toInt() + 1
|
||||||
//val leftButton = (centerButton - 1).coerceAtLeast(1)
|
//val leftButton = (centerButton - 1).coerceAtLeast(1)
|
||||||
//val rightButton = (centerButton + 1).coerceAtMost(32)
|
//val rightButton = (centerButton + 1).coerceAtMost(32)
|
||||||
|
@ -223,9 +228,49 @@ class MainActivity : AppCompatActivity() {
|
||||||
val pointPos = x / buttonBlockWidth
|
val pointPos = x / buttonBlockWidth
|
||||||
var index = pointPos.toInt()
|
var index = pointPos.toInt()
|
||||||
if (index > numOfButtons) index = numOfButtons
|
if (index > numOfButtons) index = numOfButtons
|
||||||
var realIndex = index * 2
|
|
||||||
if (touchedButtons.contains(realIndex)) realIndex++
|
var centerButton = index * 2
|
||||||
touchedButtons.add(realIndex)
|
if (touchedButtons.contains(centerButton)) centerButton++
|
||||||
|
var leftButton = ((index - 1) * 2).coerceAtLeast(0)
|
||||||
|
if (touchedButtons.contains(leftButton)) leftButton++
|
||||||
|
var rightButton = ((index + 1) * 2).coerceAtMost(numOfButtons * 2)
|
||||||
|
if (touchedButtons.contains(rightButton)) rightButton++
|
||||||
|
var left2Button = ((index - 2) * 2).coerceAtLeast(0)
|
||||||
|
if (touchedButtons.contains(left2Button)) left2Button++
|
||||||
|
var right2Button = ((index + 2) * 2).coerceAtMost(numOfButtons * 2)
|
||||||
|
if (touchedButtons.contains(right2Button)) right2Button++
|
||||||
|
|
||||||
|
val currentSize = event.getSize(i)
|
||||||
|
maxTouchedSize = maxTouchedSize.coerceAtLeast(currentSize)
|
||||||
|
|
||||||
|
touchedButtons.add(centerButton)
|
||||||
|
when ((pointPos - index) * 4) {
|
||||||
|
in 0f..1f -> {
|
||||||
|
touchedButtons.add(leftButton)
|
||||||
|
if (currentSize >= extraFatTouchSizeThreshold) {
|
||||||
|
touchedButtons.add(left2Button)
|
||||||
|
touchedButtons.add(rightButton)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
in 1f..3f -> {
|
||||||
|
if (currentSize >= fatTouchSizeThreshold) {
|
||||||
|
touchedButtons.add(leftButton)
|
||||||
|
touchedButtons.add(rightButton)
|
||||||
|
}
|
||||||
|
if (currentSize >= extraFatTouchSizeThreshold) {
|
||||||
|
touchedButtons.add(left2Button)
|
||||||
|
touchedButtons.add(right2Button)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
in 3f..4f -> {
|
||||||
|
touchedButtons.add(rightButton)
|
||||||
|
if (currentSize >= extraFatTouchSizeThreshold) {
|
||||||
|
touchedButtons.add(leftButton)
|
||||||
|
touchedButtons.add(right2Button)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*
|
||||||
if (index > 0) {
|
if (index > 0) {
|
||||||
if ((pointPos - index) * 4 < 1) {
|
if ((pointPos - index) * 4 < 1) {
|
||||||
realIndex = (index - 1) * 2
|
realIndex = (index - 1) * 2
|
||||||
|
@ -239,6 +284,7 @@ class MainActivity : AppCompatActivity() {
|
||||||
touchedButtons.add(realIndex)
|
touchedButtons.add(realIndex)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -256,7 +302,7 @@ class MainActivity : AppCompatActivity() {
|
||||||
mCurrentAirHeight = thisAirHeight
|
mCurrentAirHeight = thisAirHeight
|
||||||
//mInputQueue.add(InputEvent(touchedButtons, mCurrentAirHeight))
|
//mInputQueue.add(InputEvent(touchedButtons, mCurrentAirHeight))
|
||||||
if (mDebugInfo)
|
if (mDebugInfo)
|
||||||
textInfo.text = getString(R.string.debug_info, mCurrentAirHeight, touchedButtons.toString(), event.toString())
|
textInfo.text = getString(R.string.debug_info, mCurrentAirHeight, touchedButtons.toString(), maxTouchedSize, event.toString())
|
||||||
view.performClick()
|
view.performClick()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -432,7 +478,7 @@ class MainActivity : AppCompatActivity() {
|
||||||
super.onResume()
|
super.onResume()
|
||||||
if (mSensorManager == null)
|
if (mSensorManager == null)
|
||||||
mSensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager
|
mSensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager
|
||||||
val gyro = mSensorManager?.getDefaultSensor(Sensor.TYPE_GAME_ROTATION_VECTOR)
|
val gyro = mSensorManager?.getDefaultSensor(if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) Sensor.TYPE_GAME_ROTATION_VECTOR else Sensor.TYPE_ROTATION_VECTOR)
|
||||||
mSensorManager?.registerListener(listener, gyro, 10000)
|
mSensorManager?.registerListener(listener, gyro, 10000)
|
||||||
val accel = mSensorManager?.getDefaultSensor(Sensor.TYPE_LINEAR_ACCELERATION)
|
val accel = mSensorManager?.getDefaultSensor(Sensor.TYPE_LINEAR_ACCELERATION)
|
||||||
mSensorManager?.registerListener(listener, accel, 10000)
|
mSensorManager?.registerListener(listener, accel, 10000)
|
||||||
|
@ -531,10 +577,17 @@ class MainActivity : AppCompatActivity() {
|
||||||
}
|
}
|
||||||
val buffer = ByteArray(256)
|
val buffer = ByteArray(256)
|
||||||
val packet = DatagramPacket(buffer, buffer.size)
|
val packet = DatagramPacket(buffer, buffer.size)
|
||||||
|
fun InetSocketAddress.toHostString(): String? {
|
||||||
|
if (hostName != null)
|
||||||
|
return hostName
|
||||||
|
if (this.address != null)
|
||||||
|
return this.address.hostName ?: this.address.hostAddress
|
||||||
|
return null
|
||||||
|
}
|
||||||
while (!mExitFlag) {
|
while (!mExitFlag) {
|
||||||
try {
|
try {
|
||||||
socket.receive(packet)
|
socket.receive(packet)
|
||||||
if (packet.address.hostAddress == address.hostString && packet.port == address.port) {
|
if (packet.address.hostAddress == address.toHostString() && packet.port == address.port) {
|
||||||
val data = packet.data
|
val data = packet.data
|
||||||
if (data.size >= 3) {
|
if (data.size >= 3) {
|
||||||
if (data.size >= 100 && data[1] == 'L'.toByte() && data[2] == 'E'.toByte() && data[3] == 'D'.toByte()) {
|
if (data.size >= 100 && data[1] == 'L'.toByte() && data[2] == 'E'.toByte() && data[3] == 'D'.toByte()) {
|
||||||
|
@ -601,21 +654,17 @@ class MainActivity : AppCompatActivity() {
|
||||||
while (!mExitFlag) {
|
while (!mExitFlag) {
|
||||||
if (mShowDelay)
|
if (mShowDelay)
|
||||||
sendPing(address)
|
sendPing(address)
|
||||||
//while (!mInputQueue.isEmpty() && mInputQueue.peek() == null)
|
|
||||||
//mInputQueue.pop()
|
|
||||||
//val buttons = mInputQueue.poll()
|
|
||||||
val buttons = InputEvent(mLastButtons, mCurrentAirHeight, mTestButton, mServiceButton)
|
val buttons = InputEvent(mLastButtons, mCurrentAirHeight, mTestButton, mServiceButton)
|
||||||
if (buttons != null/* || mLastAirHeight != mCurrentAirHeight*/) {
|
val buffer = applyKeys(buttons/* ?: InputEvent()*/, IoBuffer())
|
||||||
val buffer = applyKeys(buttons/* ?: InputEvent()*/, IoBuffer())
|
val packet = constructPacket(buffer)
|
||||||
val packet = constructPacket(buffer)
|
try {
|
||||||
try {
|
socket.send(packet)
|
||||||
socket.send(packet)
|
} catch (e: Exception) {
|
||||||
} catch (e: Exception) {
|
e.printStackTrace()
|
||||||
e.printStackTrace()
|
Thread.sleep(100)
|
||||||
Thread.sleep(100)
|
continue
|
||||||
continue
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
//Thread.sleep(2)
|
||||||
Thread.sleep(1)
|
Thread.sleep(1)
|
||||||
}
|
}
|
||||||
socket.close()
|
socket.close()
|
||||||
|
|
|
@ -116,7 +116,7 @@
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginStart="8dp"
|
android:layout_marginStart="8dp"
|
||||||
android:layout_marginTop="8dp"
|
android:layout_marginTop="8dp"
|
||||||
android:text="Enable Air"
|
android:text="@string/enable_air"
|
||||||
android:textColor="@color/white"
|
android:textColor="@color/white"
|
||||||
android:visibility="gone"
|
android:visibility="gone"
|
||||||
app:layout_constraintStart_toEndOf="@+id/button_card"
|
app:layout_constraintStart_toEndOf="@+id/button_card"
|
||||||
|
@ -131,7 +131,7 @@
|
||||||
android:foreground="?android:attr/selectableItemBackground"
|
android:foreground="?android:attr/selectableItemBackground"
|
||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:padding="8dp"
|
android:padding="8dp"
|
||||||
android:text="Disable Air"
|
android:text="@string/disable_air"
|
||||||
android:textColor="@color/white"
|
android:textColor="@color/white"
|
||||||
android:textStyle="bold"
|
android:textStyle="bold"
|
||||||
app:layout_constraintBottom_toBottomOf="@+id/button_card"
|
app:layout_constraintBottom_toBottomOf="@+id/button_card"
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
<string name="test">Test</string>
|
<string name="test">Test</string>
|
||||||
<string name="service">Service</string>
|
<string name="service">Service</string>
|
||||||
<string name="show_debug_info">Debug</string>
|
<string name="show_debug_info">Debug</string>
|
||||||
<string name="debug_info">touched: air:%d %s\n%s</string>
|
<string name="debug_info">touched: air:%d %s size:%f\n%s</string>
|
||||||
<string name="current_latency">Current Latency: %f ms</string>
|
<string name="current_latency">Current Latency: %f ms</string>
|
||||||
<string name="press_again_to_exit">Press again to exit</string>
|
<string name="press_again_to_exit">Press again to exit</string>
|
||||||
<string name="show_delay">Show Delay</string>
|
<string name="show_delay">Show Delay</string>
|
||||||
|
@ -26,4 +26,5 @@
|
||||||
<string name="gyro_air">Gyro Air</string>
|
<string name="gyro_air">Gyro Air</string>
|
||||||
<string name="accel_air">Accel Air</string>
|
<string name="accel_air">Accel Air</string>
|
||||||
<string name="touch_air">Touch Air</string>
|
<string name="touch_air">Touch Air</string>
|
||||||
|
<string name="enable_air">Enable Air</string>
|
||||||
</resources>
|
</resources>
|
Loading…
Reference in New Issue