forked from MeloNX/MeloNX
add bottom popup ingame
This commit is contained in:
parent
0bf93ef754
commit
8c0bd460d9
@ -36,6 +36,7 @@ android {
|
|||||||
release {
|
release {
|
||||||
minifyEnabled false
|
minifyEnabled false
|
||||||
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
|
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
|
||||||
|
signingConfig signingConfigs.debug
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
compileOptions {
|
compileOptions {
|
||||||
@ -92,6 +93,7 @@ dependencies {
|
|||||||
implementation "androidx.preference:preference-ktx:1.2.0"
|
implementation "androidx.preference:preference-ktx:1.2.0"
|
||||||
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.2'
|
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.2'
|
||||||
implementation 'com.google.code.gson:gson:2.10.1'
|
implementation 'com.google.code.gson:gson:2.10.1'
|
||||||
|
implementation("br.com.devsrsouza.compose.icons:css-gg:1.1.0")
|
||||||
implementation "io.coil-kt:coil-compose:2.4.0"
|
implementation "io.coil-kt:coil-compose:2.4.0"
|
||||||
testImplementation 'junit:junit:4.13.2'
|
testImplementation 'junit:junit:4.13.2'
|
||||||
androidTestImplementation 'androidx.test.ext:junit:1.1.5'
|
androidTestImplementation 'androidx.test.ext:junit:1.1.5'
|
||||||
|
@ -224,4 +224,4 @@ extern "C"
|
|||||||
void debug_break(int code){
|
void debug_break(int code){
|
||||||
if(code >= 3)
|
if(code >= 3)
|
||||||
int r = 0;
|
int r = 0;
|
||||||
}
|
}
|
||||||
|
@ -46,15 +46,17 @@ class GameController(var activity: Activity) {
|
|||||||
return view
|
return view
|
||||||
}
|
}
|
||||||
@Composable
|
@Composable
|
||||||
fun Compose(viewModel: MainViewModel) : Unit
|
fun Compose(viewModel: MainViewModel) : Unit {
|
||||||
{
|
|
||||||
AndroidView(
|
AndroidView(
|
||||||
modifier = Modifier.fillMaxSize(), factory = { context ->
|
modifier = Modifier.fillMaxSize(), factory = { context ->
|
||||||
val controller = GameController(viewModel.activity)
|
val controller = GameController(viewModel.activity)
|
||||||
val c = Create(context, viewModel.activity, controller)
|
val c = Create(context, viewModel.activity, controller)
|
||||||
viewModel.activity.lifecycleScope.apply {
|
viewModel.activity.lifecycleScope.apply {
|
||||||
viewModel.activity.lifecycleScope.launch {
|
viewModel.activity.lifecycleScope.launch {
|
||||||
val events = merge(controller.leftGamePad.events(),controller.rightGamePad.events())
|
val events = merge(
|
||||||
|
controller.leftGamePad.events(),
|
||||||
|
controller.rightGamePad.events()
|
||||||
|
)
|
||||||
.shareIn(viewModel.activity.lifecycleScope, SharingStarted.Lazily)
|
.shareIn(viewModel.activity.lifecycleScope, SharingStarted.Lazily)
|
||||||
events.safeCollect {
|
events.safeCollect {
|
||||||
controller.handleEvent(it)
|
controller.handleEvent(it)
|
||||||
|
@ -1,8 +1,14 @@
|
|||||||
package org.ryujinx.android
|
package org.ryujinx.android
|
||||||
|
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.material.icons.Icons
|
||||||
|
import androidx.compose.material.icons.filled.KeyboardArrowUp
|
||||||
|
import androidx.compose.material3.Icon
|
||||||
|
import androidx.compose.material3.IconButton
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.graphics.PathFillType
|
import androidx.compose.ui.graphics.PathFillType
|
||||||
import androidx.compose.ui.graphics.SolidColor
|
import androidx.compose.ui.graphics.SolidColor
|
||||||
@ -10,13 +16,17 @@ import androidx.compose.ui.graphics.StrokeCap
|
|||||||
import androidx.compose.ui.graphics.StrokeJoin
|
import androidx.compose.ui.graphics.StrokeJoin
|
||||||
import androidx.compose.ui.graphics.vector.ImageVector
|
import androidx.compose.ui.graphics.vector.ImageVector
|
||||||
import androidx.compose.ui.graphics.vector.path
|
import androidx.compose.ui.graphics.vector.path
|
||||||
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
|
import compose.icons.CssGgIcons
|
||||||
|
import compose.icons.cssggicons.Games
|
||||||
|
|
||||||
class Icons {
|
class Icons {
|
||||||
companion object{
|
companion object{
|
||||||
/// Icons exported from https://www.composables.com/icons
|
/// Icons exported from https://www.composables.com/icons
|
||||||
@Composable
|
@Composable
|
||||||
fun Download(): ImageVector {
|
fun download(): ImageVector {
|
||||||
|
val primaryColor = MaterialTheme.colorScheme.primary
|
||||||
return remember {
|
return remember {
|
||||||
ImageVector.Builder(
|
ImageVector.Builder(
|
||||||
name = "download",
|
name = "download",
|
||||||
@ -26,9 +36,9 @@ class Icons {
|
|||||||
viewportHeight = 40.0f
|
viewportHeight = 40.0f
|
||||||
).apply {
|
).apply {
|
||||||
path(
|
path(
|
||||||
fill = SolidColor(Color.Black),
|
fill = SolidColor(Color.Black.copy(alpha = 0.5f)),
|
||||||
|
stroke = SolidColor(primaryColor),
|
||||||
fillAlpha = 1f,
|
fillAlpha = 1f,
|
||||||
stroke = null,
|
|
||||||
strokeAlpha = 1f,
|
strokeAlpha = 1f,
|
||||||
strokeLineWidth = 1.0f,
|
strokeLineWidth = 1.0f,
|
||||||
strokeLineCap = StrokeCap.Butt,
|
strokeLineCap = StrokeCap.Butt,
|
||||||
@ -84,7 +94,77 @@ class Icons {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
@Composable
|
@Composable
|
||||||
fun VideoGame(): ImageVector {
|
fun vSync(): ImageVector {
|
||||||
|
val primaryColor = MaterialTheme.colorScheme.primary
|
||||||
|
return remember {
|
||||||
|
ImageVector.Builder(
|
||||||
|
name = "60fps",
|
||||||
|
defaultWidth = 40.0.dp,
|
||||||
|
defaultHeight = 40.0.dp,
|
||||||
|
viewportWidth = 40.0f,
|
||||||
|
viewportHeight = 40.0f
|
||||||
|
).apply {
|
||||||
|
path(
|
||||||
|
fill = SolidColor(Color.Black.copy(alpha = 0.5f)),
|
||||||
|
stroke = SolidColor(primaryColor),
|
||||||
|
fillAlpha = 1f,
|
||||||
|
strokeAlpha = 1f,
|
||||||
|
strokeLineWidth = 1.0f,
|
||||||
|
strokeLineCap = StrokeCap.Butt,
|
||||||
|
strokeLineJoin = StrokeJoin.Miter,
|
||||||
|
strokeLineMiter = 1f,
|
||||||
|
pathFillType = PathFillType.NonZero
|
||||||
|
) {
|
||||||
|
moveTo(7.292f, 31.458f)
|
||||||
|
quadToRelative(-1.542f, 0f, -2.625f, -1.041f)
|
||||||
|
quadToRelative(-1.084f, -1.042f, -1.084f, -2.625f)
|
||||||
|
verticalLineTo(12.208f)
|
||||||
|
quadToRelative(0f, -1.583f, 1.084f, -2.625f)
|
||||||
|
quadTo(5.75f, 8.542f, 7.292f, 8.542f)
|
||||||
|
horizontalLineTo(14f)
|
||||||
|
quadToRelative(0.75f, 0f, 1.292f, 0.541f)
|
||||||
|
quadToRelative(0.541f, 0.542f, 0.541f, 1.292f)
|
||||||
|
reflectiveQuadToRelative(-0.541f, 1.292f)
|
||||||
|
quadToRelative(-0.542f, 0.541f, -1.292f, 0.541f)
|
||||||
|
horizontalLineTo(7.208f)
|
||||||
|
verticalLineToRelative(5.084f)
|
||||||
|
horizontalLineToRelative(6.709f)
|
||||||
|
quadToRelative(1.541f, 0f, 2.583f, 1.041f)
|
||||||
|
quadToRelative(1.042f, 1.042f, 1.042f, 2.625f)
|
||||||
|
verticalLineToRelative(6.834f)
|
||||||
|
quadToRelative(0f, 1.583f, -1.042f, 2.625f)
|
||||||
|
quadToRelative(-1.042f, 1.041f, -2.583f, 1.041f)
|
||||||
|
close()
|
||||||
|
moveToRelative(-0.084f, -10.5f)
|
||||||
|
verticalLineToRelative(6.834f)
|
||||||
|
horizontalLineToRelative(6.709f)
|
||||||
|
verticalLineToRelative(-6.834f)
|
||||||
|
close()
|
||||||
|
moveToRelative(17.125f, 6.834f)
|
||||||
|
horizontalLineToRelative(8.459f)
|
||||||
|
verticalLineTo(12.208f)
|
||||||
|
horizontalLineToRelative(-8.459f)
|
||||||
|
verticalLineToRelative(15.584f)
|
||||||
|
close()
|
||||||
|
moveToRelative(0f, 3.666f)
|
||||||
|
quadToRelative(-1.541f, 0f, -2.583f, -1.041f)
|
||||||
|
quadToRelative(-1.042f, -1.042f, -1.042f, -2.625f)
|
||||||
|
verticalLineTo(12.208f)
|
||||||
|
quadToRelative(0f, -1.583f, 1.042f, -2.625f)
|
||||||
|
quadToRelative(1.042f, -1.041f, 2.583f, -1.041f)
|
||||||
|
horizontalLineToRelative(8.459f)
|
||||||
|
quadToRelative(1.541f, 0f, 2.583f, 1.041f)
|
||||||
|
quadToRelative(1.042f, 1.042f, 1.042f, 2.625f)
|
||||||
|
verticalLineToRelative(15.584f)
|
||||||
|
quadToRelative(0f, 1.583f, -1.042f, 2.625f)
|
||||||
|
quadToRelative(-1.042f, 1.041f, -2.583f, 1.041f)
|
||||||
|
close()
|
||||||
|
}
|
||||||
|
}.build()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@Composable
|
||||||
|
fun videoGame(): ImageVector {
|
||||||
val primaryColor = MaterialTheme.colorScheme.primary
|
val primaryColor = MaterialTheme.colorScheme.primary
|
||||||
return remember {
|
return remember {
|
||||||
ImageVector.Builder(
|
ImageVector.Builder(
|
||||||
@ -96,8 +176,8 @@ class Icons {
|
|||||||
).apply {
|
).apply {
|
||||||
path(
|
path(
|
||||||
fill = SolidColor(Color.Black.copy(alpha = 0.5f)),
|
fill = SolidColor(Color.Black.copy(alpha = 0.5f)),
|
||||||
fillAlpha = 1f,
|
|
||||||
stroke = SolidColor(primaryColor),
|
stroke = SolidColor(primaryColor),
|
||||||
|
fillAlpha = 1f,
|
||||||
strokeAlpha = 1f,
|
strokeAlpha = 1f,
|
||||||
strokeLineWidth = 1.0f,
|
strokeLineWidth = 1.0f,
|
||||||
strokeLineCap = StrokeCap.Butt,
|
strokeLineCap = StrokeCap.Butt,
|
||||||
@ -179,4 +259,16 @@ class Icons {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Preview
|
||||||
|
@Composable
|
||||||
|
fun Preview(){
|
||||||
|
IconButton(modifier = Modifier.padding(4.dp), onClick = {
|
||||||
|
}) {
|
||||||
|
Icon(
|
||||||
|
imageVector = CssGgIcons.Games,
|
||||||
|
contentDescription = "Open Panel"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -228,6 +228,7 @@ class HomeViews {
|
|||||||
mutableStateListOf<GameModel>()
|
mutableStateListOf<GameModel>()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if(refresh.value) {
|
if(refresh.value) {
|
||||||
viewModel.setViewList(list)
|
viewModel.setViewList(list)
|
||||||
refresh.value = false
|
refresh.value = false
|
||||||
@ -342,7 +343,7 @@ class HomeViews {
|
|||||||
) {
|
) {
|
||||||
Column(modifier = Modifier.padding(16.dp)) {
|
Column(modifier = Modifier.padding(16.dp)) {
|
||||||
Icon(
|
Icon(
|
||||||
imageVector = org.ryujinx.android.Icons.Download(),
|
imageVector = org.ryujinx.android.Icons.download(),
|
||||||
contentDescription = "Game Dlc",
|
contentDescription = "Game Dlc",
|
||||||
tint = Color.Green,
|
tint = Color.Green,
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
|
@ -25,24 +25,22 @@ import androidx.compose.runtime.remember
|
|||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.graphics.Color
|
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.PointerEventType
|
||||||
import androidx.compose.ui.input.pointer.pointerInput
|
import androidx.compose.ui.input.pointer.pointerInput
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.viewinterop.AndroidView
|
import androidx.compose.ui.viewinterop.AndroidView
|
||||||
|
import androidx.compose.ui.window.Popup
|
||||||
import androidx.navigation.compose.NavHost
|
import androidx.navigation.compose.NavHost
|
||||||
import androidx.navigation.compose.composable
|
import androidx.navigation.compose.composable
|
||||||
import androidx.navigation.compose.rememberNavController
|
import androidx.navigation.compose.rememberNavController
|
||||||
|
import compose.icons.CssGgIcons
|
||||||
|
import compose.icons.cssggicons.ToolbarBottom
|
||||||
import org.ryujinx.android.GameController
|
import org.ryujinx.android.GameController
|
||||||
import org.ryujinx.android.GameHost
|
import org.ryujinx.android.GameHost
|
||||||
import org.ryujinx.android.Icons
|
import org.ryujinx.android.Icons
|
||||||
import org.ryujinx.android.RyujinxNative
|
import org.ryujinx.android.RyujinxNative
|
||||||
import org.ryujinx.android.viewmodels.MainViewModel
|
import org.ryujinx.android.viewmodels.MainViewModel
|
||||||
|
import org.ryujinx.android.viewmodels.QuickSettings
|
||||||
import org.ryujinx.android.viewmodels.SettingsViewModel
|
import org.ryujinx.android.viewmodels.SettingsViewModel
|
||||||
import kotlin.math.roundToInt
|
import kotlin.math.roundToInt
|
||||||
|
|
||||||
@ -88,6 +86,16 @@ class MainView {
|
|||||||
|
|
||||||
val ryujinxNative = RyujinxNative()
|
val ryujinxNative = RyujinxNative()
|
||||||
|
|
||||||
|
var showController = remember {
|
||||||
|
mutableStateOf(QuickSettings(mainViewModel.activity).useVirtualController)
|
||||||
|
}
|
||||||
|
var enableVsync = remember {
|
||||||
|
mutableStateOf(QuickSettings(mainViewModel.activity).enableVsync)
|
||||||
|
}
|
||||||
|
var showMore = remember {
|
||||||
|
mutableStateOf(false)
|
||||||
|
}
|
||||||
|
|
||||||
// touch surface
|
// touch surface
|
||||||
Surface(color = Color.Transparent, modifier = Modifier
|
Surface(color = Color.Transparent, modifier = Modifier
|
||||||
.fillMaxSize()
|
.fillMaxSize()
|
||||||
@ -95,8 +103,9 @@ class MainView {
|
|||||||
.pointerInput(Unit) {
|
.pointerInput(Unit) {
|
||||||
awaitPointerEventScope {
|
awaitPointerEventScope {
|
||||||
while (true) {
|
while (true) {
|
||||||
Thread.sleep(2)
|
|
||||||
val event = awaitPointerEvent()
|
val event = awaitPointerEvent()
|
||||||
|
if (!showController.value)
|
||||||
|
continue
|
||||||
|
|
||||||
val change = event
|
val change = event
|
||||||
.component1()
|
.component1()
|
||||||
@ -137,15 +146,46 @@ class MainView {
|
|||||||
.padding(8.dp)
|
.padding(8.dp)
|
||||||
) {
|
) {
|
||||||
IconButton(modifier = Modifier.padding(4.dp), onClick = {
|
IconButton(modifier = Modifier.padding(4.dp), onClick = {
|
||||||
mainViewModel.controller?.setVisible(!mainViewModel.controller!!.isVisible)
|
showMore.value = true
|
||||||
}) {
|
}) {
|
||||||
Icon(
|
Icon(
|
||||||
imageVector = Icons.VideoGame(),
|
imageVector = CssGgIcons.ToolbarBottom,
|
||||||
contentDescription = "Toggle Virtual Pad"
|
contentDescription = "Open Panel"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(showMore.value){
|
||||||
|
Popup(alignment = Alignment.BottomCenter, onDismissRequest = {showMore.value = false}) {
|
||||||
|
Surface(modifier = Modifier.padding(16.dp),
|
||||||
|
shape = MaterialTheme.shapes.medium) {
|
||||||
|
Row(modifier = Modifier.padding(8.dp)) {
|
||||||
|
IconButton(modifier = Modifier.padding(4.dp), onClick = {
|
||||||
|
showMore.value = false
|
||||||
|
showController.value = !showController.value
|
||||||
|
mainViewModel.controller?.setVisible(showController.value)
|
||||||
|
}) {
|
||||||
|
Icon(
|
||||||
|
imageVector = Icons.videoGame(),
|
||||||
|
contentDescription = "Toggle Virtual Pad"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
IconButton(modifier = Modifier.padding(4.dp), onClick = {
|
||||||
|
showMore.value = false
|
||||||
|
enableVsync.value = !enableVsync.value
|
||||||
|
RyujinxNative().graphicsRendererSetVsync(enableVsync.value)
|
||||||
|
}) {
|
||||||
|
Icon(
|
||||||
|
imageVector = Icons.vSync(),
|
||||||
|
tint = if(enableVsync.value) Color.Green else Color.Red,
|
||||||
|
contentDescription = "Toggle VSync"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var showBackNotice = remember {
|
var showBackNotice = remember {
|
||||||
mutableStateOf(false)
|
mutableStateOf(false)
|
||||||
}
|
}
|
||||||
@ -227,4 +267,4 @@ class MainView {
|
|||||||
mainViewModel.setStatStates(fifo, gameFps, gameTime)
|
mainViewModel.setStatStates(fifo, gameFps, gameTime)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@ pluginManagement {
|
|||||||
mavenCentral()
|
mavenCentral()
|
||||||
gradlePluginPortal()
|
gradlePluginPortal()
|
||||||
maven { url 'https://jitpack.io' }
|
maven { url 'https://jitpack.io' }
|
||||||
|
maven { url "https://maven.pkg.jetbrains.space/public/p/compose/dev" }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
dependencyResolutionManagement {
|
dependencyResolutionManagement {
|
||||||
@ -12,6 +13,7 @@ dependencyResolutionManagement {
|
|||||||
google()
|
google()
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
maven { url 'https://jitpack.io' }
|
maven { url 'https://jitpack.io' }
|
||||||
|
maven { url "https://maven.pkg.jetbrains.space/public/p/compose/dev" }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
rootProject.name = "RyujinxAndroid"
|
rootProject.name = "RyujinxAndroid"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user