summaryrefslogtreecommitdiff
path: root/Source/Android/app/src/main/java/org
diff options
context:
space:
mode:
authorSimonx22 <simon@oatmealdome.me>2026-04-06 18:07:21 -0400
committerSimonx22 <simon@oatmealdome.me>2026-04-06 18:21:07 -0400
commit662b1d74a8ee5ccd79c8c5a3b7fef9229e8ee0a2 (patch)
treea559e32eba85002ec5c94f801ccdcb929b888915 /Source/Android/app/src/main/java/org
parent5abf0e35560b3d2e1be0ad0db825e343c3e2c8fe (diff)
Android: Convert WiimoteAdapter to Kotlin
Diffstat (limited to 'Source/Android/app/src/main/java/org')
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/WiimoteAdapter.java172
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/WiimoteAdapter.kt153
2 files changed, 153 insertions, 172 deletions
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/WiimoteAdapter.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/WiimoteAdapter.java
deleted file mode 100644
index 98a7d51900..0000000000
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/WiimoteAdapter.java
+++ /dev/null
@@ -1,172 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-package org.dolphinemu.dolphinemu.utils;
-
-import android.app.PendingIntent;
-import android.content.Context;
-import android.content.Intent;
-import android.hardware.usb.UsbConfiguration;
-import android.hardware.usb.UsbDevice;
-import android.hardware.usb.UsbDeviceConnection;
-import android.hardware.usb.UsbEndpoint;
-import android.hardware.usb.UsbInterface;
-import android.hardware.usb.UsbManager;
-import android.os.Build;
-
-import androidx.annotation.Keep;
-
-import org.dolphinemu.dolphinemu.DolphinApplication;
-import org.dolphinemu.dolphinemu.services.USBPermService;
-
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.Map;
-
-public class WiimoteAdapter
-{
- final static int MAX_PAYLOAD = 23;
- final static int MAX_WIIMOTES = 4;
- final static int TIMEOUT = 200;
- final static short NINTENDO_VENDOR_ID = 0x057e;
- final static short NINTENDO_WIIMOTE_PRODUCT_ID = 0x0306;
- public static UsbManager manager;
-
- static UsbDeviceConnection usbConnection;
- static UsbInterface[] usbInterface = new UsbInterface[MAX_WIIMOTES];
- static UsbEndpoint[] usbIn = new UsbEndpoint[MAX_WIIMOTES];
-
- @Keep
- public static byte[][] wiimotePayload = new byte[MAX_WIIMOTES][MAX_PAYLOAD];
-
- private static void requestPermission()
- {
- HashMap<String, UsbDevice> devices = manager.getDeviceList();
- for (Map.Entry<String, UsbDevice> pair : devices.entrySet())
- {
- UsbDevice dev = pair.getValue();
- if (dev.getProductId() == NINTENDO_WIIMOTE_PRODUCT_ID &&
- dev.getVendorId() == NINTENDO_VENDOR_ID)
- {
- if (!manager.hasPermission(dev))
- {
- Log.warning("Requesting permission for Wii Remote adapter");
-
- Context context = DolphinApplication.getAppContext();
- Intent intent = new Intent(context, USBPermService.class);
-
- int flags = Build.VERSION.SDK_INT >= Build.VERSION_CODES.M ?
- PendingIntent.FLAG_IMMUTABLE : 0;
- PendingIntent pendingIntent = PendingIntent.getService(context, 0, intent, flags);
-
- manager.requestPermission(dev, pendingIntent);
- }
- }
- }
- }
-
- @Keep
- public static boolean queryAdapter()
- {
- HashMap<String, UsbDevice> devices = manager.getDeviceList();
- for (Map.Entry<String, UsbDevice> pair : devices.entrySet())
- {
- UsbDevice dev = pair.getValue();
- if (dev.getProductId() == NINTENDO_WIIMOTE_PRODUCT_ID &&
- dev.getVendorId() == NINTENDO_VENDOR_ID)
- {
- if (manager.hasPermission(dev))
- return true;
- else
- requestPermission();
- }
- }
- return false;
- }
-
- @Keep
- public static int input(int index)
- {
- return usbConnection.bulkTransfer(usbIn[index], wiimotePayload[index], MAX_PAYLOAD, TIMEOUT);
- }
-
- @Keep
- public static int output(int index, byte[] buf, int size)
- {
- byte report_number = buf[0];
-
- // Remove the report number from the buffer
- buf = Arrays.copyOfRange(buf, 1, buf.length);
- size--;
-
- final int LIBUSB_REQUEST_TYPE_CLASS = (1 << 5);
- final int LIBUSB_RECIPIENT_INTERFACE = 0x1;
- final int LIBUSB_ENDPOINT_OUT = 0;
-
- final int HID_SET_REPORT = 0x9;
- final int HID_OUTPUT = (2 << 8);
-
- int write = usbConnection.controlTransfer(
- LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_RECIPIENT_INTERFACE | LIBUSB_ENDPOINT_OUT,
- HID_SET_REPORT,
- HID_OUTPUT | report_number,
- index,
- buf, size,
- 1000);
-
- if (write < 0)
- return 0;
-
- return write + 1;
- }
-
- @Keep
- public static boolean openAdapter()
- {
- // If the adapter is already open. Don't attempt to do it again
- if (usbConnection != null && usbConnection.getFileDescriptor() != -1)
- return true;
-
- HashMap<String, UsbDevice> devices = manager.getDeviceList();
- for (Map.Entry<String, UsbDevice> pair : devices.entrySet())
- {
- UsbDevice dev = pair.getValue();
- if (dev.getProductId() == NINTENDO_WIIMOTE_PRODUCT_ID &&
- dev.getVendorId() == NINTENDO_VENDOR_ID)
- {
- if (manager.hasPermission(dev))
- {
- usbConnection = manager.openDevice(dev);
- UsbConfiguration conf = dev.getConfiguration(0);
-
- Log.info("Number of configurations: " + dev.getConfigurationCount());
- Log.info("Number of Interfaces: " + dev.getInterfaceCount());
- Log.info("Number of Interfaces from conf: " + conf.getInterfaceCount());
-
- // Sometimes the interface count is returned as zero.
- // Means the device needs to be unplugged and plugged back in again
- if (dev.getInterfaceCount() > 0)
- {
- for (int i = 0; i < MAX_WIIMOTES; ++i)
- {
- // One interface per Wii Remote
- usbInterface[i] = dev.getInterface(i);
- usbConnection.claimInterface(usbInterface[i], true);
-
- // One endpoint per Wii Remote. Input only
- // Output reports go through the control channel.
- usbIn[i] = usbInterface[i].getEndpoint(0);
- Log.info("Interface " + i + " endpoint count:" + usbInterface[i].getEndpointCount());
- }
- return true;
- }
- else
- {
- // XXX: Message that the device was found, but it needs to be unplugged and plugged back in?
- usbConnection.close();
- }
- }
- }
- }
- return false;
- }
-}
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/WiimoteAdapter.kt b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/WiimoteAdapter.kt
new file mode 100644
index 0000000000..5f7c2bcb90
--- /dev/null
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/WiimoteAdapter.kt
@@ -0,0 +1,153 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+package org.dolphinemu.dolphinemu.utils
+
+import android.app.PendingIntent
+import android.content.Context
+import android.content.Intent
+import android.hardware.usb.UsbConfiguration
+import android.hardware.usb.UsbDeviceConnection
+import android.hardware.usb.UsbEndpoint
+import android.hardware.usb.UsbInterface
+import android.hardware.usb.UsbManager
+import androidx.annotation.Keep
+import org.dolphinemu.dolphinemu.DolphinApplication
+import org.dolphinemu.dolphinemu.services.USBPermService
+import java.util.Arrays
+
+object WiimoteAdapter {
+ private const val MAX_PAYLOAD = 23
+ private const val MAX_WIIMOTES = 4
+ private const val TIMEOUT = 200
+ private const val NINTENDO_VENDOR_ID = 0x057e
+ private const val NINTENDO_WIIMOTE_PRODUCT_ID = 0x0306
+
+ lateinit var manager: UsbManager
+
+ private var usbConnection: UsbDeviceConnection? = null
+ private val usbInterface = arrayOfNulls<UsbInterface>(MAX_WIIMOTES)
+ private val usbIn = arrayOfNulls<UsbEndpoint>(MAX_WIIMOTES)
+
+ @Keep
+ @JvmField
+ val wiimotePayload: Array<ByteArray> = Array(MAX_WIIMOTES) { ByteArray(MAX_PAYLOAD) }
+
+ private fun requestPermission() {
+ val devices = manager.deviceList
+ for (dev in devices.values) {
+ if (dev.productId == NINTENDO_WIIMOTE_PRODUCT_ID && dev.vendorId == NINTENDO_VENDOR_ID) {
+ if (!manager.hasPermission(dev)) {
+ Log.warning("Requesting permission for Wii Remote adapter")
+
+ val context: Context = DolphinApplication.getAppContext()
+ val intent = Intent(context, USBPermService::class.java)
+
+ val pendingIntent =
+ PendingIntent.getService(context, 0, intent, PendingIntent.FLAG_IMMUTABLE)
+
+ manager.requestPermission(dev, pendingIntent)
+ }
+ }
+ }
+ }
+
+ @Keep
+ @JvmStatic
+ fun queryAdapter(): Boolean {
+ val devices = manager.deviceList
+ for (dev in devices.values) {
+ if (dev.productId == NINTENDO_WIIMOTE_PRODUCT_ID && dev.vendorId == NINTENDO_VENDOR_ID) {
+ if (manager.hasPermission(dev)) {
+ return true
+ } else {
+ requestPermission()
+ }
+ }
+ }
+ return false
+ }
+
+ @Keep
+ @JvmStatic
+ fun input(index: Int): Int {
+ return usbConnection!!.bulkTransfer(
+ usbIn[index], wiimotePayload[index], MAX_PAYLOAD, TIMEOUT
+ )
+ }
+
+ @Keep
+ @JvmStatic
+ fun output(index: Int, buf: ByteArray, size: Int): Int {
+ val reportNumber = buf[0]
+
+ // Remove the report number from the buffer
+ val outputBuffer = Arrays.copyOfRange(buf, 1, buf.size)
+ val outputSize = size - 1
+
+ val libusbRequestTypeClass = 1 shl 5
+ val libusbRecipientInterface = 0x1
+ val libusbEndpointOut = 0
+
+ val hidSetReport = 0x9
+ val hidOutput = 2 shl 8
+
+ val write = usbConnection!!.controlTransfer(
+ libusbRequestTypeClass or libusbRecipientInterface or libusbEndpointOut,
+ hidSetReport,
+ hidOutput or reportNumber.toInt(),
+ index,
+ outputBuffer,
+ outputSize,
+ 1000
+ )
+
+ if (write < 0) {
+ return 0
+ }
+
+ return write + 1
+ }
+
+ @Keep
+ @JvmStatic
+ fun openAdapter(): Boolean {
+ // If the adapter is already open. Don't attempt to do it again
+ if (usbConnection != null && usbConnection!!.fileDescriptor != -1) {
+ return true
+ }
+
+ val devices = manager.deviceList
+ for (dev in devices.values) {
+ if (dev.productId == NINTENDO_WIIMOTE_PRODUCT_ID && dev.vendorId == NINTENDO_VENDOR_ID) {
+ if (manager.hasPermission(dev)) {
+ usbConnection = manager.openDevice(dev)
+ val conf: UsbConfiguration = dev.getConfiguration(0)
+
+ Log.info("Number of configurations: " + dev.configurationCount)
+ Log.info("Number of Interfaces: " + dev.interfaceCount)
+ Log.info("Number of Interfaces from conf: " + conf.interfaceCount)
+
+ // Sometimes the interface count is returned as zero.
+ // Means the device needs to be unplugged and plugged back in again
+ if (dev.interfaceCount > 0) {
+ for (i in 0 until MAX_WIIMOTES) {
+ // One interface per Wii Remote
+ usbInterface[i] = dev.getInterface(i)
+ usbConnection!!.claimInterface(usbInterface[i], true)
+
+ // One endpoint per Wii Remote. Input only
+ // Output reports go through the control channel.
+ usbIn[i] = usbInterface[i]!!.getEndpoint(0)
+ Log.info("Interface " + i + " endpoint count:" + usbInterface[i]!!.endpointCount)
+ }
+ return true
+ } else {
+ // XXX: Message that the device was found, but it needs to be unplugged and plugged back in?
+ usbConnection!!.close()
+ }
+ }
+ }
+ }
+ return false
+ }
+}