summaryrefslogtreecommitdiff
path: root/Source/Android/app/src/main
diff options
context:
space:
mode:
authorTom Pratt <tom.pratt@outlook.com>2026-05-03 10:05:08 +0200
committerTom Pratt <tompratt@squareup.com>2026-05-19 12:02:59 +0200
commit6655672ee3d15cceb9fdb73f4b16df9553fefeb1 (patch)
tree859c9aef1cf538d93b61e6c839446defe4d38951 /Source/Android/app/src/main
parent68e9fd6cde8168f591881b8d94b3f6ac4ee55d15 (diff)
Add ability to choose game when hosting
Also fix bottom sheets so they survive rotation
Diffstat (limited to 'Source/Android/app/src/main')
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/netplay/NetplaySession.kt5
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/netplay/model/NetplayViewModel.kt34
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/netplay/ui/NetplayActivity.kt3
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/netplay/ui/NetplayScreen.kt213
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/StringSetting.kt3
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/CoilUtils.kt2
6 files changed, 246 insertions, 14 deletions
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/netplay/NetplaySession.kt b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/netplay/NetplaySession.kt
index ba8a0a321d..3ec1dea43f 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/netplay/NetplaySession.kt
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/netplay/NetplaySession.kt
@@ -25,6 +25,7 @@ import kotlinx.coroutines.flow.runningFold
import kotlinx.coroutines.isActive
import kotlinx.coroutines.withContext
import org.dolphinemu.dolphinemu.features.netplay.model.GameDigestProgress
+import org.dolphinemu.dolphinemu.model.GameFile
import org.dolphinemu.dolphinemu.features.netplay.model.NetplayMessage
import org.dolphinemu.dolphinemu.features.netplay.model.Player
import org.dolphinemu.dolphinemu.features.netplay.model.SaveTransferProgress
@@ -153,6 +154,8 @@ class NetplaySession(
fun adjustPadBufferSize(buffer: Int) = nativeAdjustPadBufferSize(buffer)
+ fun changeGame(gameFile: GameFile) = nativeChangeGame(gameFile)
+
fun startGame() = nativeStartGame()
fun consumeBootSessionData(): Long {
@@ -232,6 +235,8 @@ class NetplaySession(
private external fun nativeReleaseBootSessionData(pointer: Long)
+ private external fun nativeChangeGame(gameFile: GameFile)
+
private external fun nativeStartGame()
// NetPlayUI callbacks
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/netplay/model/NetplayViewModel.kt b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/netplay/model/NetplayViewModel.kt
index e7518bdf43..50edaba597 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/netplay/model/NetplayViewModel.kt
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/netplay/model/NetplayViewModel.kt
@@ -4,17 +4,22 @@ package org.dolphinemu.dolphinemu.features.netplay.model
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
+import androidx.lifecycle.asFlow
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.DelicateCoroutinesApi
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.asStateFlow
+import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.launch
import org.dolphinemu.dolphinemu.features.netplay.NetplaySession
import org.dolphinemu.dolphinemu.features.settings.model.IntSetting
import org.dolphinemu.dolphinemu.features.settings.model.NativeConfig
+import org.dolphinemu.dolphinemu.features.settings.model.StringSetting
+import org.dolphinemu.dolphinemu.model.GameFile
+import org.dolphinemu.dolphinemu.services.GameFileCacheManager
class NetplayViewModel(
private val netplaySession: NetplaySession,
@@ -41,10 +46,24 @@ class NetplayViewModel(
private val _maxBuffer = MutableStateFlow(IntSetting.NETPLAY_CLIENT_BUFFER_SIZE.int)
val maxBuffer = _maxBuffer.asStateFlow()
+ val gameFiles = GameFileCacheManager.getGameFiles().asFlow()
+ .map { it.toList() }
+ .stateIn(
+ viewModelScope,
+ SharingStarted.WhileSubscribed(),
+ GameFileCacheManager.getGameFiles().value?.toList() ?: emptyList()
+ )
+
val saveTransferProgress = netplaySession.saveTransferProgress
val gameDigestProgress = netplaySession.gameDigestProgress
+ init {
+ if (netplaySession.isHosting) {
+ setInitialGame()
+ }
+ }
+
fun startGame() {
netplaySession.startGame()
}
@@ -64,6 +83,21 @@ class NetplayViewModel(
netplaySession.adjustPadBufferSize(buffer)
}
+ fun changeGame(gameFile: GameFile) {
+ StringSetting.NETPLAY_GAME.setString(NativeConfig.LAYER_BASE, gameFile.getGameId())
+ netplaySession.changeGame(gameFile)
+ }
+
+ private fun setInitialGame() {
+ val game = gameFiles.value
+ .find { it.getGameId() == StringSetting.NETPLAY_GAME.string }
+ ?: gameFiles.value.firstOrNull()
+
+ if (game != null) {
+ changeGame(game)
+ }
+ }
+
@OptIn(DelicateCoroutinesApi::class)
override fun onCleared() {
super.onCleared()
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/netplay/ui/NetplayActivity.kt b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/netplay/ui/NetplayActivity.kt
index ce1f7dec19..55888dde6d 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/netplay/ui/NetplayActivity.kt
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/netplay/ui/NetplayActivity.kt
@@ -9,6 +9,7 @@ import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
import androidx.appcompat.app.AppCompatActivity
import androidx.compose.runtime.collectAsState
+import androidx.compose.runtime.livedata.observeAsState
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.flowWithLifecycle
@@ -53,6 +54,8 @@ class NetplayActivity : AppCompatActivity(), ThemeProvider {
game = viewModel.game.collectAsState().value,
isHosting = viewModel.isHosting,
onStartGame = viewModel::startGame,
+ onGameSelected = viewModel::changeGame,
+ gameFiles = viewModel.gameFiles.collectAsState().value,
players = viewModel.players.collectAsState().value,
hostInputAuthorityEnabled = viewModel.hostInputAuthority.collectAsState().value,
maxBuffer = viewModel.maxBuffer.collectAsState().value,
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/netplay/ui/NetplayScreen.kt b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/netplay/ui/NetplayScreen.kt
index 45bd89efab..86cbfe5129 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/netplay/ui/NetplayScreen.kt
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/netplay/ui/NetplayScreen.kt
@@ -3,12 +3,14 @@
package org.dolphinemu.dolphinemu.features.netplay.ui
import android.content.res.Configuration
+import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.layout.aspectRatio
import androidx.compose.foundation.layout.consumeWindowInsets
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxSize
@@ -19,6 +21,9 @@ import androidx.compose.foundation.layout.statusBarsPadding
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.LazyListScope
+import androidx.compose.foundation.lazy.grid.GridCells
+import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
+import androidx.compose.foundation.lazy.grid.items
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.text.KeyboardActions
@@ -30,6 +35,7 @@ import androidx.compose.material.icons.filled.Add
import androidx.compose.material.icons.filled.Remove
import androidx.compose.material3.AlertDialog
import androidx.compose.material3.Button
+import androidx.compose.material3.Card
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.ExtendedFloatingActionButton
import androidx.compose.material3.HorizontalDivider
@@ -42,9 +48,10 @@ import androidx.compose.material3.MediumTopAppBar
import androidx.compose.material3.ModalBottomSheet
import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.Scaffold
+import androidx.compose.material3.SheetState
+import androidx.compose.material3.SheetValue
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
-import androidx.compose.material3.rememberModalBottomSheetState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
@@ -55,6 +62,8 @@ import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
+import androidx.compose.ui.draw.clip
+import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.layout.onGloballyPositioned
import androidx.compose.ui.platform.LocalConfiguration
import androidx.compose.ui.platform.LocalContext
@@ -66,8 +75,11 @@ import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.text.input.TextFieldValue
import androidx.compose.ui.text.style.TextAlign
+import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
+import coil.compose.AsyncImage
+import coil.request.ImageRequest
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.emptyFlow
import org.dolphinemu.dolphinemu.R
@@ -75,10 +87,12 @@ import org.dolphinemu.dolphinemu.features.netplay.model.GameDigestProgress
import org.dolphinemu.dolphinemu.features.netplay.model.NetplayMessage
import org.dolphinemu.dolphinemu.features.netplay.model.Player
import org.dolphinemu.dolphinemu.features.netplay.model.SaveTransferProgress
+import org.dolphinemu.dolphinemu.model.GameFile
import org.dolphinemu.dolphinemu.ui.theme.DolphinTheme
import org.dolphinemu.dolphinemu.ui.theme.MenuSpacer
import org.dolphinemu.dolphinemu.ui.theme.OutlinedBox
import org.dolphinemu.dolphinemu.ui.theme.PreviewTheme
+import org.dolphinemu.dolphinemu.utils.CoilUtils
import java.util.Locale
@OptIn(ExperimentalMaterial3Api::class)
@@ -91,6 +105,8 @@ fun NetplayScreen(
onSendMessage: (String) -> Unit,
game: String,
onStartGame: () -> Unit,
+ onGameSelected: (GameFile) -> Unit,
+ gameFiles: List<GameFile>,
hostInputAuthorityEnabled: Boolean,
maxBuffer: Int,
onMaxBufferChanged: (Int) -> Unit,
@@ -125,12 +141,21 @@ fun NetplayScreen(
.consumeWindowInsets(innerPadding)
.padding(innerPadding)
+ var showChat by rememberSaveable { mutableStateOf(false) }
+ var showGamePicker by rememberSaveable { mutableStateOf(false) }
+
if (LocalConfiguration.current.orientation == Configuration.ORIENTATION_LANDSCAPE) {
LandscapeContent(
isHosting = isHosting,
messages = messages,
onSendMessage = onSendMessage,
+ showChat = showChat,
+ onShowChatChanged = { showChat = it },
game = game,
+ gameFiles = gameFiles,
+ onGameSelected = onGameSelected,
+ showGamePicker = showGamePicker,
+ onShowGamePickerChanged = { showGamePicker = it },
players = players,
hostInputAuthorityEnabled = hostInputAuthorityEnabled,
maxBuffer = maxBuffer,
@@ -142,7 +167,13 @@ fun NetplayScreen(
isHosting = isHosting,
messages = messages,
onSendMessage = onSendMessage,
+ showChat = showChat,
+ onShowChatChanged = { showChat = it },
game = game,
+ gameFiles = gameFiles,
+ onGameSelected = onGameSelected,
+ showGamePicker = showGamePicker,
+ onShowGamePickerChanged = { showGamePicker = it },
players = players,
hostInputAuthorityEnabled = hostInputAuthorityEnabled,
maxBuffer = maxBuffer,
@@ -201,7 +232,13 @@ private fun PortraitContent(
isHosting: Boolean,
messages: List<NetplayMessage>,
onSendMessage: (String) -> Unit,
+ showChat: Boolean,
+ onShowChatChanged: (Boolean) -> Unit,
game: String,
+ gameFiles: List<GameFile>,
+ onGameSelected: (GameFile) -> Unit,
+ showGamePicker: Boolean,
+ onShowGamePickerChanged: (Boolean) -> Unit,
players: List<Player>,
hostInputAuthorityEnabled: Boolean,
maxBuffer: Int,
@@ -215,6 +252,8 @@ private fun PortraitContent(
Chat(
messages = messages,
onSendMessage = onSendMessage,
+ showBottomSheet = showChat,
+ onShowBottomSheetChanged = onShowChatChanged,
modifier = Modifier
.fillMaxWidth()
.height(200.dp)
@@ -225,10 +264,15 @@ private fun PortraitContent(
PlayersAndSettings(
game = game,
+ gameFiles = gameFiles,
+ onGameSelected = onGameSelected,
+ showGamePicker = showGamePicker,
+ onShowGamePickerChanged = onShowGamePickerChanged,
players = players,
hostInputAuthorityEnabled = hostInputAuthorityEnabled,
maxBuffer = maxBuffer,
onMaxBufferChanged = onMaxBufferChanged,
+ isHosting = isHosting,
modifier = Modifier
.padding(horizontal = DolphinTheme.scaffoldPadding),
)
@@ -244,7 +288,13 @@ private fun LandscapeContent(
isHosting: Boolean,
messages: List<NetplayMessage>,
onSendMessage: (String) -> Unit,
+ showChat: Boolean,
+ onShowChatChanged: (Boolean) -> Unit,
game: String,
+ gameFiles: List<GameFile>,
+ onGameSelected: (GameFile) -> Unit,
+ showGamePicker: Boolean,
+ onShowGamePickerChanged: (Boolean) -> Unit,
players: List<Player>,
hostInputAuthorityEnabled: Boolean,
maxBuffer: Int,
@@ -257,6 +307,8 @@ private fun LandscapeContent(
Chat(
messages = messages,
onSendMessage = onSendMessage,
+ showBottomSheet = showChat,
+ onShowBottomSheetChanged = onShowChatChanged,
modifier = Modifier
.weight(1f)
.fillMaxHeight()
@@ -270,10 +322,15 @@ private fun LandscapeContent(
) {
PlayersAndSettings(
game = game,
+ gameFiles = gameFiles,
+ onGameSelected = onGameSelected,
+ showGamePicker = showGamePicker,
+ onShowGamePickerChanged = onShowGamePickerChanged,
players = players,
hostInputAuthorityEnabled = hostInputAuthorityEnabled,
maxBuffer = maxBuffer,
onMaxBufferChanged = onMaxBufferChanged,
+ isHosting = isHosting,
modifier = Modifier
.padding(horizontal = DolphinTheme.scaffoldPadding)
)
@@ -288,22 +345,27 @@ private fun LandscapeContent(
@Composable
private fun PlayersAndSettings(
game: String,
+ gameFiles: List<GameFile>,
+ onGameSelected: (GameFile) -> Unit,
+ showGamePicker: Boolean,
+ onShowGamePickerChanged: (Boolean) -> Unit,
players: List<Player>,
hostInputAuthorityEnabled: Boolean,
maxBuffer: Int,
onMaxBufferChanged: (Int) -> Unit,
+ isHosting: Boolean,
modifier: Modifier = Modifier,
) {
Column(
modifier = modifier
) {
- OutlinedTextField(
- value = game,
- onValueChange = {},
- label = { Text(stringResource(R.string.netplay_game_label)) },
- readOnly = true,
- modifier = Modifier
- .fillMaxWidth()
+ GamePicker(
+ game = game,
+ gameFiles = gameFiles,
+ onGameSelected = onGameSelected,
+ showGamePicker = showGamePicker,
+ onShowGamePickerChanged = onShowGamePickerChanged,
+ isHosting = isHosting,
)
MenuSpacer()
@@ -345,6 +407,8 @@ private fun PlayersAndSettings(
private fun Chat(
messages: List<NetplayMessage>,
onSendMessage: (String) -> Unit,
+ showBottomSheet: Boolean,
+ onShowBottomSheetChanged: (Boolean) -> Unit,
modifier: Modifier,
) {
val context = LocalContext.current
@@ -361,12 +425,18 @@ private fun Chat(
draftMessage = ""
}
- var showBottomSheet by remember { mutableStateOf(false) }
- val bottomSheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true)
+ val density = LocalDensity.current
+ val bottomSheetState = remember {
+ SheetState(
+ skipPartiallyExpanded = true,
+ density = density,
+ initialValue = if (showBottomSheet) SheetValue.Expanded else SheetValue.Hidden,
+ )
+ }
if (showBottomSheet) {
ModalBottomSheet(
- onDismissRequest = { showBottomSheet = false },
+ onDismissRequest = { onShowBottomSheetChanged(false) },
sheetState = bottomSheetState,
modifier = Modifier
.statusBarsPadding()
@@ -407,7 +477,7 @@ private fun Chat(
}
OutlinedBox(
- onClick = { showBottomSheet = true },
+ onClick = { onShowBottomSheetChanged(true) },
label = { Text(stringResource(R.string.netplay_chat_label)) },
modifier = modifier
) {
@@ -422,6 +492,123 @@ private fun Chat(
}
}
+@OptIn(ExperimentalMaterial3Api::class)
+@Composable
+private fun GamePicker(
+ game: String,
+ gameFiles: List<GameFile>,
+ onGameSelected: (GameFile) -> Unit,
+ showGamePicker: Boolean,
+ onShowGamePickerChanged: (Boolean) -> Unit,
+ isHosting: Boolean,
+) {
+ val density = LocalDensity.current
+ val bottomSheetState = remember {
+ SheetState(
+ skipPartiallyExpanded = true,
+ density = density,
+ initialValue = if (showGamePicker) SheetValue.Expanded else SheetValue.Hidden,
+ )
+ }
+
+ if (showGamePicker) {
+ ModalBottomSheet(
+ onDismissRequest = { onShowGamePickerChanged(false) },
+ sheetState = bottomSheetState,
+ modifier = Modifier.statusBarsPadding()
+ ) {
+ GameList(
+ gameFiles = gameFiles,
+ onGameSelected = { gameFile ->
+ onGameSelected(gameFile)
+ onShowGamePickerChanged(false)
+ },
+ contentPadding = PaddingValues(
+ start = DolphinTheme.scaffoldPadding,
+ end = DolphinTheme.scaffoldPadding,
+ bottom = 16.dp
+ ),
+ )
+ }
+ }
+
+ Box(
+ modifier = Modifier.fillMaxWidth()
+ ) {
+ OutlinedTextField(
+ value = game,
+ onValueChange = {},
+ label = { Text(stringResource(R.string.netplay_game_label)) },
+ readOnly = true,
+ modifier = Modifier.fillMaxWidth()
+ )
+ if (isHosting) {
+ Box(
+ modifier = Modifier
+ .matchParentSize()
+ .padding(top = 8.dp)
+ .clip(MaterialTheme.shapes.extraSmall)
+ .clickable { onShowGamePickerChanged(true) }
+ )
+ }
+ }
+}
+
+@Composable
+private fun GameList(
+ gameFiles: List<GameFile>,
+ onGameSelected: (GameFile) -> Unit,
+ contentPadding: PaddingValues = PaddingValues(),
+) {
+ LazyVerticalGrid(
+ columns = GridCells.Adaptive(minSize = 120.dp),
+ contentPadding = contentPadding,
+ horizontalArrangement = Arrangement.spacedBy(12.dp),
+ verticalArrangement = Arrangement.spacedBy(12.dp),
+ ) {
+ items(gameFiles, key = { it.getPath() }) { gameFile ->
+ GameGridItem(
+ gameFile = gameFile,
+ onClick = { onGameSelected(gameFile) },
+ )
+ }
+ }
+}
+
+@Composable
+private fun GameGridItem(
+ gameFile: GameFile,
+ onClick: () -> Unit,
+) {
+ Card(
+ onClick = onClick,
+ ) {
+ Column {
+ AsyncImage(
+ model = ImageRequest.Builder(LocalContext.current)
+ .data(gameFile)
+ .error(R.drawable.no_banner)
+ .build(),
+ contentDescription = gameFile.getTitle(),
+ contentScale = ContentScale.Crop,
+ imageLoader = CoilUtils.imageLoader,
+ modifier = Modifier
+ .fillMaxWidth()
+ .aspectRatio(0.7f)
+ )
+ Text(
+ text = gameFile.getTitle(),
+ style = MaterialTheme.typography.bodySmall,
+ maxLines = 2,
+ minLines = 2,
+ overflow = TextOverflow.Ellipsis,
+ modifier = Modifier
+ .padding(8.dp)
+ )
+ }
+ }
+}
+
/**
* A table arranged into columns sized to wrap the largest item. Except the
* first column which takes up the remaining space left by the other columns.
@@ -787,6 +974,8 @@ private fun PreviewNetplayScreen() {
game = "Game name",
isHosting = true,
onStartGame = {},
+ onGameSelected = {},
+ gameFiles = emptyList(),
hostInputAuthorityEnabled = true,
maxBuffer = 10,
onMaxBufferChanged = {},
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/StringSetting.kt b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/StringSetting.kt
index d3070a51ca..610f45b2a3 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/StringSetting.kt
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/StringSetting.kt
@@ -115,7 +115,8 @@ enum class StringSetting(
""
),
NETPLAY_ADDRESS(Settings.FILE_DOLPHIN, Settings.SECTION_INI_NETPLAY, "Address", "127.0.0.1"),
- NETPLAY_NICKNAME(Settings.FILE_DOLPHIN, Settings.SECTION_INI_NETPLAY, "Nickname", "Player");
+ NETPLAY_NICKNAME(Settings.FILE_DOLPHIN, Settings.SECTION_INI_NETPLAY, "Nickname", "Player"),
+ NETPLAY_GAME(Settings.FILE_DOLPHIN, Settings.SECTION_INI_NETPLAY, "Game", "");
override val isOverridden: Boolean
get() = NativeConfig.isOverridden(file, section, key)
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/CoilUtils.kt b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/CoilUtils.kt
index 846fcd564e..8c3fb2e3f3 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/CoilUtils.kt
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/CoilUtils.kt
@@ -66,7 +66,7 @@ class GameCoverKeyer : Keyer<GameFile> {
}
object CoilUtils {
- private val imageLoader = ImageLoader.Builder(DolphinApplication.getAppContext())
+ val imageLoader = ImageLoader.Builder(DolphinApplication.getAppContext())
.components {
add(GameCoverKeyer())
add(GameCoverFetcher.Factory())