Add host buffer settings for fair input delay mode

Also rename max buffer to client buffer for better consistency with settings and c++
This commit is contained in:
Tom Pratt
2026-05-05 21:50:04 +02:00
committed by Tom Pratt
parent 86de5ef4b0
commit 1c2806dfe9
7 changed files with 93 additions and 35 deletions
@@ -49,7 +49,7 @@ class NetplaySession(
@Volatile
var isClosed = false
private set
val isHosting: Boolean
get() = netPlayServerPointer != 0L
@@ -162,7 +162,9 @@ class NetplaySession(
nativeSendMessage(message)
}
fun adjustPadBufferSize(buffer: Int) = nativeAdjustPadBufferSize(buffer)
fun adjustClientPadBufferSize(buffer: Int) = nativeAdjustClientPadBufferSize(buffer)
fun adjustServerPadBufferSize(buffer: Int) = nativeAdjustServerPadBufferSize(buffer)
fun changeGame(gameFile: GameFile) = nativeChangeGame(gameFile)
@@ -241,7 +243,9 @@ class NetplaySession(
private external fun nativeSendMessage(message: String)
private external fun nativeAdjustPadBufferSize(buffer: Int)
private external fun nativeAdjustClientPadBufferSize(buffer: Int)
private external fun nativeAdjustServerPadBufferSize(buffer: Int)
private external fun nativeReleaseUICallbacks(pointer: Long)
@@ -65,8 +65,11 @@ class NetplayViewModel(
val hostInputAuthority = netplaySession.hostInputAuthorityEnabled
.stateIn(viewModelScope, SharingStarted.WhileSubscribed(), false)
private val _maxBuffer = MutableStateFlow(IntSetting.NETPLAY_CLIENT_BUFFER_SIZE.int)
val maxBuffer = _maxBuffer.asStateFlow()
private val _buffer = MutableStateFlow(IntSetting.NETPLAY_BUFFER_SIZE.int)
val buffer = _buffer.asStateFlow()
private val _clientBuffer = MutableStateFlow(IntSetting.NETPLAY_CLIENT_BUFFER_SIZE.int)
val clientBuffer = _clientBuffer.asStateFlow()
val gameFiles = GameFileCacheManager.getGameFiles().asFlow()
.map { it.toList() }
@@ -104,10 +107,16 @@ class NetplayViewModel(
netplaySession.sendMessage(trimmedMessage)
}
fun setMaxBuffer(buffer: Int) {
_maxBuffer.value = buffer
IntSetting.NETPLAY_CLIENT_BUFFER_SIZE.setInt(NativeConfig.LAYER_BASE, buffer)
netplaySession.adjustPadBufferSize(buffer)
fun setBuffer(value: Int) {
_buffer.value = value
IntSetting.NETPLAY_BUFFER_SIZE.setInt(NativeConfig.LAYER_BASE, value)
netplaySession.adjustServerPadBufferSize(value)
}
fun setClientBuffer(value: Int) {
_clientBuffer.value = value
IntSetting.NETPLAY_CLIENT_BUFFER_SIZE.setInt(NativeConfig.LAYER_BASE, value)
netplaySession.adjustClientPadBufferSize(value)
}
fun changeGame(gameFile: GameFile) {
@@ -60,8 +60,10 @@ class NetplayActivity : AppCompatActivity(), ThemeProvider {
gameFiles = viewModel.gameFiles.collectAsState().value,
players = viewModel.players.collectAsState().value,
hostInputAuthorityEnabled = viewModel.hostInputAuthority.collectAsState().value,
maxBuffer = viewModel.maxBuffer.collectAsState().value,
onMaxBufferChanged = viewModel::setMaxBuffer,
buffer = viewModel.buffer.collectAsState().value,
onBufferChanged = viewModel::setBuffer,
clientBuffer = viewModel.clientBuffer.collectAsState().value,
onClientBufferChanged = viewModel::setClientBuffer,
saveTransferProgress = viewModel.saveTransferProgress.collectAsState().value,
gameDigestProgress = viewModel.gameDigestProgress.collectAsState().value,
joinAddresses = viewModel.joinAddresses.collectAsState().value,
@@ -121,8 +121,10 @@ fun NetplayScreen(
onGameSelected: (GameFile) -> Unit,
gameFiles: List<GameFile>,
hostInputAuthorityEnabled: Boolean,
maxBuffer: Int,
onMaxBufferChanged: (Int) -> Unit,
buffer: Int,
onBufferChanged: (Int) -> Unit,
clientBuffer: Int,
onClientBufferChanged: (Int) -> Unit,
players: List<Player>,
saveTransferProgress: SaveTransferProgress?,
gameDigestProgress: GameDigestProgress?,
@@ -176,8 +178,10 @@ fun NetplayScreen(
onShowGamePickerChanged = { showGamePicker = it },
players = players,
hostInputAuthorityEnabled = hostInputAuthorityEnabled,
maxBuffer = maxBuffer,
onMaxBufferChanged = onMaxBufferChanged,
buffer = buffer,
onBufferChanged = onBufferChanged,
clientBuffer = clientBuffer,
onClientBufferChanged = onClientBufferChanged,
joinAddresses = joinAddresses,
selectedJoinInfoType = selectedJoinInfoType,
onSelectedJoinInfoTypeChanged = { selectedJoinInfoType = it },
@@ -197,8 +201,10 @@ fun NetplayScreen(
onShowGamePickerChanged = { showGamePicker = it },
players = players,
hostInputAuthorityEnabled = hostInputAuthorityEnabled,
maxBuffer = maxBuffer,
onMaxBufferChanged = onMaxBufferChanged,
buffer = buffer,
onBufferChanged = onBufferChanged,
clientBuffer = clientBuffer,
onClientBufferChanged = onClientBufferChanged,
joinAddresses = joinAddresses,
selectedJoinInfoType = selectedJoinInfoType,
onSelectedJoinInfoTypeChanged = { selectedJoinInfoType = it },
@@ -284,8 +290,10 @@ private fun PortraitContent(
onShowGamePickerChanged: (Boolean) -> Unit,
players: List<Player>,
hostInputAuthorityEnabled: Boolean,
maxBuffer: Int,
onMaxBufferChanged: (Int) -> Unit,
buffer: Int,
onBufferChanged: (Int) -> Unit,
clientBuffer: Int,
onClientBufferChanged: (Int) -> Unit,
joinAddresses: Map<JoinInfoType, JoinAddress>,
selectedJoinInfoType: JoinInfoType,
onSelectedJoinInfoTypeChanged: (JoinInfoType) -> Unit,
@@ -316,8 +324,10 @@ private fun PortraitContent(
onShowGamePickerChanged = onShowGamePickerChanged,
players = players,
hostInputAuthorityEnabled = hostInputAuthorityEnabled,
maxBuffer = maxBuffer,
onMaxBufferChanged = onMaxBufferChanged,
buffer = buffer,
onBufferChanged = onBufferChanged,
clientBuffer = clientBuffer,
onClientBufferChanged = onClientBufferChanged,
isHosting = isHosting,
joinAddresses = joinAddresses,
selectedJoinInfoType = selectedJoinInfoType,
@@ -346,8 +356,10 @@ private fun LandscapeContent(
onShowGamePickerChanged: (Boolean) -> Unit,
players: List<Player>,
hostInputAuthorityEnabled: Boolean,
maxBuffer: Int,
onMaxBufferChanged: (Int) -> Unit,
buffer: Int,
onBufferChanged: (Int) -> Unit,
clientBuffer: Int,
onClientBufferChanged: (Int) -> Unit,
joinAddresses: Map<JoinInfoType, JoinAddress>,
selectedJoinInfoType: JoinInfoType,
onSelectedJoinInfoTypeChanged: (JoinInfoType) -> Unit,
@@ -382,8 +394,10 @@ private fun LandscapeContent(
onShowGamePickerChanged = onShowGamePickerChanged,
players = players,
hostInputAuthorityEnabled = hostInputAuthorityEnabled,
maxBuffer = maxBuffer,
onMaxBufferChanged = onMaxBufferChanged,
buffer = buffer,
onBufferChanged = onBufferChanged,
clientBuffer = clientBuffer,
onClientBufferChanged = onClientBufferChanged,
isHosting = isHosting,
joinAddresses = joinAddresses,
selectedJoinInfoType = selectedJoinInfoType,
@@ -407,8 +421,10 @@ private fun PlayersAndSettings(
onShowGamePickerChanged: (Boolean) -> Unit,
players: List<Player>,
hostInputAuthorityEnabled: Boolean,
maxBuffer: Int,
onMaxBufferChanged: (Int) -> Unit,
buffer: Int,
onBufferChanged: (Int) -> Unit,
clientBuffer: Int,
onClientBufferChanged: (Int) -> Unit,
isHosting: Boolean,
joinAddresses: Map<JoinInfoType, JoinAddress>,
selectedJoinInfoType: JoinInfoType,
@@ -459,13 +475,23 @@ private fun PlayersAndSettings(
)
}
if (hostInputAuthorityEnabled) {
if (isHosting && !hostInputAuthorityEnabled) {
MenuSpacer()
BufferInput(
value = maxBuffer,
onValueChange = onMaxBufferChanged,
label = stringResource(R.string.netplay_max_buffer),
value = buffer,
onValueChange = onBufferChanged,
label = stringResource(R.string.netplay_buffer),
)
}
if (!isHosting && hostInputAuthorityEnabled) {
MenuSpacer()
BufferInput(
value = clientBuffer,
onValueChange = onClientBufferChanged,
label = stringResource(R.string.netplay_client_buffer),
)
}
}
@@ -1188,8 +1214,10 @@ private fun PreviewNetplayScreen() {
onGameSelected = {},
gameFiles = emptyList(),
hostInputAuthorityEnabled = true,
maxBuffer = 10,
onMaxBufferChanged = {},
buffer = 5,
onBufferChanged = {},
clientBuffer = 10,
onClientBufferChanged = {},
saveTransferProgress = null,
gameDigestProgress = null,
joinAddresses = mapOf(
@@ -146,6 +146,12 @@ enum class IntSetting(
Settings.SECTION_INI_NETPLAY,
"BufferSizeClient",
1
),
NETPLAY_BUFFER_SIZE(
Settings.FILE_DOLPHIN,
Settings.SECTION_INI_NETPLAY,
"BufferSize",
5
);
override val isOverridden: Boolean
@@ -1008,7 +1008,8 @@ 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_max_buffer">Max buffer</string>
<string name="netplay_buffer">Buffer</string>
<string name="netplay_client_buffer">Max buffer</string>
<string name="netplay_connection_lost">Netplay connection lost</string>
<string name="netplay_save_transfer_progress_close">Close</string>
<string name="netplay_game_digest_match">The hashes match</string>
+9 -1
View File
@@ -50,7 +50,7 @@ Java_org_dolphinemu_dolphinemu_features_netplay_NetplaySession_nativeSendMessage
}
JNIEXPORT void JNICALL
Java_org_dolphinemu_dolphinemu_features_netplay_NetplaySession_nativeAdjustPadBufferSize(JNIEnv* env,
Java_org_dolphinemu_dolphinemu_features_netplay_NetplaySession_nativeAdjustClientPadBufferSize(JNIEnv* env,
jobject obj,
jint buffer)
{
@@ -58,6 +58,14 @@ Java_org_dolphinemu_dolphinemu_features_netplay_NetplaySession_nativeAdjustPadBu
client->AdjustPadBufferSize(static_cast<u32>(buffer));
}
JNIEXPORT void JNICALL
Java_org_dolphinemu_dolphinemu_features_netplay_NetplaySession_nativeAdjustServerPadBufferSize(
JNIEnv* env, jobject obj, jint buffer)
{
if (auto* server = GetServerPointer(env, obj))
server->AdjustPadBufferSize(static_cast<u32>(buffer));
}
JNIEXPORT jlong JNICALL
Java_org_dolphinemu_dolphinemu_features_netplay_NetplaySession_nativeCreateUICallbacks(JNIEnv* env,
jobject obj)