mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2026-08-25 03:46:01 -05:00
Add network mode picker for host
This commit is contained in:
@@ -162,6 +162,8 @@ class NetplaySession(
|
||||
nativeSendMessage(message)
|
||||
}
|
||||
|
||||
fun setHostInputAuthority(enable: Boolean) = nativeSetHostInputAuthority(enable)
|
||||
|
||||
fun adjustClientPadBufferSize(buffer: Int) = nativeAdjustClientPadBufferSize(buffer)
|
||||
|
||||
fun adjustServerPadBufferSize(buffer: Int) = nativeAdjustServerPadBufferSize(buffer)
|
||||
@@ -243,6 +245,8 @@ class NetplaySession(
|
||||
|
||||
private external fun nativeSendMessage(message: String)
|
||||
|
||||
private external fun nativeSetHostInputAuthority(enable: Boolean)
|
||||
|
||||
private external fun nativeAdjustClientPadBufferSize(buffer: Int)
|
||||
|
||||
private external fun nativeAdjustServerPadBufferSize(buffer: Int)
|
||||
|
||||
@@ -65,6 +65,11 @@ class NetplayViewModel(
|
||||
val hostInputAuthority = netplaySession.hostInputAuthorityEnabled
|
||||
.stateIn(viewModelScope, SharingStarted.WhileSubscribed(), false)
|
||||
|
||||
private val _networkMode = MutableStateFlow(
|
||||
NetworkMode.fromConfigValue(StringSetting.NETPLAY_NETWORK_MODE.string)
|
||||
)
|
||||
val networkMode = _networkMode.asStateFlow()
|
||||
|
||||
private val _buffer = MutableStateFlow(IntSetting.NETPLAY_BUFFER_SIZE.int)
|
||||
val buffer = _buffer.asStateFlow()
|
||||
|
||||
@@ -107,6 +112,12 @@ class NetplayViewModel(
|
||||
netplaySession.sendMessage(trimmedMessage)
|
||||
}
|
||||
|
||||
fun setNetworkMode(mode: NetworkMode) {
|
||||
_networkMode.value = mode
|
||||
StringSetting.NETPLAY_NETWORK_MODE.setString(NativeConfig.LAYER_BASE, mode.configValue)
|
||||
netplaySession.setHostInputAuthority(mode.isHostInputAuthority)
|
||||
}
|
||||
|
||||
fun setBuffer(value: Int) {
|
||||
_buffer.value = value
|
||||
IntSetting.NETPLAY_BUFFER_SIZE.setInt(NativeConfig.LAYER_BASE, value)
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
package org.dolphinemu.dolphinemu.features.netplay.model
|
||||
|
||||
import androidx.annotation.StringRes
|
||||
import org.dolphinemu.dolphinemu.R
|
||||
|
||||
enum class NetworkMode(val configValue: String, @StringRes val labelId: Int) {
|
||||
FAIR_INPUT_DELAY("fixeddelay", R.string.netplay_network_mode_fair_input_delay),
|
||||
HOST_INPUT_AUTHORITY("hostinputauthority", R.string.netplay_network_mode_host_input_authority),
|
||||
GOLF("golf", R.string.netplay_network_mode_golf);
|
||||
|
||||
val isHostInputAuthority: Boolean
|
||||
get() = this == HOST_INPUT_AUTHORITY || this == GOLF
|
||||
|
||||
companion object {
|
||||
fun fromConfigValue(value: String): NetworkMode =
|
||||
entries.find { it.configValue == value } ?: FAIR_INPUT_DELAY
|
||||
}
|
||||
}
|
||||
@@ -60,6 +60,8 @@ class NetplayActivity : AppCompatActivity(), ThemeProvider {
|
||||
gameFiles = viewModel.gameFiles.collectAsState().value,
|
||||
players = viewModel.players.collectAsState().value,
|
||||
hostInputAuthorityEnabled = viewModel.hostInputAuthority.collectAsState().value,
|
||||
networkMode = viewModel.networkMode.collectAsState().value,
|
||||
onNetworkModeChanged = viewModel::setNetworkMode,
|
||||
buffer = viewModel.buffer.collectAsState().value,
|
||||
onBufferChanged = viewModel::setBuffer,
|
||||
clientBuffer = viewModel.clientBuffer.collectAsState().value,
|
||||
|
||||
@@ -95,6 +95,7 @@ import org.dolphinemu.dolphinemu.features.netplay.model.GameDigestProgress
|
||||
import org.dolphinemu.dolphinemu.features.netplay.model.JoinAddress
|
||||
import org.dolphinemu.dolphinemu.features.netplay.model.JoinInfoType
|
||||
import org.dolphinemu.dolphinemu.features.netplay.model.NetplayMessage
|
||||
import org.dolphinemu.dolphinemu.features.netplay.model.NetworkMode
|
||||
import org.dolphinemu.dolphinemu.features.netplay.model.Player
|
||||
import org.dolphinemu.dolphinemu.features.netplay.model.SaveTransferProgress
|
||||
import org.dolphinemu.dolphinemu.features.netplay.model.TraversalState
|
||||
@@ -121,6 +122,8 @@ fun NetplayScreen(
|
||||
onGameSelected: (GameFile) -> Unit,
|
||||
gameFiles: List<GameFile>,
|
||||
hostInputAuthorityEnabled: Boolean,
|
||||
networkMode: NetworkMode,
|
||||
onNetworkModeChanged: (NetworkMode) -> Unit,
|
||||
buffer: Int,
|
||||
onBufferChanged: (Int) -> Unit,
|
||||
clientBuffer: Int,
|
||||
@@ -178,6 +181,8 @@ fun NetplayScreen(
|
||||
onShowGamePickerChanged = { showGamePicker = it },
|
||||
players = players,
|
||||
hostInputAuthorityEnabled = hostInputAuthorityEnabled,
|
||||
networkMode = networkMode,
|
||||
onNetworkModeChanged = onNetworkModeChanged,
|
||||
buffer = buffer,
|
||||
onBufferChanged = onBufferChanged,
|
||||
clientBuffer = clientBuffer,
|
||||
@@ -201,6 +206,8 @@ fun NetplayScreen(
|
||||
onShowGamePickerChanged = { showGamePicker = it },
|
||||
players = players,
|
||||
hostInputAuthorityEnabled = hostInputAuthorityEnabled,
|
||||
networkMode = networkMode,
|
||||
onNetworkModeChanged = onNetworkModeChanged,
|
||||
buffer = buffer,
|
||||
onBufferChanged = onBufferChanged,
|
||||
clientBuffer = clientBuffer,
|
||||
@@ -290,6 +297,8 @@ private fun PortraitContent(
|
||||
onShowGamePickerChanged: (Boolean) -> Unit,
|
||||
players: List<Player>,
|
||||
hostInputAuthorityEnabled: Boolean,
|
||||
networkMode: NetworkMode,
|
||||
onNetworkModeChanged: (NetworkMode) -> Unit,
|
||||
buffer: Int,
|
||||
onBufferChanged: (Int) -> Unit,
|
||||
clientBuffer: Int,
|
||||
@@ -324,6 +333,8 @@ private fun PortraitContent(
|
||||
onShowGamePickerChanged = onShowGamePickerChanged,
|
||||
players = players,
|
||||
hostInputAuthorityEnabled = hostInputAuthorityEnabled,
|
||||
networkMode = networkMode,
|
||||
onNetworkModeChanged = onNetworkModeChanged,
|
||||
buffer = buffer,
|
||||
onBufferChanged = onBufferChanged,
|
||||
clientBuffer = clientBuffer,
|
||||
@@ -356,6 +367,8 @@ private fun LandscapeContent(
|
||||
onShowGamePickerChanged: (Boolean) -> Unit,
|
||||
players: List<Player>,
|
||||
hostInputAuthorityEnabled: Boolean,
|
||||
networkMode: NetworkMode,
|
||||
onNetworkModeChanged: (NetworkMode) -> Unit,
|
||||
buffer: Int,
|
||||
onBufferChanged: (Int) -> Unit,
|
||||
clientBuffer: Int,
|
||||
@@ -394,6 +407,8 @@ private fun LandscapeContent(
|
||||
onShowGamePickerChanged = onShowGamePickerChanged,
|
||||
players = players,
|
||||
hostInputAuthorityEnabled = hostInputAuthorityEnabled,
|
||||
networkMode = networkMode,
|
||||
onNetworkModeChanged = onNetworkModeChanged,
|
||||
buffer = buffer,
|
||||
onBufferChanged = onBufferChanged,
|
||||
clientBuffer = clientBuffer,
|
||||
@@ -421,6 +436,8 @@ private fun PlayersAndSettings(
|
||||
onShowGamePickerChanged: (Boolean) -> Unit,
|
||||
players: List<Player>,
|
||||
hostInputAuthorityEnabled: Boolean,
|
||||
networkMode: NetworkMode,
|
||||
onNetworkModeChanged: (NetworkMode) -> Unit,
|
||||
buffer: Int,
|
||||
onBufferChanged: (Int) -> Unit,
|
||||
clientBuffer: Int,
|
||||
@@ -475,6 +492,15 @@ private fun PlayersAndSettings(
|
||||
)
|
||||
}
|
||||
|
||||
if (isHosting) {
|
||||
MenuSpacer()
|
||||
|
||||
NetworkModeDropdown(
|
||||
networkMode = networkMode,
|
||||
onNetworkModeChanged = onNetworkModeChanged,
|
||||
)
|
||||
}
|
||||
|
||||
if (isHosting && !hostInputAuthorityEnabled) {
|
||||
MenuSpacer()
|
||||
|
||||
@@ -902,6 +928,47 @@ private fun PlayersTable(
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
private fun NetworkModeDropdown(
|
||||
networkMode: NetworkMode,
|
||||
onNetworkModeChanged: (NetworkMode) -> Unit,
|
||||
) {
|
||||
var expanded by remember { mutableStateOf(false) }
|
||||
|
||||
ExposedDropdownMenuBox(
|
||||
expanded = expanded,
|
||||
onExpandedChange = { expanded = it },
|
||||
) {
|
||||
OutlinedTextField(
|
||||
value = stringResource(networkMode.labelId),
|
||||
onValueChange = {},
|
||||
readOnly = true,
|
||||
label = { Text(stringResource(R.string.netplay_network_mode_label)) },
|
||||
trailingIcon = { ExposedDropdownMenuDefaults.TrailingIcon(expanded = expanded) },
|
||||
colors = ExposedDropdownMenuDefaults.outlinedTextFieldColors(),
|
||||
modifier = Modifier
|
||||
.menuAnchor(MenuAnchorType.PrimaryNotEditable)
|
||||
.fillMaxWidth(),
|
||||
)
|
||||
ExposedDropdownMenu(
|
||||
expanded = expanded,
|
||||
onDismissRequest = { expanded = false },
|
||||
) {
|
||||
// No golf mode for now since it requires in game UI.
|
||||
listOf(NetworkMode.FAIR_INPUT_DELAY, NetworkMode.HOST_INPUT_AUTHORITY).forEach { mode ->
|
||||
DropdownMenuItem(
|
||||
text = { Text(stringResource(mode.labelId)) },
|
||||
onClick = {
|
||||
onNetworkModeChanged(mode)
|
||||
expanded = false
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun BufferInput(
|
||||
value: Int,
|
||||
@@ -1214,6 +1281,8 @@ private fun PreviewNetplayScreen() {
|
||||
onGameSelected = {},
|
||||
gameFiles = emptyList(),
|
||||
hostInputAuthorityEnabled = true,
|
||||
networkMode = NetworkMode.HOST_INPUT_AUTHORITY,
|
||||
onNetworkModeChanged = {},
|
||||
buffer = 5,
|
||||
onBufferChanged = {},
|
||||
clientBuffer = 10,
|
||||
|
||||
@@ -116,7 +116,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_GAME(Settings.FILE_DOLPHIN, Settings.SECTION_INI_NETPLAY, "Game", "");
|
||||
NETPLAY_GAME(Settings.FILE_DOLPHIN, Settings.SECTION_INI_NETPLAY, "Game", ""),
|
||||
NETPLAY_NETWORK_MODE(Settings.FILE_DOLPHIN, Settings.SECTION_INI_NETPLAY, "NetworkMode", "fixeddelay");
|
||||
|
||||
override val isOverridden: Boolean
|
||||
get() = NativeConfig.isOverridden(file, section, key)
|
||||
|
||||
@@ -1008,6 +1008,10 @@ It can efficiently compress both junk data and encrypted Wii data.
|
||||
<string name="netplay_players_name">Name</string>
|
||||
<string name="netplay_players_ping">Ping</string>
|
||||
<string name="netplay_players_mapping">Mapping</string>
|
||||
<string name="netplay_network_mode_label">Input mode</string>
|
||||
<string name="netplay_network_mode_fair_input_delay">Fair Input Delay</string>
|
||||
<string name="netplay_network_mode_host_input_authority">Host Input Authority</string>
|
||||
<string name="netplay_network_mode_golf">Golf Mode</string>
|
||||
<string name="netplay_buffer">Buffer</string>
|
||||
<string name="netplay_client_buffer">Max buffer</string>
|
||||
<string name="netplay_connection_lost">Netplay connection lost</string>
|
||||
|
||||
@@ -49,6 +49,14 @@ Java_org_dolphinemu_dolphinemu_features_netplay_NetplaySession_nativeSendMessage
|
||||
client->SendChatMessage(GetJString(env, jmessage));
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_org_dolphinemu_dolphinemu_features_netplay_NetplaySession_nativeSetHostInputAuthority(
|
||||
JNIEnv* env, jobject obj, jboolean enable)
|
||||
{
|
||||
if (auto* server = GetServerPointer(env, obj))
|
||||
server->SetHostInputAuthority(static_cast<bool>(enable));
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_org_dolphinemu_dolphinemu_features_netplay_NetplaySession_nativeAdjustClientPadBufferSize(JNIEnv* env,
|
||||
jobject obj,
|
||||
|
||||
Reference in New Issue
Block a user