summaryrefslogtreecommitdiff
path: root/Source/Android
diff options
context:
space:
mode:
authorTom Pratt <tom.pratt@outlook.com>2026-04-08 13:33:42 +0100
committerTom Pratt <tompratt@squareup.com>2026-05-19 12:02:54 +0200
commita1983e5fa2f66911b7151e0fc8f90a86b7cece52 (patch)
treea491a910a947ca5b350a7031cc6e28429ccc7aa2 /Source/Android
parentf10022f2dc6e5e7d9636d3e91fe1dc3737dc703e (diff)
Add Netplay settings JNI layer and wire up NetplaySetupViewModel
Diffstat (limited to 'Source/Android')
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/netplay/Netplay.kt96
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/netplay/model/ConnectionType.kt3
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/netplay/model/NetplaySetupViewModel.kt18
-rw-r--r--Source/Android/jni/CMakeLists.txt1
-rw-r--r--Source/Android/jni/NetPlay/Netplay.cpp120
5 files changed, 233 insertions, 5 deletions
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/netplay/Netplay.kt b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/netplay/Netplay.kt
new file mode 100644
index 0000000000..ace7277a9a
--- /dev/null
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/netplay/Netplay.kt
@@ -0,0 +1,96 @@
+// Copyright 2003 Dolphin Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+package org.dolphinemu.dolphinemu.features.netplay
+
+import org.dolphinemu.dolphinemu.features.netplay.model.ConnectionType
+
+object Netplay {
+ @JvmStatic
+ external fun getNickname(): String
+
+ fun getConnectionType(): ConnectionType = ConnectionType.all
+ .find { it.configValue == getTraversalChoice() } ?: throw IllegalStateException()
+
+ @JvmStatic
+ external fun getTraversalChoice(): String
+
+ @JvmStatic
+ external fun getAddress(): String
+
+ @JvmStatic
+ external fun getHostCode(): String
+
+ @JvmStatic
+ external fun getConnectPort(): Int
+
+ @JvmStatic
+ external fun getHostPort(): Int
+
+ @JvmStatic
+ external fun getUseUpnp(): Boolean
+
+ @JvmStatic
+ external fun getEnableChunkedUploadLimit(): Boolean
+
+ @JvmStatic
+ external fun getChunkedUploadLimit(): Int
+
+ @JvmStatic
+ external fun getUseIndex(): Boolean
+
+ @JvmStatic
+ external fun getIndexRegion(): String
+
+ @JvmStatic
+ external fun getIndexName(): String
+
+ @JvmStatic
+ external fun getIndexPassword(): String
+
+ fun saveSetup(
+ nickname: String,
+ connectionType: ConnectionType,
+ address: String,
+ hostCode: String,
+ connectPort: Int,
+ ) {
+ SaveSetup(
+ nickname = nickname,
+ traversalChoice = connectionType.configValue,
+ address = address,
+ hostCode = hostCode,
+ connectPort = connectPort,
+ hostPort = 2626,
+ useUpnp = false,
+ useListenPort = false,
+ listenPort = 2626,
+ enableChunkedUploadLimit = false,
+ chunkedUploadLimit = 3000,
+ useIndex = false,
+ indexRegion = "",
+ indexName = "",
+ indexPassword = "",
+ )
+ }
+
+ @JvmStatic
+ external fun SaveSetup(
+ nickname: String,
+ traversalChoice: String,
+ address: String,
+ hostCode: String,
+ connectPort: Int,
+ hostPort: Int,
+ useUpnp: Boolean,
+ useListenPort: Boolean,
+ listenPort: Int,
+ enableChunkedUploadLimit: Boolean,
+ chunkedUploadLimit: Int,
+ useIndex: Boolean,
+ indexRegion: String,
+ indexName: String,
+ indexPassword: String,
+ )
+
+}
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/netplay/model/ConnectionType.kt b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/netplay/model/ConnectionType.kt
index aed03f89cc..f6b3f0eca1 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/netplay/model/ConnectionType.kt
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/netplay/model/ConnectionType.kt
@@ -5,13 +5,16 @@ import org.dolphinemu.dolphinemu.R
sealed class ConnectionType(
@StringRes val labelId: Int,
+ val configValue: String,
) {
object DirectConnection : ConnectionType(
labelId = R.string.netplay_connection_type_direct_connection,
+ configValue = "direct",
)
object TraversalServer : ConnectionType(
labelId = R.string.netplay_connection_type_traversal_server,
+ configValue = "traversal",
)
companion object {
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 8d0dd05c79..ecf0b2cff2 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
@@ -5,24 +5,25 @@ package org.dolphinemu.dolphinemu.features.netplay.model
import androidx.lifecycle.ViewModel
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
+import org.dolphinemu.dolphinemu.features.netplay.Netplay
class NetplaySetupViewModel : ViewModel() {
private val _connectionRole = MutableStateFlow<ConnectionRole>(ConnectionRole.Connect)
val connectionRole = _connectionRole.asStateFlow()
- private val _nickname = MutableStateFlow("")
+ private val _nickname = MutableStateFlow(Netplay.getNickname())
val nickname = _nickname.asStateFlow()
- private val _connectionType = MutableStateFlow<ConnectionType>(ConnectionType.DirectConnection)
+ private val _connectionType = MutableStateFlow(Netplay.getConnectionType())
val connectionType = _connectionType.asStateFlow()
- private val _ipAddress = MutableStateFlow("")
+ private val _ipAddress = MutableStateFlow(Netplay.getAddress())
val ipAddress = _ipAddress.asStateFlow()
- private val _hostCode = MutableStateFlow("")
+ private val _hostCode = MutableStateFlow(Netplay.getHostCode())
val hostCode = _hostCode.asStateFlow()
- private val _connectPort = MutableStateFlow(0.toString())
+ private val _connectPort = MutableStateFlow(Netplay.getConnectPort().toString())
val connectPort = _connectPort.asStateFlow()
fun setConnectionRole(connectionRole: ConnectionRole) {
@@ -54,5 +55,12 @@ class NetplaySetupViewModel : ViewModel() {
}
fun connect() {
+ Netplay.saveSetup(
+ nickname = nickname.value,
+ connectionType = connectionType.value,
+ address = ipAddress.value,
+ hostCode = hostCode.value,
+ connectPort = connectPort.value.toInt(),
+ )
}
}
diff --git a/Source/Android/jni/CMakeLists.txt b/Source/Android/jni/CMakeLists.txt
index a15eb5c636..a71668a758 100644
--- a/Source/Android/jni/CMakeLists.txt
+++ b/Source/Android/jni/CMakeLists.txt
@@ -30,6 +30,7 @@ add_library(main SHARED
Input/MappingCommon.cpp
Input/NumericSetting.cpp
Input/NumericSetting.h
+ NetPlay/Netplay.cpp
MainAndroid.cpp
RiivolutionPatches.cpp
SkylanderConfig.cpp
diff --git a/Source/Android/jni/NetPlay/Netplay.cpp b/Source/Android/jni/NetPlay/Netplay.cpp
new file mode 100644
index 0000000000..245a24852c
--- /dev/null
+++ b/Source/Android/jni/NetPlay/Netplay.cpp
@@ -0,0 +1,120 @@
+// Copyright 2003 Dolphin Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include <string>
+
+#include <jni.h>
+
+#include "Common/CommonTypes.h"
+#include "Core/Config/NetplaySettings.h"
+
+#include "jni/AndroidCommon/AndroidCommon.h"
+
+extern "C" {
+
+JNIEXPORT jstring JNICALL
+Java_org_dolphinemu_dolphinemu_features_netplay_Netplay_getNickname(JNIEnv* env, jclass)
+{
+ return ToJString(env, Config::Get(Config::NETPLAY_NICKNAME));
+}
+
+JNIEXPORT jstring JNICALL
+Java_org_dolphinemu_dolphinemu_features_netplay_Netplay_getTraversalChoice(JNIEnv* env, jclass)
+{
+ return ToJString(env, Config::Get(Config::NETPLAY_TRAVERSAL_CHOICE));
+}
+
+JNIEXPORT jstring JNICALL
+Java_org_dolphinemu_dolphinemu_features_netplay_Netplay_getAddress(JNIEnv* env, jclass)
+{
+ return ToJString(env, Config::Get(Config::NETPLAY_ADDRESS));
+}
+
+JNIEXPORT jstring JNICALL
+Java_org_dolphinemu_dolphinemu_features_netplay_Netplay_getHostCode(JNIEnv* env, jclass)
+{
+ return ToJString(env, Config::Get(Config::NETPLAY_HOST_CODE));
+}
+
+JNIEXPORT jint JNICALL
+Java_org_dolphinemu_dolphinemu_features_netplay_Netplay_getConnectPort(JNIEnv*, jclass)
+{
+ return static_cast<jint>(Config::Get(Config::NETPLAY_CONNECT_PORT));
+}
+
+JNIEXPORT jint JNICALL
+Java_org_dolphinemu_dolphinemu_features_netplay_Netplay_getHostPort(JNIEnv*, jclass)
+{
+ return static_cast<jint>(Config::Get(Config::NETPLAY_HOST_PORT));
+}
+
+JNIEXPORT jboolean JNICALL
+Java_org_dolphinemu_dolphinemu_features_netplay_Netplay_getUseUpnp(JNIEnv*, jclass)
+{
+ return static_cast<jboolean>(Config::Get(Config::NETPLAY_USE_UPNP));
+}
+
+JNIEXPORT jboolean JNICALL
+Java_org_dolphinemu_dolphinemu_features_netplay_Netplay_getEnableChunkedUploadLimit(JNIEnv*, jclass)
+{
+ return static_cast<jboolean>(Config::Get(Config::NETPLAY_ENABLE_CHUNKED_UPLOAD_LIMIT));
+}
+
+JNIEXPORT jint JNICALL
+Java_org_dolphinemu_dolphinemu_features_netplay_Netplay_getChunkedUploadLimit(JNIEnv*, jclass)
+{
+ return static_cast<jint>(Config::Get(Config::NETPLAY_CHUNKED_UPLOAD_LIMIT));
+}
+
+JNIEXPORT jboolean JNICALL
+Java_org_dolphinemu_dolphinemu_features_netplay_Netplay_getUseIndex(JNIEnv*, jclass)
+{
+ return static_cast<jboolean>(Config::Get(Config::NETPLAY_USE_INDEX));
+}
+
+JNIEXPORT jstring JNICALL
+Java_org_dolphinemu_dolphinemu_features_netplay_Netplay_getIndexRegion(JNIEnv* env, jclass)
+{
+ return ToJString(env, Config::Get(Config::NETPLAY_INDEX_REGION));
+}
+
+JNIEXPORT jstring JNICALL
+Java_org_dolphinemu_dolphinemu_features_netplay_Netplay_getIndexName(JNIEnv* env, jclass)
+{
+ return ToJString(env, Config::Get(Config::NETPLAY_INDEX_NAME));
+}
+
+JNIEXPORT jstring JNICALL
+Java_org_dolphinemu_dolphinemu_features_netplay_Netplay_getIndexPassword(JNIEnv* env, jclass)
+{
+ return ToJString(env, Config::Get(Config::NETPLAY_INDEX_PASSWORD));
+}
+
+JNIEXPORT void JNICALL
+Java_org_dolphinemu_dolphinemu_features_netplay_Netplay_SaveSetup(
+ JNIEnv* env, jclass, jstring jnickname, jstring traversalChoice, jstring jaddress,
+ jstring jhostCode, jint connectPort, jint hostPort, jboolean useUpnp, jboolean useListenPort,
+ jint listenPort, jboolean enableChunkedUploadLimit, jint chunkedUploadLimit, jboolean useIndex,
+ jstring jindexRegion, jstring jindexName, jstring jindexPassword)
+{
+ Config::ConfigChangeCallbackGuard config_guard;
+
+ Config::SetBaseOrCurrent(Config::NETPLAY_NICKNAME, GetJString(env, jnickname));
+ Config::SetBaseOrCurrent(Config::NETPLAY_TRAVERSAL_CHOICE, GetJString(env, traversalChoice));
+ Config::SetBaseOrCurrent(Config::NETPLAY_ADDRESS, GetJString(env, jaddress));
+ Config::SetBaseOrCurrent(Config::NETPLAY_HOST_CODE, GetJString(env, jhostCode));
+ Config::SetBaseOrCurrent(Config::NETPLAY_CONNECT_PORT, static_cast<u16>(connectPort));
+ Config::SetBaseOrCurrent(Config::NETPLAY_HOST_PORT, static_cast<u16>(hostPort));
+ Config::SetBaseOrCurrent(Config::NETPLAY_USE_UPNP, static_cast<bool>(useUpnp));
+ Config::SetBaseOrCurrent(Config::NETPLAY_ENABLE_CHUNKED_UPLOAD_LIMIT,
+ static_cast<bool>(enableChunkedUploadLimit));
+ Config::SetBaseOrCurrent(Config::NETPLAY_CHUNKED_UPLOAD_LIMIT,
+ static_cast<u32>(chunkedUploadLimit));
+ Config::SetBaseOrCurrent(Config::NETPLAY_USE_INDEX, static_cast<bool>(useIndex));
+ Config::SetBaseOrCurrent(Config::NETPLAY_INDEX_REGION, GetJString(env, jindexRegion));
+ Config::SetBaseOrCurrent(Config::NETPLAY_INDEX_NAME, GetJString(env, jindexName));
+ Config::SetBaseOrCurrent(Config::NETPLAY_INDEX_PASSWORD, GetJString(env, jindexPassword));
+ Config::SetBaseOrCurrent(Config::NETPLAY_LISTEN_PORT, static_cast<u16>(listenPort));
+}
+
+} // extern "C"