summaryrefslogtreecommitdiff
path: root/Source/Android/app/src/main/java/org
diff options
context:
space:
mode:
authorTom Pratt <tom.pratt@outlook.com>2026-05-12 11:20:46 -0700
committerTom Pratt <tompratt@squareup.com>2026-05-19 12:02:59 +0200
commit77f08364db41de05e06d02128c3107c2d45df105 (patch)
treea1302806b82586bd567df919ca1230fe9d1fc266 /Source/Android/app/src/main/java/org
parentb63ccacdfa7355989e0ca971b9b06ef1dcfb3bbb (diff)
Create NetPlayServer and start game
Diffstat (limited to 'Source/Android/app/src/main/java/org')
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/netplay/NetplaySession.kt31
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/netplay/model/NetplaySetupViewModel.kt13
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/netplay/model/NetplayViewModel.kt6
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/netplay/ui/NetplayActivity.kt4
4 files changed, 47 insertions, 7 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 e0531a6477..1ec663a1a5 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
@@ -37,6 +37,8 @@ class NetplaySession(
private var netPlayClientPointer: Long = 0
+ private var netPlayServerPointer: Long = 0
+
private var bootSessionDataPointer: Long = 0
private val sessionScope = CoroutineScope(SupervisorJob())
@@ -44,6 +46,9 @@ class NetplaySession(
@Volatile
var isClosed = false
private set
+
+ val isHosting: Boolean
+ get() = netPlayServerPointer != 0L
val isLaunching: Boolean
get() = bootSessionDataPointer != 0L
@@ -126,10 +131,24 @@ class NetplaySession(
true
}
+ suspend fun host(): Boolean = withContext(Dispatchers.IO) {
+ if (isClosed) throw IllegalStateException("Cannot host a closed session")
+
+ netPlayServerPointer = nativeHost()
+ if (netPlayServerPointer == 0L || !isActive) {
+ closeBlocking()
+ return@withContext false
+ }
+
+ join()
+ }
+
fun sendMessage(message: String) = nativeSendMessage(message)
fun adjustPadBufferSize(buffer: Int) = nativeAdjustPadBufferSize(buffer)
+ fun startGame() = nativeStartGame()
+
fun consumeBootSessionData(): Long {
return bootSessionDataPointer.also {
bootSessionDataPointer = 0
@@ -174,6 +193,12 @@ class NetplaySession(
nativeReleaseClient(currentNetPlayClientPointer)
}
+ val currentNetPlayServerPointer = netPlayServerPointer
+ if (currentNetPlayServerPointer != 0L) {
+ netPlayServerPointer = 0
+ nativeReleaseServer(currentNetPlayServerPointer)
+ }
+
val currentNetPlayUICallbacksPointer = netPlayUICallbacksPointer
if (currentNetPlayUICallbacksPointer != 0L) {
netPlayUICallbacksPointer = 0
@@ -187,6 +212,8 @@ class NetplaySession(
private external fun nativeJoin(): Long
+ private external fun nativeHost(): Long
+
private external fun nativeSendMessage(message: String)
private external fun nativeAdjustPadBufferSize(buffer: Int)
@@ -195,8 +222,12 @@ class NetplaySession(
private external fun nativeReleaseClient(pointer: Long)
+ private external fun nativeReleaseServer(pointer: Long)
+
private external fun nativeReleaseBootSessionData(pointer: Long)
+ private external fun nativeStartGame()
+
// NetPlayUI callbacks
@Keep
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/netplay/model/NetplaySetupViewModel.kt b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/netplay/model/NetplaySetupViewModel.kt
index d51ae477ac..9c667245e5 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/netplay/model/NetplaySetupViewModel.kt
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/netplay/model/NetplaySetupViewModel.kt
@@ -119,11 +119,9 @@ class NetplaySetupViewModel(
BooleanSetting.NETPLAY_USE_UPNP.setBoolean(NativeConfig.LAYER_BASE, useUpnp)
}
- fun host() {
+ fun host() = connect(host = true)
- }
-
- fun connect() {
+ fun connect(host: Boolean = false) {
if (_connecting.value) return
_connecting.value = true
@@ -139,7 +137,12 @@ class NetplaySetupViewModel(
.onEach { _errors.emit(it) }
.launchIn(this)
- if (session.join()) {
+ val success = if (host) {
+ session.host()
+ } else {
+ session.join()
+ }
+ if (success) {
_showNetplayScreen.trySend(Unit)
}
} finally {
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 d0f86ed3f6..e7518bdf43 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
@@ -22,6 +22,8 @@ class NetplayViewModel(
val launchGame = netplaySession.launchGame
+ val isHosting = netplaySession.isHosting
+
val connectionLost = netplaySession.connectionLost
val players = netplaySession.players
@@ -43,6 +45,10 @@ class NetplayViewModel(
val gameDigestProgress = netplaySession.gameDigestProgress
+ fun startGame() {
+ netplaySession.startGame()
+ }
+
fun sendMessage(message: String) {
val trimmedMessage = message.trim()
if (trimmedMessage.isEmpty()) {
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 c01ec2a76c..ce1f7dec19 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
@@ -51,8 +51,8 @@ class NetplayActivity : AppCompatActivity(), ThemeProvider {
messages = viewModel.messages.collectAsState().value,
onSendMessage = viewModel::sendMessage,
game = viewModel.game.collectAsState().value,
- isHosting = false,
- onStartGame = {},
+ isHosting = viewModel.isHosting,
+ onStartGame = viewModel::startGame,
players = viewModel.players.collectAsState().value,
hostInputAuthorityEnabled = viewModel.hostInputAuthority.collectAsState().value,
maxBuffer = viewModel.maxBuffer.collectAsState().value,