Skip to content

Commit

Permalink
i have no idea what i'm doing
Browse files Browse the repository at this point in the history
  • Loading branch information
jakedowns committed Jan 10, 2024
1 parent 370c842 commit 13dc51e
Show file tree
Hide file tree
Showing 5 changed files with 197 additions and 13 deletions.
2 changes: 2 additions & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# Enable modules to include each other's files
include_directories(.)

set(CMAKE_LINKER "E:/Program Files/Unity/Hub/Editor/2021.3.16f1/Editor/Data/PlaybackEngines/AndroidPlayer/NDK/toolchains/x86-4.9/prebuilt/windows-x86_64/i686-linux-android/bin/ld.gold.exe")

# CMake seems to only define _DEBUG on Windows
set_property(DIRECTORY APPEND PROPERTY
COMPILE_DEFINITIONS $<$<CONFIG:Debug>:_DEBUG> $<$<NOT:$<CONFIG:Debug>>:NDEBUG>)
Expand Down
88 changes: 87 additions & 1 deletion src/android/app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.

import java.util.Properties
import android.databinding.tool.ext.capitalizeUS
import com.android.build.api.dsl.Packaging
import com.android.build.gradle.internal.dsl.PackagingOptions
import de.undercouch.gradle.tasks.download.Download

plugins {
Expand All @@ -24,6 +27,67 @@ val abiFilter = listOf("arm64-v8a", "x86_64")

val downloadedJniLibsPath = "${buildDir}/downloadedJniLibs"

// Leia
val shouldAddDebugInfo: () -> Boolean = { true }
val useInAppFaceTracking: () -> Boolean = { false }

val localPropertiesFile = File(rootProject.projectDir, "local.properties")
val properties = Properties()
check(localPropertiesFile.exists())
localPropertiesFile.reader(charset = Charsets.UTF_8).use { reader ->
properties.load(reader)
}
extra.set("cnsdkPath", properties.getProperty("cnsdk.dir").also {
check(it != null) { "cnsdk.dir not set in local.properties" }
if (!File(it).isAbsolute) {
File(rootProject.projectDir, it).absolutePath
} else {
File(it).absolutePath
}
}.apply {
println("CNSDK directory: $this")
})
val cnsdkPath: String by extra(properties.getProperty("cnsdk.dir").also {
check(it != null) { "cnsdk.dir not set in local.properties" }
if (!File(it).isAbsolute) {
File(rootProject.projectDir, it).absolutePath
} else {
File(it).absolutePath
}
})
println("CNSDK directory: $cnsdkPath")
val getCNSDKVersionName: () -> String = {
file(File(cnsdkPath, "VERSION.txt")).readText()
}
fun getCNSDKLibName(forceInApp: Boolean): String {
return if (useInAppFaceTracking() || forceInApp) {
"sdk-faceTrackingInApp-${getCNSDKVersionName()}.aar"
} else {
"sdk-faceTrackingService-${getCNSDKVersionName()}.aar"
}
}
tasks.register("copyNativeLibs") {
doLast {
copy {
from(zipTree("${cnsdkPath}/android/${getCNSDKLibName(false)}"))
include("jni/*/*.so")
into("${cnsdkPath}/lib")
}
}
}
fun DependencyHandler.addDependency(depFile: String) {
check(file(depFile).exists())
add("implementation", files(depFile))
}
fun DependencyHandler.addSdkDependency(forceInApp: Boolean) {
addDependency("${cnsdkPath}/android/${getCNSDKLibName(forceInApp)}")
if (useInAppFaceTracking() || forceInApp) {
addDependency("${cnsdkPath}/android/third_party/snpe-release.aar")
}
}



@Suppress("UnstableApiUsage")
android {
namespace = "org.citra.citra_emu"
Expand All @@ -40,9 +104,26 @@ android {
jvmTarget = "17"
}

if (shouldAddDebugInfo()) {
packaging {
jniLibs.keepDebugSymbols.add("**/*.so")

jniLibs {
keepDebugSymbols.add("**/*.so")
}
}

// ndk {
// debugSymbolLevel.set("FULL")
// }
}

packaging {
// This is necessary for libadrenotools custom driver loading
jniLibs.useLegacyPackaging = true

resources.pickFirsts.add("**/libleiaSDK.so")
resources.pickFirsts.add("**/lib*blink.so")
}

buildFeatures {
Expand Down Expand Up @@ -73,7 +154,8 @@ android {
arguments(
"-DENABLE_QT=0", // Don't use QT
"-DENABLE_SDL2=0", // Don't use SDL
"-DANDROID_ARM_NEON=true" // cryptopp requires Neon to work
"-DANDROID_ARM_NEON=true", // cryptopp requires Neon to work
"-DCMAKE_OBJECT_PATH_MAX=1024"
)
}
}
Expand All @@ -94,6 +176,8 @@ android {
}
}



// Define build types, which are orthogonal to product flavors.
buildTypes {
// Signed by release key, allowing for upload to Play Store.
Expand Down Expand Up @@ -186,8 +270,10 @@ dependencies {
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.5.0")
implementation("androidx.preference:preference-ktx:1.2.1")
implementation("io.coil-kt:coil:2.2.2")
addSdkDependency(false)
}


// Download Vulkan Validation Layers from the KhronosGroup GitHub.
val downloadVulkanValidationLayers = tasks.register<Download>("downloadVulkanValidationLayers") {
src("https://github.com/KhronosGroup/Vulkan-ValidationLayers/releases/download/sdk-1.3.261.1/android-binaries-sdk-1.3.261.1-android.zip")
Expand Down
5 changes: 5 additions & 0 deletions src/android/app/proguard-rules.pro
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,8 @@
-dontwarn java.beans.Introspector
-dontwarn java.beans.VetoableChangeListener
-dontwarn java.beans.VetoableChangeSupport

-keep class com.leia.sdk.** { *; }
-keep class com.leia.core.** { *; }
-keep class com.leia.internal.** { *; }
-keep class com.leia.headtracking.** { *; }
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,80 @@ import org.citra.citra_emu.utils.EmulationLifecycleUtil
import org.citra.citra_emu.utils.ThemeUtil
import org.citra.citra_emu.viewmodel.EmulationViewModel

import com.leia.core.LogLevel
import com.leia.sdk.LeiaSDK
private class LWERenderer(val activity: Activity) : GLSurfaceView.Renderer, AutoCloseable {
private val TAG = LWERenderer::class.java.simpleName

var lweCore: LWE_Core? = null

private var width = 0
private var height = 0
private var isSizeDirty = false

private var enableBacklight = true

fun onPause() {
lweCore?.onPause()
}

fun onResume() {
lweCore?.onResume()
}

fun setBacklight(enable: Boolean) {
if (lweCore != null) {
lweCore?.setBacklight(enable)
} else {
enableBacklight = enable
}
}

override fun close() {
lweCore?.close()
lweCore = null
}

override fun onSurfaceCreated(p0: GL10?, p1: EGLConfig?) {
Log.d(TAG, "onSurfaceCreated")
}

override fun onSurfaceChanged(p0: GL10?, width: Int, height: Int) {
Log.d(TAG, "onSurfaceChanged")
this.width = width
this.height = height
this.isSizeDirty = true
}

override fun onDrawFrame(p0: GL10?) {
Log.d(TAG, "onDrawFrame")
if (lweCore == null) { tryInit() }

val lweCore = lweCore
if (lweCore != null) {
lweCore.tick(1.0 / 60.0)

if (lweCore.isInitialized) {
if (isSizeDirty) {
isSizeDirty = false
lweCore.onWindowSizeChanged(width, height)
}
lweCore.render()
}
}
}

private fun tryInit() {
if (EGL14.eglGetCurrentContext() == EGL14.EGL_NO_CONTEXT) {
return
}

lweCore = LWE_Core(activity)
lweCore?.setBacklight(enableBacklight)
}
}

class EmulationActivity : AppCompatActivity(), LeiaSDK.Delegate {
private var leiaSDK: LeiaSDK? = null
private lateinit var lweRenderer: LWERenderer
private lateinit var surfaceView: GLSurfaceView

private val preferences: SharedPreferences
get() = PreferenceManager.getDefaultSharedPreferences(CitraApplication.appContext)
Expand All @@ -68,17 +137,21 @@ class EmulationActivity : AppCompatActivity(), LeiaSDK.Delegate {

super.onCreate(savedInstanceState)

// Initialize the Leia SDK
// Initialize the Leia Renderer
try {
val initArgs = LeiaSDK.InitArgs().apply {
delegate = this@EmulationActivity
platform.activity = this@EmulationActivity
platform.logLevel = LogLevel.Trace
platform.context = applicationContext
faceTrackingServerLogLevel = LogLevel.Trace
enableFaceTracking = true
lweRenderer = LWERenderer(this)

surfaceView = findViewById(R.id.fragment_container)

surfaceView.setOnTouchListener OnTouchListener@{ view, motionEvent -> Boolean
surfaceView.queueEvent { lweRenderer.lweCore?.processGuiEvent(motionEvent) }
return@OnTouchListener true
}
leiaSDK = LeiaSDK.createSDK(initArgs)

surfaceView.setEGLContextClientVersion(3)
surfaceView.setEGLConfigChooser(8, 8, 8, 8, 16, 0)
surfaceView.setPreserveEGLContextOnPause(true)
surfaceView.setRenderer(lweRenderer)
} catch (e: Exception) {
Log.e("[EmulationActivity]", "Error: ${e.toString()}")
e.printStackTrace()
Expand Down Expand Up @@ -111,11 +184,13 @@ class EmulationActivity : AppCompatActivity(), LeiaSDK.Delegate {
// onWindowFocusChanged to prevent the unwanted status bar state.
override fun onResume() {
super.onResume()
surfaceView.queueEvent { lweRenderer.onResume() }
enableFullscreenImmersive()
}

override fun onWindowFocusChanged(hasFocus: Boolean) {
super.onWindowFocusChanged(hasFocus)
surfaceView.queueEvent { lweRenderer.setBacklight(hasFocus) }
enableFullscreenImmersive()
}

Expand All @@ -128,8 +203,19 @@ class EmulationActivity : AppCompatActivity(), LeiaSDK.Delegate {
EmulationLifecycleUtil.clear()
stopForegroundService(this)
super.onDestroy()
lweRenderer.close()
}

override fun onStop () {
super.onStop();
surfaceView.queueEvent { lweRenderer.onPause() }
}

override fun onPause() {
surfaceView.queueEvent { lweRenderer.onPause() }
super.onPause()
}

override fun onRequestPermissionsResult(
requestCode: Int,
permissions: Array<String>,
Expand Down
5 changes: 5 additions & 0 deletions src/android/app/src/main/jni/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
list(APPEND CMAKE_PREFIX_PATH "K:/Code/citra/src/android/cnsdk-android-0.7.28")
find_package(CNSDK CONFIG REQUIRED)
target_link_libraries(citra-android CNSDK::leiaSDK)

add_library(citra-android SHARED
android_common/android_common.cpp
android_common/android_common.h
Expand Down Expand Up @@ -42,3 +46,4 @@ if ("arm64" IN_LIST ARCHITECTURE)
endif()

set(CPACK_PACKAGE_EXECUTABLES ${CPACK_PACKAGE_EXECUTABLES} citra-android)

0 comments on commit 13dc51e

Please sign in to comment.