├── Android ├── app │ ├── .gitignore │ ├── src │ │ ├── main │ │ │ ├── jni │ │ │ │ ├── Application.mk │ │ │ │ ├── Android.mk │ │ │ │ ├── joycon.c │ │ │ │ ├── include │ │ │ │ │ ├── jni_utils.h │ │ │ │ │ ├── crc8.h │ │ │ │ │ └── joycon.h │ │ │ │ ├── com_mumumusuc_joycon_Joycon.h │ │ │ │ ├── jc_desc.txt │ │ │ │ ├── com_mumumusuc_joycon_Joycon.c │ │ │ │ └── joycon_report.c │ │ │ ├── assets │ │ │ │ ├── xposed_init │ │ │ │ └── pro_spi.bin │ │ │ ├── res │ │ │ │ ├── drawable │ │ │ │ │ ├── ns_logo.png │ │ │ │ │ ├── player_1.png │ │ │ │ │ ├── player_2.png │ │ │ │ │ ├── player_3.png │ │ │ │ │ ├── player_4.png │ │ │ │ │ ├── player_bg.png │ │ │ │ │ ├── bg_round.xml │ │ │ │ │ ├── ic_btn_minus.xml │ │ │ │ │ ├── ic_btn_home.xml │ │ │ │ │ ├── ic_btn_plus.xml │ │ │ │ │ ├── ic_btn_up.xml │ │ │ │ │ ├── ic_btn_down.xml │ │ │ │ │ ├── ic_btn_left.xml │ │ │ │ │ ├── ic_btn_right.xml │ │ │ │ │ ├── bg_splash.xml │ │ │ │ │ ├── ic_btn_capture.xml │ │ │ │ │ ├── player_list.xml │ │ │ │ │ └── ic_launcher_background.xml │ │ │ │ ├── mipmap-hdpi │ │ │ │ │ ├── ic_launcher.png │ │ │ │ │ └── ic_launcher_round.png │ │ │ │ ├── mipmap-mdpi │ │ │ │ │ ├── ic_launcher.png │ │ │ │ │ └── ic_launcher_round.png │ │ │ │ ├── mipmap-xhdpi │ │ │ │ │ ├── ic_launcher.png │ │ │ │ │ └── ic_launcher_round.png │ │ │ │ ├── mipmap-xxhdpi │ │ │ │ │ ├── ic_launcher.png │ │ │ │ │ └── ic_launcher_round.png │ │ │ │ ├── mipmap-xxxhdpi │ │ │ │ │ ├── ic_launcher.png │ │ │ │ │ └── ic_launcher_round.png │ │ │ │ ├── mipmap-anydpi-v26 │ │ │ │ │ ├── ic_launcher.xml │ │ │ │ │ └── ic_launcher_round.xml │ │ │ │ ├── drawable-v24 │ │ │ │ │ ├── ic_square_black_24dp.xml │ │ │ │ │ ├── ic_triangle_black_24dp.xml │ │ │ │ │ ├── ic_cross_black_24dp.xml │ │ │ │ │ ├── ic_circle_black_24dp.xml │ │ │ │ │ ├── ic_launcher_foreground.xml │ │ │ │ │ └── ic_launcher_background.xml │ │ │ │ ├── values │ │ │ │ │ ├── dimens.xml │ │ │ │ │ ├── attrs.xml │ │ │ │ │ ├── colors.xml │ │ │ │ │ ├── strings.xml │ │ │ │ │ └── styles.xml │ │ │ │ └── layout │ │ │ │ │ ├── activity_main.xml │ │ │ │ │ ├── connection.xml │ │ │ │ │ └── gamepad.xml │ │ │ ├── java │ │ │ │ └── com │ │ │ │ │ └── mumumusuc │ │ │ │ │ └── droidpro │ │ │ │ │ ├── Utils.kt │ │ │ │ │ ├── eventbus │ │ │ │ │ └── JcEvent.kt │ │ │ │ │ ├── IHidDevice.kt │ │ │ │ │ ├── fragment │ │ │ │ │ ├── Connection.kt │ │ │ │ │ └── Gamepad.kt │ │ │ │ │ ├── ProBtGamepad.kt │ │ │ │ │ ├── XposedUtil.kt │ │ │ │ │ ├── MainActivity.kt │ │ │ │ │ ├── BtHidClient.kt │ │ │ │ │ └── JoyconProxy.kt │ │ │ └── AndroidManifest.xml │ │ └── androidTest │ │ │ └── java │ │ │ └── com │ │ │ └── mumumusuc │ │ │ └── droidpro │ │ │ └── ExampleInstrumentedTest.kt │ ├── proguard-rules.pro │ └── build.gradle ├── settings.gradle ├── LibJoycon-release │ ├── build.gradle │ └── LibJoycon-release.aar ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── .gitignore ├── build.gradle ├── gradle.properties ├── gradlew.bat └── gradlew ├── images ├── bt-pro.png └── sample.jpg ├── .gitmodules ├── .gitignore ├── README.md └── LICENSE /Android/app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /Android/app/src/main/jni/Application.mk: -------------------------------------------------------------------------------- 1 | APP_ABI := all -------------------------------------------------------------------------------- /Android/settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app', ':LibJoycon-release' 2 | -------------------------------------------------------------------------------- /Android/app/src/main/assets/xposed_init: -------------------------------------------------------------------------------- 1 | com.mumumusuc.droidpro.XposedUtil -------------------------------------------------------------------------------- /images/bt-pro.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mumumusuc/Bluetooth-Joycon/HEAD/images/bt-pro.png -------------------------------------------------------------------------------- /images/sample.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mumumusuc/Bluetooth-Joycon/HEAD/images/sample.jpg -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "LibJoycon"] 2 | path = LibJoycon 3 | url = git@github.com:mumumusuc/LibJoycon.git 4 | -------------------------------------------------------------------------------- /Android/LibJoycon-release/build.gradle: -------------------------------------------------------------------------------- 1 | configurations.maybeCreate("default") 2 | artifacts.add("default", file('LibJoycon-release.aar')) -------------------------------------------------------------------------------- /Android/app/src/main/assets/pro_spi.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mumumusuc/Bluetooth-Joycon/HEAD/Android/app/src/main/assets/pro_spi.bin -------------------------------------------------------------------------------- /Android/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mumumusuc/Bluetooth-Joycon/HEAD/Android/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /Android/app/src/main/res/drawable/ns_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mumumusuc/Bluetooth-Joycon/HEAD/Android/app/src/main/res/drawable/ns_logo.png -------------------------------------------------------------------------------- /Android/LibJoycon-release/LibJoycon-release.aar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mumumusuc/Bluetooth-Joycon/HEAD/Android/LibJoycon-release/LibJoycon-release.aar -------------------------------------------------------------------------------- /Android/app/src/main/res/drawable/player_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mumumusuc/Bluetooth-Joycon/HEAD/Android/app/src/main/res/drawable/player_1.png -------------------------------------------------------------------------------- /Android/app/src/main/res/drawable/player_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mumumusuc/Bluetooth-Joycon/HEAD/Android/app/src/main/res/drawable/player_2.png -------------------------------------------------------------------------------- /Android/app/src/main/res/drawable/player_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mumumusuc/Bluetooth-Joycon/HEAD/Android/app/src/main/res/drawable/player_3.png -------------------------------------------------------------------------------- /Android/app/src/main/res/drawable/player_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mumumusuc/Bluetooth-Joycon/HEAD/Android/app/src/main/res/drawable/player_4.png -------------------------------------------------------------------------------- /Android/app/src/main/res/drawable/player_bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mumumusuc/Bluetooth-Joycon/HEAD/Android/app/src/main/res/drawable/player_bg.png -------------------------------------------------------------------------------- /Android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mumumusuc/Bluetooth-Joycon/HEAD/Android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /Android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mumumusuc/Bluetooth-Joycon/HEAD/Android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /Android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mumumusuc/Bluetooth-Joycon/HEAD/Android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /Android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mumumusuc/Bluetooth-Joycon/HEAD/Android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /Android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mumumusuc/Bluetooth-Joycon/HEAD/Android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /Android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mumumusuc/Bluetooth-Joycon/HEAD/Android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /Android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mumumusuc/Bluetooth-Joycon/HEAD/Android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /Android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mumumusuc/Bluetooth-Joycon/HEAD/Android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /Android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mumumusuc/Bluetooth-Joycon/HEAD/Android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /Android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mumumusuc/Bluetooth-Joycon/HEAD/Android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /Android/.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/caches 5 | /.idea/libraries 6 | /.idea/modules.xml 7 | /.idea/workspace.xml 8 | /.idea/navEditor.xml 9 | /.idea/assetWizardSettings.xml 10 | .DS_Store 11 | /build 12 | /captures 13 | .externalNativeBuild 14 | -------------------------------------------------------------------------------- /Android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Mon May 27 17:33:43 CST 2019 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-5.1.1-all.zip 7 | -------------------------------------------------------------------------------- /Android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /Android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /Android/app/src/main/jni/Android.mk: -------------------------------------------------------------------------------- 1 | LOCAL_PATH := $(call my-dir) 2 | include $(CLEAR_VARS) 3 | 4 | LOCAL_MODULE := joycon 5 | LOCAL_SRC_FILES := \ 6 | com_mumumusuc_joycon_Joycon.c \ 7 | joycon.c \ 8 | joycon_report.c 9 | 10 | LOCAL_LDLIBS := -llog -landroid 11 | 12 | 13 | include $(BUILD_SHARED_LIBRARY) 14 | -------------------------------------------------------------------------------- /Android/app/src/main/res/drawable/bg_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /Android/app/src/main/res/drawable/ic_btn_minus.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /Android/app/src/main/res/drawable/ic_btn_home.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /Android/app/src/main/res/drawable/ic_btn_plus.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /Android/app/src/main/res/drawable-v24/ic_square_black_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /Android/app/src/main/res/drawable/ic_btn_up.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /Android/app/src/main/res/drawable/ic_btn_down.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /Android/app/src/main/res/drawable/ic_btn_left.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /Android/app/src/main/res/drawable/ic_btn_right.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /Android/app/src/main/res/drawable/bg_splash.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /Android/app/src/main/res/drawable-v24/ic_triangle_black_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /Android/app/src/main/res/drawable-v24/ic_cross_black_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /Android/app/src/main/res/drawable-v24/ic_circle_black_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /Android/app/src/main/res/drawable/ic_btn_capture.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /Android/app/src/main/res/values/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 16dp 4 | 16dp 5 | 6 | 450dp 7 | 350dp 8 | 52dp 9 | 45dp 10 | 28sp 11 | 12 | -------------------------------------------------------------------------------- /Android/app/src/main/res/drawable/player_list.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Android/app/src/main/res/values/attrs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /Android/app/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | @color/dark_gray 4 | @color/dark_gray 5 | #D81B60 6 | #66000000 7 | 8 | #303030 9 | @android:color/white 10 | @android:color/white 11 | @android:color/black 12 | 13 | -------------------------------------------------------------------------------- /Android/app/src/main/java/com/mumumusuc/droidpro/Utils.kt: -------------------------------------------------------------------------------- 1 | package com.mumumusuc.droidpro 2 | 3 | import java.lang.StringBuilder 4 | 5 | object Utils { 6 | private val sb by lazy { StringBuilder() } 7 | fun Array2String(fmt: String, data: Collection): String { 8 | sb.clear() 9 | for (i in 0 until data.size) { 10 | if (i in 61..320) 11 | continue 12 | if (i == 60) 13 | sb.append("... ") 14 | else 15 | sb.append(String.format(fmt, data.elementAt(i))) 16 | } 17 | return sb.toString() 18 | } 19 | } -------------------------------------------------------------------------------- /Android/app/src/main/java/com/mumumusuc/droidpro/eventbus/JcEvent.kt: -------------------------------------------------------------------------------- 1 | package com.mumumusuc.droidpro.eventbus 2 | 3 | import com.mumumusuc.joycon.Joycon.NsButton 4 | 5 | enum class JcConnectStatus { 6 | CONNECTING, CONNECTED, DISCONNECTING, DISCONNECTED, REQUEST 7 | } 8 | 9 | class JcPlayerChangeEvent(val player: Int) 10 | 11 | class JcConnectEvent(val status: JcConnectStatus) 12 | 13 | class JcInputEvent(val reportId: Int) 14 | 15 | class JcOutputEvent(val reportId: Int, val data: ByteArray) 16 | 17 | class JcButtonEvent(val mask: NsButton, val value: Boolean) 18 | 19 | class JcStickEvent(val ls: Pair?, val rs: Pair?) 20 | 21 | class JcImuEvent(val accl: IntArray?, val gyro: IntArray?) -------------------------------------------------------------------------------- /Android/build.gradle: -------------------------------------------------------------------------------- 1 | // Top-level build file where you can add configuration options common to all sub-projects/modules. 2 | 3 | buildscript { 4 | ext.kotlin_version = '1.3.21' 5 | repositories { 6 | google() 7 | jcenter() 8 | 9 | } 10 | dependencies { 11 | classpath 'com.android.tools.build:gradle:3.4.1' 12 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" 13 | // NOTE: Do not place your application dependencies here; they belong 14 | // in the individual module build.gradle files 15 | } 16 | } 17 | 18 | allprojects { 19 | repositories { 20 | google() 21 | jcenter() 22 | 23 | } 24 | } 25 | 26 | task clean(type: Delete) { 27 | delete rootProject.buildDir 28 | } 29 | -------------------------------------------------------------------------------- /Android/app/src/main/jni/joycon.c: -------------------------------------------------------------------------------- 1 | #include "include/joycon.h" 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | int jc_init(joycon_t *jc) { 10 | assert(jc->spi_fd >= 0); 11 | assert(jc->status); 12 | assert(jc->input); 13 | jc_status_t *status = jc->status; 14 | status->voltage = 0x0690; 15 | status->con_type = CON_PRO_CG | CON_BT; 16 | status->battery = LEVEL_FULL; 17 | status->dev_type = DEV_PRO; 18 | status->vibrate = 0x09; 19 | status->enable_imu = false; 20 | status->start_push = false; 21 | return 0; 22 | } 23 | 24 | void jc_free(joycon_t *jc) { 25 | if (!jc) 26 | return; 27 | close(jc->spi_fd); 28 | //free(jc->input); 29 | //free(jc->status); 30 | } -------------------------------------------------------------------------------- /Android/app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | DroidPro 3 | Connect to: 4 | Status: 5 | Disconnected 6 | Connecting… 7 | Connected 8 | Disconnecting… 9 | cross 10 | circle 11 | triangle 12 | square 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /Android/app/src/androidTest/java/com/mumumusuc/droidpro/ExampleInstrumentedTest.kt: -------------------------------------------------------------------------------- 1 | package com.mumumusuc.droidpro 2 | 3 | import android.support.test.InstrumentationRegistry 4 | import android.support.test.runner.AndroidJUnit4 5 | 6 | import org.junit.Test 7 | import org.junit.runner.RunWith 8 | 9 | import org.junit.Assert.* 10 | 11 | /** 12 | * Instrumented test, which will execute on an Android device. 13 | * 14 | * See [testing documentation](http://d.android.com/tools/testing). 15 | */ 16 | @RunWith(AndroidJUnit4::class) 17 | class ExampleInstrumentedTest { 18 | @Test 19 | fun useAppContext() { 20 | // Context of the app under test. 21 | val appContext = InstrumentationRegistry.getTargetContext() 22 | assertEquals("com.mumumusuc.droidpro", appContext.packageName) 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Android/app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /Android/gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | 3 | # IDE (e.g. Android Studio) users: 4 | # Gradle settings configured through the IDE *will override* 5 | # any settings specified in this file. 6 | 7 | # For more details on how to configure your build environment visit 8 | # http://www.gradle.org/docs/current/userguide/build_environment.html 9 | 10 | # Specifies the JVM arguments used for the daemon process. 11 | # The setting is particularly useful for tweaking memory settings. 12 | org.gradle.jvmargs=-Xmx1536m 13 | 14 | # When configured, Gradle will run in incubating parallel mode. 15 | # This option should only be used with decoupled projects. More details, visit 16 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 17 | # org.gradle.parallel=true 18 | 19 | 20 | # Kotlin code style for this project: "official" or "obsolete": 21 | kotlin.code.style=official 22 | -------------------------------------------------------------------------------- /Android/app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 13 | 14 | 15 | 20 | 21 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Prerequisites 2 | *.d 3 | 4 | # Object files 5 | *.o 6 | *.ko 7 | *.obj 8 | *.elf 9 | 10 | # Linker output 11 | *.ilk 12 | *.map 13 | *.exp 14 | 15 | # Precompiled Headers 16 | *.gch 17 | *.pch 18 | 19 | # Libraries 20 | *.lib 21 | *.a 22 | *.la 23 | *.lo 24 | 25 | # Shared objects (inc. Windows DLLs) 26 | *.dll 27 | *.so 28 | *.so.* 29 | *.dylib 30 | 31 | # Executables 32 | *.exe 33 | *.out 34 | *.app 35 | *.i*86 36 | *.x86_64 37 | *.hex 38 | 39 | # Debug files 40 | *.dSYM/ 41 | *.su 42 | *.idb 43 | *.pdb 44 | 45 | # Kernel Module Compile Results 46 | *.mod* 47 | *.cmd 48 | .tmp_versions/ 49 | modules.order 50 | Module.symvers 51 | Mkfile.old 52 | dkms.conf 53 | 54 | # CMake 55 | cmake-build-debug 56 | cmake-build-release 57 | .cache.mk 58 | 59 | # IDE 60 | .idea 61 | build 62 | 63 | # web 64 | .idea 65 | node_modules 66 | test 67 | 68 | Android/*.iml 69 | Android/.gradle 70 | Android/local.properties 71 | Android/.idea/caches 72 | Android/.idea/libraries 73 | Android/.idea/modules.xml 74 | Android/.idea/workspace.xml 75 | Android/.idea/navEditor.xml 76 | Android/.idea/assetWizardSettings.xml 77 | Android.DS_Store 78 | Android/build 79 | Android/captures 80 | Android.externalNativeBuild 81 | -------------------------------------------------------------------------------- /Android/app/src/main/java/com/mumumusuc/droidpro/IHidDevice.kt: -------------------------------------------------------------------------------- 1 | package com.mumumusuc.droidpro 2 | 3 | import android.bluetooth.BluetoothHidDevice 4 | 5 | interface IHidClient { 6 | fun register() 7 | fun unregister() 8 | fun resume(): Boolean 9 | fun pause() 10 | fun connect(name: String): Boolean 11 | fun disconnect(): Boolean 12 | fun sendInputReport(reportId: Int, data: ByteArray): Boolean 13 | } 14 | 15 | abstract class HidDeviceConfig { 16 | open val SERVICE_NAME: String = "BlueHID" 17 | open val SERVICE_DESC: String = "Android HID" 18 | open val SERVICE_PROV: String = "Android" 19 | open val SUBCLASS: Byte = BluetoothHidDevice.SUBCLASS1_NONE 20 | protected open val BCD_VERSION: Int get() = 0x0111 21 | protected open val COUNTRY_CODE: Byte get() = 0x00 22 | protected open val DESC_NUM: Byte get() = 0x01 23 | protected open val DESC_TYEP: Byte get() = 0x22 24 | protected abstract val DESC_LEN: Int 25 | protected abstract val DESCRIPTOR: ByteArray 26 | 27 | private fun int2Le(uint16: Int): ByteArray { 28 | return byteArrayOf(uint16.and(0xFF).toByte(), uint16.shr(8).and(0xFF).toByte()) 29 | } 30 | 31 | fun descriptor(): ByteArray { 32 | val r = mutableListOf(0x09/*bLength*/, 0x21 /*bDescriptorType*/) 33 | r.addAll(int2Le(BCD_VERSION).asList()) 34 | r.add(COUNTRY_CODE) 35 | r.add(DESC_NUM) 36 | r.add(DESC_TYEP) 37 | r.addAll(int2Le(DESC_LEN).toList()) 38 | r.addAll(DESCRIPTOR.toList()) 39 | return r.toByteArray() 40 | } 41 | } -------------------------------------------------------------------------------- /Android/app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | apply plugin: 'kotlin-android' 4 | 5 | apply plugin: 'kotlin-android-extensions' 6 | 7 | android { 8 | compileSdkVersion 28 9 | defaultConfig { 10 | applicationId "com.mumumusuc.droidpro" 11 | minSdkVersion 28 12 | targetSdkVersion 28 13 | versionCode 1 14 | versionName "1.0" 15 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 16 | } 17 | buildTypes { 18 | release { 19 | minifyEnabled false 20 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' 21 | } 22 | } 23 | 24 | aaptOptions { 25 | noCompress 'bin' 26 | } 27 | } 28 | 29 | dependencies { 30 | compileOnly 'de.robv.android.xposed:api:82' 31 | implementation fileTree(dir: 'libs', include: ['*.jar']) 32 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" 33 | implementation 'com.android.support:appcompat-v7:28.0.0' 34 | implementation 'com.android.support.constraint:constraint-layout:1.1.3' 35 | implementation 'io.github.controlwear:virtualjoystick:1.10.1' 36 | implementation 'org.greenrobot:eventbus:3.1.1' 37 | implementation 'io.github.controlwear:virtualjoystick:1.10.1' 38 | 39 | testImplementation 'junit:junit:4.12' 40 | androidTestImplementation 'com.android.support.test:runner:1.0.2' 41 | androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' 42 | implementation project(path: ':LibJoycon-release') 43 | } 44 | -------------------------------------------------------------------------------- /Android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 19 | 20 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 34 | 37 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /Android/app/src/main/jni/include/jni_utils.h: -------------------------------------------------------------------------------- 1 | #ifndef DROIDPRO_UTILS_H 2 | #define DROIDPRO_UTILS_H 3 | 4 | #define DEBUG 1 5 | #define INPUT_TAG "[INP]" 6 | #define OUTPUT_TAG "[OUT]" 7 | #define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,TAG,__VA_ARGS__) 8 | #define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,TAG,__VA_ARGS__) 9 | 10 | #if DEBUG 11 | 12 | #include 13 | #include 14 | 15 | #define TMP_SIZE 128 16 | #define TAG "jc_jni" 17 | static char tmp[TMP_SIZE] = {0}; 18 | 19 | #define dump(tag, fmt, buf, size) \ 20 | do{ \ 21 | int len = 0; \ 22 | char *_tmp = tmp; \ 23 | memset(_tmp, 0, TMP_SIZE); \ 24 | if ((tag)) { \ 25 | len = sprintf(_tmp, "%s", (tag)); \ 26 | _tmp += len; \ 27 | } \ 28 | for (int _i = 0; _i < (size); _i++) { \ 29 | if(_i > 64 && _i < 320) \ 30 | continue; \ 31 | if(_i == 64) \ 32 | len = sprintf(_tmp,"... "); \ 33 | else \ 34 | len = sprintf(_tmp, (fmt), (buf)[_i]); \ 35 | _tmp += len; \ 36 | } \ 37 | LOGD("%s",tmp); \ 38 | }while(0) 39 | 40 | #define hexdump(tag, buf, size) dump(tag,"%02x ",buf,size) 41 | 42 | #else 43 | #define hexdump(tag,buf,size) {} 44 | #endif 45 | 46 | #endif //DROIDPRO_UTILS_H 47 | -------------------------------------------------------------------------------- /Android/app/src/main/java/com/mumumusuc/droidpro/fragment/Connection.kt: -------------------------------------------------------------------------------- 1 | package com.mumumusuc.droidpro.fragment 2 | 3 | import android.os.Bundle 4 | import android.support.v4.app.Fragment 5 | import android.view.LayoutInflater 6 | import android.view.MotionEvent 7 | import android.view.View 8 | import android.view.ViewGroup 9 | import com.mumumusuc.droidpro.R 10 | import com.mumumusuc.droidpro.eventbus.JcButtonEvent 11 | import com.mumumusuc.droidpro.eventbus.JcConnectEvent 12 | import com.mumumusuc.droidpro.eventbus.JcConnectStatus 13 | import com.mumumusuc.droidpro.eventbus.JcOutputEvent 14 | import com.mumumusuc.joycon.Joycon 15 | import org.greenrobot.eventbus.EventBus 16 | 17 | 18 | class Connection : Fragment() { 19 | override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View { 20 | val root = inflater.inflate(R.layout.connection, container, false) 21 | root.findViewById(R.id.device_label)?.setOnClickListener { 22 | EventBus.getDefault().post(JcConnectEvent(JcConnectStatus.REQUEST)) 23 | } 24 | 25 | root.findViewById(R.id.ns_logo)?.setOnTouchListener { view: View, motionEvent: MotionEvent -> 26 | when (motionEvent.action) { 27 | MotionEvent.ACTION_DOWN -> { 28 | EventBus.getDefault().post(JcButtonEvent(Joycon.NsButton.A, true)) 29 | EventBus.getDefault().post(JcOutputEvent(0x30, byteArrayOf())) 30 | return@setOnTouchListener true 31 | } 32 | MotionEvent.ACTION_UP -> { 33 | EventBus.getDefault().post(JcButtonEvent(Joycon.NsButton.A, false)) 34 | EventBus.getDefault().post(JcOutputEvent(0x30, byteArrayOf())) 35 | return@setOnTouchListener true 36 | } 37 | else -> return@setOnTouchListener false 38 | } 39 | } 40 | return root 41 | } 42 | } -------------------------------------------------------------------------------- /Android/app/src/main/res/drawable-v24/ic_launcher_foreground.xml: -------------------------------------------------------------------------------- 1 | 7 | 12 | 13 | 19 | 22 | 25 | 26 | 27 | 28 | 34 | 35 | -------------------------------------------------------------------------------- /Android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 11 | 18 | 19 | 22 | 23 | 33 | 34 | 38 | 39 | 42 | 43 | 48 | 49 | -------------------------------------------------------------------------------- /Android/app/src/main/jni/include/crc8.h: -------------------------------------------------------------------------------- 1 | #ifndef CRC8_H 2 | #define CRC8_H 3 | 4 | #define CRC8_POLYNOMIAL 0x07 5 | 6 | static inline unsigned char crc8_table_high_first(unsigned char value) { 7 | unsigned char i, crc; 8 | crc = value; 9 | for (i = 8; i > 0; --i) 10 | if (crc & 0x80) 11 | crc = (crc << 1) ^ CRC8_POLYNOMIAL; 12 | else 13 | crc = (crc << 1); 14 | return crc; 15 | } 16 | 17 | static const unsigned char _crc8_07_table[] = { 18 | 0x00, 0x07, 0x0e, 0x09, 0x1c, 0x1b, 0x12, 0x15, 0x38, 0x3f, 0x36, 0x31, 0x24, 0x23, 0x2a, 0x2d, 0x70, 0x77, 19 | 0x7e, 0x79, 0x6c, 0x6b, 0x62, 0x65, 0x48, 0x4f, 0x46, 0x41, 0x54, 0x53, 0x5a, 0x5d, 0xe0, 0xe7, 0xee, 0xe9, 20 | 0xfc, 0xfb, 0xf2, 0xf5, 0xd8, 0xdf, 0xd6, 0xd1, 0xc4, 0xc3, 0xca, 0xcd, 0x90, 0x97, 0x9e, 0x99, 0x8c, 0x8b, 21 | 0x82, 0x85, 0xa8, 0xaf, 0xa6, 0xa1, 0xb4, 0xb3, 0xba, 0xbd, 0xc7, 0xc0, 0xc9, 0xce, 0xdb, 0xdc, 0xd5, 0xd2, 22 | 0xff, 0xf8, 0xf1, 0xf6, 0xe3, 0xe4, 0xed, 0xea, 0xb7, 0xb0, 0xb9, 0xbe, 0xab, 0xac, 0xa5, 0xa2, 0x8f, 0x88, 23 | 0x81, 0x86, 0x93, 0x94, 0x9d, 0x9a, 0x27, 0x20, 0x29, 0x2e, 0x3b, 0x3c, 0x35, 0x32, 0x1f, 0x18, 0x11, 0x16, 24 | 0x03, 0x04, 0x0d, 0x0a, 0x57, 0x50, 0x59, 0x5e, 0x4b, 0x4c, 0x45, 0x42, 0x6f, 0x68, 0x61, 0x66, 0x73, 0x74, 25 | 0x7d, 0x7a, 0x89, 0x8e, 0x87, 0x80, 0x95, 0x92, 0x9b, 0x9c, 0xb1, 0xb6, 0xbf, 0xb8, 0xad, 0xaa, 0xa3, 0xa4, 26 | 0xf9, 0xfe, 0xf7, 0xf0, 0xe5, 0xe2, 0xeb, 0xec, 0xc1, 0xc6, 0xcf, 0xc8, 0xdd, 0xda, 0xd3, 0xd4, 0x69, 0x6e, 27 | 0x67, 0x60, 0x75, 0x72, 0x7b, 0x7c, 0x51, 0x56, 0x5f, 0x58, 0x4d, 0x4a, 0x43, 0x44, 0x19, 0x1e, 0x17, 0x10, 28 | 0x05, 0x02, 0x0b, 0x0c, 0x21, 0x26, 0x2f, 0x28, 0x3d, 0x3a, 0x33, 0x34, 0x4e, 0x49, 0x40, 0x47, 0x52, 0x55, 29 | 0x5c, 0x5b, 0x76, 0x71, 0x78, 0x7f, 0x6a, 0x6d, 0x64, 0x63, 0x3e, 0x39, 0x30, 0x37, 0x22, 0x25, 0x2c, 0x2b, 30 | 0x06, 0x01, 0x08, 0x0f, 0x1a, 0x1d, 0x14, 0x13, 0xae, 0xa9, 0xa0, 0xa7, 0xb2, 0xb5, 0xbc, 0xbb, 0x96, 0x91, 31 | 0x98, 0x9f, 0x8a, 0x8d, 0x84, 0x83, 0xde, 0xd9, 0xd0, 0xd7, 0xc2, 0xc5, 0xcc, 0xcb, 0xe6, 0xe1, 0xe8, 0xef, 32 | 0xfa, 0xfd, 0xf4, 0xf3}; 33 | 34 | 35 | static inline void crc8_create_table(unsigned char *table) { 36 | unsigned short i; 37 | for (i = 0; i <= 0xFF; i++) 38 | table[i] = crc8_table_high_first(i); 39 | } 40 | 41 | static inline unsigned char crc8(const unsigned char *ptr, int len) { 42 | unsigned char crc = 0x00; 43 | while (len--) 44 | crc = _crc8_07_table[crc ^ *ptr++]; 45 | return (crc); 46 | } 47 | 48 | #endif //CRC8_H 49 | -------------------------------------------------------------------------------- /Android/gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | set DIRNAME=%~dp0 12 | if "%DIRNAME%" == "" set DIRNAME=. 13 | set APP_BASE_NAME=%~n0 14 | set APP_HOME=%DIRNAME% 15 | 16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 17 | set DEFAULT_JVM_OPTS= 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windows variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | 53 | :win9xME_args 54 | @rem Slurp the command line arguments. 55 | set CMD_LINE_ARGS= 56 | set _SKIP=2 57 | 58 | :win9xME_args_slurp 59 | if "x%~1" == "x" goto execute 60 | 61 | set CMD_LINE_ARGS=%* 62 | 63 | :execute 64 | @rem Setup the command line 65 | 66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 67 | 68 | @rem Execute Gradle 69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 70 | 71 | :end 72 | @rem End local scope for the variables with windows NT shell 73 | if "%ERRORLEVEL%"=="0" goto mainEnd 74 | 75 | :fail 76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 77 | rem the _cmd.exe /c_ return code! 78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 79 | exit /b 1 80 | 81 | :mainEnd 82 | if "%OS%"=="Windows_NT" endlocal 83 | 84 | :omega 85 | -------------------------------------------------------------------------------- /Android/app/src/main/jni/com_mumumusuc_joycon_Joycon.h: -------------------------------------------------------------------------------- 1 | /* DO NOT EDIT THIS FILE - it is machine generated */ 2 | #include 3 | /* Header for class com_mumumusuc_joycon_Joycon */ 4 | 5 | #ifndef _Included_com_mumumusuc_joycon_Joycon 6 | #define _Included_com_mumumusuc_joycon_Joycon 7 | #ifdef __cplusplus 8 | extern "C" { 9 | #endif 10 | /* 11 | * Class: com_mumumusuc_joycon_Joycon 12 | * Method: nativeInit 13 | * Signature: (Ljava/nio/ByteBuffer;?;?)I 14 | */ 15 | JNIEXPORT jint JNICALL Java_com_mumumusuc_joycon_Joycon_nativeInit 16 | (JNIEnv *, jobject, jobject, jobject, jstring); 17 | 18 | /* 19 | * Class: com_mumumusuc_joycon_Joycon 20 | * Method: nativeFree 21 | * Signature: ()I 22 | */ 23 | JNIEXPORT jint JNICALL Java_com_mumumusuc_joycon_Joycon_nativeFree 24 | (JNIEnv *, jobject); 25 | 26 | /* 27 | * Class: com_mumumusuc_joycon_Joycon 28 | * Method: nativeReplayOutputReport 29 | * Signature: ()I 30 | */ 31 | JNIEXPORT jint JNICALL Java_com_mumumusuc_joycon_Joycon_nativeReplayOutputReport 32 | (JNIEnv *, jobject); 33 | 34 | /* 35 | * Class: com_mumumusuc_joycon_Joycon 36 | * Method: nativeMakeupInputReport 37 | * Signature: ()I 38 | */ 39 | JNIEXPORT jint JNICALL Java_com_mumumusuc_joycon_Joycon_nativeMakeupInputReport 40 | (JNIEnv *, jobject); 41 | 42 | /* 43 | * Class: com_mumumusuc_joycon_Joycon 44 | * Method: nativeUpdateButtons 45 | * Signature: ([Z)V 46 | */ 47 | JNIEXPORT void JNICALL Java_com_mumumusuc_joycon_Joycon_nativeUpdateButtons 48 | (JNIEnv *, jobject, jbooleanArray); 49 | 50 | /* 51 | * Class: com_mumumusuc_joycon_Joycon 52 | * Method: nativeUpdateSticks 53 | * Signature: ([C)V 54 | */ 55 | JNIEXPORT void JNICALL Java_com_mumumusuc_joycon_Joycon_nativeUpdateSticks 56 | (JNIEnv *, jobject, jcharArray); 57 | 58 | /* 59 | * Class: com_mumumusuc_joycon_Joycon 60 | * Method: nativeUpdateIMU 61 | * Signature: ([S[S)V 62 | */ 63 | JNIEXPORT void JNICALL Java_com_mumumusuc_joycon_Joycon_nativeUpdateIMU 64 | (JNIEnv *, jobject, jshortArray, jshortArray); 65 | 66 | /* 67 | * Class: com_mumumusuc_joycon_Joycon 68 | * Method: nativeUpdateNFC 69 | * Signature: ([B)V 70 | */ 71 | JNIEXPORT void JNICALL Java_com_mumumusuc_joycon_Joycon_nativeUpdateNFC 72 | (JNIEnv *, jobject, jbyteArray); 73 | 74 | /* 75 | * Class: com_mumumusuc_joycon_Joycon 76 | * Method: nativeUpdateIR 77 | * Signature: ([B)V 78 | */ 79 | JNIEXPORT void JNICALL Java_com_mumumusuc_joycon_Joycon_nativeUpdateIR 80 | (JNIEnv *, jobject, jbyteArray); 81 | 82 | #ifdef __cplusplus 83 | } 84 | #endif 85 | #endif 86 | -------------------------------------------------------------------------------- /Android/app/src/main/res/layout/connection.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 13 |