fix touch, add toggle for virtual gamepad

This commit is contained in:
Emmanuel Hansen 2023-07-20 16:07:23 +00:00
parent fe5f21fe74
commit 532e915ba7
3 changed files with 184 additions and 26 deletions

View File

@ -50,6 +50,14 @@ class GameController(var activity: Activity, var ryujinxNative: RyujinxNative =
var leftGamePad: GamePad
var rightGamePad: GamePad
var controllerId: Int = -1
val isVisible : Boolean
get() {
controllerView?.apply {
return this.isVisible
}
return false;
}
init {
leftGamePad = GamePad(generateConfig(true), 16f, activity)
@ -97,6 +105,9 @@ class GameController(var activity: Activity, var ryujinxNative: RyujinxNative =
fun setVisible(isVisible: Boolean){
controllerView?.apply {
this.isVisible = isVisible
if(isVisible)
connect()
}
}

View File

@ -33,26 +33,6 @@ class GameHost(context: Context?, val controller: GameController, val mainViewMo
holder.addCallback(this)
}
override fun onTouchEvent(event: MotionEvent?): Boolean {
if (_isStarted)
return when (event!!.actionMasked) {
MotionEvent.ACTION_MOVE -> {
_nativeRyujinx.inputSetTouchPoint(event.x.roundToInt(), event.y.roundToInt())
true
}
MotionEvent.ACTION_DOWN -> {
_nativeRyujinx.inputSetTouchPoint(event.x.roundToInt(), event.y.roundToInt())
true
}
MotionEvent.ACTION_UP -> {
_nativeRyujinx.inputReleaseTouchPoint()
true
}
else -> super.onTouchEvent(event)
}
return super.onTouchEvent(event)
}
override fun surfaceCreated(holder: SurfaceHolder) {
}

View File

@ -1,17 +1,30 @@
package org.ryujinx.android.views
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.PathFillType
import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.graphics.StrokeCap
import androidx.compose.ui.graphics.StrokeJoin
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.graphics.vector.path
import androidx.compose.ui.input.pointer.PointerEventType
import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.unit.dp
import androidx.compose.ui.viewinterop.AndroidView
import androidx.lifecycle.lifecycleScope
@ -20,8 +33,10 @@ import androidx.navigation.compose.composable
import androidx.navigation.compose.rememberNavController
import org.ryujinx.android.GameController
import org.ryujinx.android.GameHost
import org.ryujinx.android.RyujinxNative
import org.ryujinx.android.viewmodels.MainViewModel
import org.ryujinx.android.viewmodels.SettingsViewModel
import kotlin.math.roundToInt
class MainView {
companion object {
@ -40,9 +55,8 @@ class MainView {
@Composable
fun GameView(mainViewModel: MainViewModel){
Box(modifier = Modifier.fillMaxSize()) {
var controller = GameController(mainViewModel.activity)
Surface(color = Color.Green, modifier = Modifier.fillMaxSize()) {
val controller = remember {
GameController(mainViewModel.activity)
}
AndroidView(
modifier = Modifier.fillMaxSize(),
@ -50,11 +64,164 @@ class MainView {
GameHost(context, controller, mainViewModel)
}
)
GameStats(mainViewModel)
controller.Compose(mainViewModel.activity.lifecycleScope, mainViewModel.activity.lifecycle)
GameOverlay(mainViewModel, controller)
}
}
@Composable
fun GameOverlay(mainViewModel: MainViewModel, controller: GameController){
Box(modifier = Modifier.fillMaxSize()) {
GameStats(mainViewModel)
var ryujinxNative = RyujinxNative()
// touch surface
Surface(color = Color.Transparent, modifier = Modifier
.fillMaxSize()
.padding(0.dp)
.pointerInput(Unit) {
awaitPointerEventScope {
while (true) {
Thread.sleep(2);
val event = awaitPointerEvent()
if(controller.isVisible)
continue
var change = event
.component1()
.firstOrNull()
change?.apply {
var position = this.position
if (event.type == PointerEventType.Press) {
ryujinxNative.inputSetTouchPoint(
position.x.roundToInt(),
position.y.roundToInt()
)
} else if (event.type == PointerEventType.Release) {
ryujinxNative.inputReleaseTouchPoint()
} else if (event.type == PointerEventType.Move) {
ryujinxNative.inputSetTouchPoint(
position.x.roundToInt(),
position.y.roundToInt()
)
}
}
}
}
}) {
}
controller.Compose(mainViewModel.activity.lifecycleScope, mainViewModel.activity.lifecycle)
Row(modifier = Modifier
.align(Alignment.BottomCenter)
.padding(8.dp)) {
IconButton(modifier = Modifier.padding(4.dp),onClick = {
controller.setVisible(!controller.isVisible)
}) {
Icon(imageVector = rememberVideogameAsset(), contentDescription = "Toggle Virtual Pad")
}
}
}
}
@Composable
fun rememberVideogameAsset(): ImageVector {
var primaryColor = MaterialTheme.colorScheme.primary
return remember {
ImageVector.Builder(
name = "videogame_asset",
defaultWidth = 40.0.dp,
defaultHeight = 40.0.dp,
viewportWidth = 40.0f,
viewportHeight = 40.0f
).apply {
path(
fill = SolidColor(Color.Black.copy(alpha = 0.5f)),
fillAlpha = 1f,
stroke = SolidColor(primaryColor),
strokeAlpha = 1f,
strokeLineWidth = 1.0f,
strokeLineCap = StrokeCap.Butt,
strokeLineJoin = StrokeJoin.Miter,
strokeLineMiter = 1f,
pathFillType = PathFillType.NonZero
) {
moveTo(6.25f, 29.792f)
quadToRelative(-1.083f, 0f, -1.854f, -0.792f)
quadToRelative(-0.771f, -0.792f, -0.771f, -1.833f)
verticalLineTo(12.833f)
quadToRelative(0f, -1.083f, 0.771f, -1.854f)
quadToRelative(0.771f, -0.771f, 1.854f, -0.771f)
horizontalLineToRelative(27.5f)
quadToRelative(1.083f, 0f, 1.854f, 0.771f)
quadToRelative(0.771f, 0.771f, 0.771f, 1.854f)
verticalLineToRelative(14.334f)
quadToRelative(0f, 1.041f, -0.771f, 1.833f)
reflectiveQuadToRelative(-1.854f, 0.792f)
close()
moveToRelative(0f, -2.625f)
horizontalLineToRelative(27.5f)
verticalLineTo(12.833f)
horizontalLineTo(6.25f)
verticalLineToRelative(14.334f)
close()
moveToRelative(7.167f, -1.792f)
quadToRelative(0.541f, 0f, 0.916f, -0.375f)
reflectiveQuadToRelative(0.375f, -0.917f)
verticalLineToRelative(-2.791f)
horizontalLineToRelative(2.75f)
quadToRelative(0.584f, 0f, 0.959f, -0.375f)
reflectiveQuadToRelative(0.375f, -0.917f)
quadToRelative(0f, -0.542f, -0.375f, -0.938f)
quadToRelative(-0.375f, -0.395f, -0.959f, -0.395f)
horizontalLineToRelative(-2.75f)
verticalLineToRelative(-2.75f)
quadToRelative(0f, -0.542f, -0.375f, -0.938f)
quadToRelative(-0.375f, -0.396f, -0.916f, -0.396f)
quadToRelative(-0.584f, 0f, -0.959f, 0.396f)
reflectiveQuadToRelative(-0.375f, 0.938f)
verticalLineToRelative(2.75f)
horizontalLineToRelative(-2.75f)
quadToRelative(-0.541f, 0f, -0.937f, 0.395f)
quadTo(8f, 19.458f, 8f, 20f)
quadToRelative(0f, 0.542f, 0.396f, 0.917f)
reflectiveQuadToRelative(0.937f, 0.375f)
horizontalLineToRelative(2.75f)
verticalLineToRelative(2.791f)
quadToRelative(0f, 0.542f, 0.396f, 0.917f)
reflectiveQuadToRelative(0.938f, 0.375f)
close()
moveToRelative(11.125f, -0.5f)
quadToRelative(0.791f, 0f, 1.396f, -0.583f)
quadToRelative(0.604f, -0.584f, 0.604f, -1.375f)
quadToRelative(0f, -0.834f, -0.604f, -1.417f)
quadToRelative(-0.605f, -0.583f, -1.396f, -0.583f)
quadToRelative(-0.834f, 0f, -1.417f, 0.583f)
quadToRelative(-0.583f, 0.583f, -0.583f, 1.375f)
quadToRelative(0f, 0.833f, 0.583f, 1.417f)
quadToRelative(0.583f, 0.583f, 1.417f, 0.583f)
close()
moveToRelative(3.916f, -5.833f)
quadToRelative(0.834f, 0f, 1.417f, -0.584f)
quadToRelative(0.583f, -0.583f, 0.583f, -1.416f)
quadToRelative(0f, -0.792f, -0.583f, -1.375f)
quadToRelative(-0.583f, -0.584f, -1.417f, -0.584f)
quadToRelative(-0.791f, 0f, -1.375f, 0.584f)
quadToRelative(-0.583f, 0.583f, -0.583f, 1.375f)
quadToRelative(0f, 0.833f, 0.583f, 1.416f)
quadToRelative(0.584f, 0.584f, 1.375f, 0.584f)
close()
moveTo(6.25f, 27.167f)
verticalLineTo(12.833f)
verticalLineToRelative(14.334f)
close()
}
}.build()
}
}
@Composable
fun GameStats(mainViewModel: MainViewModel){
var fifo = remember {