Merge branch 'libryujinx_bionic' into 'libryujinx_bionic'

Small Kotlin changes

* Use Delegation for KenjinxNative jnaInstance

* rework KenjiNative.updateUiHandler + remove needless companion object

* Small syntactic niceties, general cleanups & code style fixes

See merge request kenji-nx/ryujinx!1
This commit is contained in:
KeatonTheBot
2025-05-23 20:26:17 -05:00
17 changed files with 186 additions and 220 deletions
@@ -36,9 +36,9 @@ typealias GamePadConfig = RadialGamePadConfig
class GameController(var activity: Activity) { class GameController(var activity: Activity) {
companion object { companion object {
private fun Create(context: Context, controller: GameController): View { private fun init(context: Context, controller: GameController): View {
val inflator = LayoutInflater.from(context) val inflater = LayoutInflater.from(context)
val view = inflator.inflate(R.layout.game_layout, null) val view = inflater.inflate(R.layout.game_layout, null)
view.findViewById<FrameLayout>(R.id.leftcontainer)!!.addView(controller.leftGamePad) view.findViewById<FrameLayout>(R.id.leftcontainer)!!.addView(controller.leftGamePad)
view.findViewById<FrameLayout>(R.id.rightcontainer)!!.addView(controller.rightGamePad) view.findViewById<FrameLayout>(R.id.rightcontainer)!!.addView(controller.rightGamePad)
@@ -50,7 +50,7 @@ class GameController(var activity: Activity) {
AndroidView( AndroidView(
modifier = Modifier.fillMaxSize(), factory = { context -> modifier = Modifier.fillMaxSize(), factory = { context ->
val controller = GameController(viewModel.activity) val controller = GameController(viewModel.activity)
val c = Create(context, controller) val c = init(context, controller)
viewModel.activity.lifecycleScope.apply { viewModel.activity.lifecycleScope.apply {
viewModel.activity.lifecycleScope.launch { viewModel.activity.lifecycleScope.launch {
val events = merge( val events = merge(
@@ -108,12 +108,12 @@ class GameController(var activity: Activity) {
fun connect() { fun connect() {
if (controllerId == -1) if (controllerId == -1)
controllerId = KenjinxNative.jnaInstance.inputConnectGamepad(0) controllerId = KenjinxNative.inputConnectGamepad(0)
} }
private fun handleEvent(ev: Event) { private fun handleEvent(ev: Event) {
if (controllerId == -1) if (controllerId == -1)
controllerId = KenjinxNative.jnaInstance.inputConnectGamepad(0) controllerId = KenjinxNative.inputConnectGamepad(0)
controllerId.apply { controllerId.apply {
when (ev) { when (ev) {
@@ -121,11 +121,11 @@ class GameController(var activity: Activity) {
val action = ev.action val action = ev.action
when (action) { when (action) {
KeyEvent.ACTION_UP -> { KeyEvent.ACTION_UP -> {
KenjinxNative.jnaInstance.inputSetButtonReleased(ev.id, this) KenjinxNative.inputSetButtonReleased(ev.id, this)
} }
KeyEvent.ACTION_DOWN -> { KeyEvent.ACTION_DOWN -> {
KenjinxNative.jnaInstance.inputSetButtonPressed(ev.id, this) KenjinxNative.inputSetButtonPressed(ev.id, this)
} }
} }
} }
@@ -136,57 +136,57 @@ class GameController(var activity: Activity) {
when (direction) { when (direction) {
GamePadButtonInputId.DpadUp.ordinal -> { GamePadButtonInputId.DpadUp.ordinal -> {
if (ev.xAxis > 0) { if (ev.xAxis > 0) {
KenjinxNative.jnaInstance.inputSetButtonPressed( KenjinxNative.inputSetButtonPressed(
GamePadButtonInputId.DpadRight.ordinal, GamePadButtonInputId.DpadRight.ordinal,
this this
) )
KenjinxNative.jnaInstance.inputSetButtonReleased( KenjinxNative.inputSetButtonReleased(
GamePadButtonInputId.DpadLeft.ordinal, GamePadButtonInputId.DpadLeft.ordinal,
this this
) )
} else if (ev.xAxis < 0) { } else if (ev.xAxis < 0) {
KenjinxNative.jnaInstance.inputSetButtonPressed( KenjinxNative.inputSetButtonPressed(
GamePadButtonInputId.DpadLeft.ordinal, GamePadButtonInputId.DpadLeft.ordinal,
this this
) )
KenjinxNative.jnaInstance.inputSetButtonReleased( KenjinxNative.inputSetButtonReleased(
GamePadButtonInputId.DpadRight.ordinal, GamePadButtonInputId.DpadRight.ordinal,
this this
) )
} else { } else {
KenjinxNative.jnaInstance.inputSetButtonReleased( KenjinxNative.inputSetButtonReleased(
GamePadButtonInputId.DpadLeft.ordinal, GamePadButtonInputId.DpadLeft.ordinal,
this this
) )
KenjinxNative.jnaInstance.inputSetButtonReleased( KenjinxNative.inputSetButtonReleased(
GamePadButtonInputId.DpadRight.ordinal, GamePadButtonInputId.DpadRight.ordinal,
this this
) )
} }
if (ev.yAxis < 0) { if (ev.yAxis < 0) {
KenjinxNative.jnaInstance.inputSetButtonPressed( KenjinxNative.inputSetButtonPressed(
GamePadButtonInputId.DpadUp.ordinal, GamePadButtonInputId.DpadUp.ordinal,
this this
) )
KenjinxNative.jnaInstance.inputSetButtonReleased( KenjinxNative.inputSetButtonReleased(
GamePadButtonInputId.DpadDown.ordinal, GamePadButtonInputId.DpadDown.ordinal,
this this
) )
} else if (ev.yAxis > 0) { } else if (ev.yAxis > 0) {
KenjinxNative.jnaInstance.inputSetButtonPressed( KenjinxNative.inputSetButtonPressed(
GamePadButtonInputId.DpadDown.ordinal, GamePadButtonInputId.DpadDown.ordinal,
this this
) )
KenjinxNative.jnaInstance.inputSetButtonReleased( KenjinxNative.inputSetButtonReleased(
GamePadButtonInputId.DpadUp.ordinal, GamePadButtonInputId.DpadUp.ordinal,
this this
) )
} else { } else {
KenjinxNative.jnaInstance.inputSetButtonReleased( KenjinxNative.inputSetButtonReleased(
GamePadButtonInputId.DpadDown.ordinal, GamePadButtonInputId.DpadDown.ordinal,
this this
) )
KenjinxNative.jnaInstance.inputSetButtonReleased( KenjinxNative.inputSetButtonReleased(
GamePadButtonInputId.DpadUp.ordinal, GamePadButtonInputId.DpadUp.ordinal,
this this
) )
@@ -197,7 +197,7 @@ class GameController(var activity: Activity) {
val setting = QuickSettings(activity) val setting = QuickSettings(activity)
val x = MathUtils.clamp(ev.xAxis * setting.controllerStickSensitivity, -1f, 1f) val x = MathUtils.clamp(ev.xAxis * setting.controllerStickSensitivity, -1f, 1f)
val y = MathUtils.clamp(ev.yAxis * setting.controllerStickSensitivity, -1f, 1f) val y = MathUtils.clamp(ev.yAxis * setting.controllerStickSensitivity, -1f, 1f)
KenjinxNative.jnaInstance.inputSetStickAxis( KenjinxNative.inputSetStickAxis(
1, 1,
x, x,
-y, -y,
@@ -209,7 +209,7 @@ class GameController(var activity: Activity) {
val setting = QuickSettings(activity) val setting = QuickSettings(activity)
val x = MathUtils.clamp(ev.xAxis * setting.controllerStickSensitivity, -1f, 1f) val x = MathUtils.clamp(ev.xAxis * setting.controllerStickSensitivity, -1f, 1f)
val y = MathUtils.clamp(ev.yAxis * setting.controllerStickSensitivity, -1f, 1f) val y = MathUtils.clamp(ev.yAxis * setting.controllerStickSensitivity, -1f, 1f)
KenjinxNative.jnaInstance.inputSetStickAxis( KenjinxNative.inputSetStickAxis(
2, 2,
x, x,
-y, -y,
@@ -12,7 +12,6 @@ import kotlin.concurrent.thread
@SuppressLint("ViewConstructor") @SuppressLint("ViewConstructor")
class GameHost(context: Context?, private val mainViewModel: MainViewModel) : SurfaceView(context), class GameHost(context: Context?, private val mainViewModel: MainViewModel) : SurfaceView(context),
SurfaceHolder.Callback { SurfaceHolder.Callback {
private var _currentWindow: Long = -1
private var isProgressHidden: Boolean = false private var isProgressHidden: Boolean = false
private var progress: MutableState<String>? = null private var progress: MutableState<String>? = null
private var progressValue: MutableState<Float>? = null private var progressValue: MutableState<Float>? = null
@@ -28,12 +27,10 @@ class GameHost(context: Context?, private val mainViewModel: MainViewModel) : Su
private var _isStarted: Boolean = false private var _isStarted: Boolean = false
private val _nativeWindow: NativeWindow private val _nativeWindow: NativeWindow
val currentSurface:Long var currentSurface: Long = -1
get() { private set
return _currentWindow
}
val currentWindowhandle: Long val currentWindowHandle: Long
get() { get() {
return _nativeWindow.nativePointer return _nativeWindow.nativePointer
} }
@@ -67,7 +64,7 @@ class GameHost(context: Context?, private val mainViewModel: MainViewModel) : Su
return return
if (_width != width || _height != height) { if (_width != width || _height != height) {
_currentWindow = _nativeWindow.requeryWindowHandle() currentSurface = _nativeWindow.requeryWindowHandle()
_nativeWindow.swapInterval = 0 _nativeWindow.swapInterval = 0
} }
@@ -77,13 +74,13 @@ class GameHost(context: Context?, private val mainViewModel: MainViewModel) : Su
start(holder) start(holder)
KenjinxNative.jnaInstance.graphicsRendererSetSize( KenjinxNative.graphicsRendererSetSize(
width, width,
height height
) )
if (_isStarted) { if (_isStarted) {
KenjinxNative.jnaInstance.inputSetClientSize(width, height) KenjinxNative.inputSetClientSize(width, height)
} }
} }
@@ -96,7 +93,7 @@ class GameHost(context: Context?, private val mainViewModel: MainViewModel) : Su
_isInit = false _isInit = false
_isStarted = false _isStarted = false
KenjinxNative.jnaInstance.uiHandlerSetResponse(false, "") KenjinxNative.uiHandlerSetResponse(false, "")
_updateThread?.join() _updateThread?.join()
_renderingThreadWatcher?.join() _renderingThreadWatcher?.join()
@@ -110,12 +107,12 @@ class GameHost(context: Context?, private val mainViewModel: MainViewModel) : Su
game = if (mainViewModel.isMiiEditorLaunched) null else mainViewModel.gameModel game = if (mainViewModel.isMiiEditorLaunched) null else mainViewModel.gameModel
KenjinxNative.jnaInstance.inputInitialize(width, height) KenjinxNative.inputInitialize(width, height)
val id = mainViewModel.physicalControllerManager?.connect() val id = mainViewModel.physicalControllerManager?.connect()
mainViewModel.motionSensorManager?.setControllerId(id ?: -1) mainViewModel.motionSensorManager?.setControllerId(id ?: -1)
KenjinxNative.jnaInstance.graphicsRendererSetSize( KenjinxNative.graphicsRendererSetSize(
surfaceHolder.surfaceFrame.width(), surfaceHolder.surfaceFrame.width(),
surfaceHolder.surfaceFrame.height() surfaceHolder.surfaceFrame.height()
) )
@@ -130,7 +127,7 @@ class GameHost(context: Context?, private val mainViewModel: MainViewModel) : Su
var c = 0 var c = 0
val helper = NativeHelpers.instance val helper = NativeHelpers.instance
while (_isStarted) { while (_isStarted) {
KenjinxNative.jnaInstance.inputUpdate() KenjinxNative.inputUpdate()
Thread.sleep(1) Thread.sleep(1)
c++ c++
if (c >= 1000) { if (c >= 1000) {
@@ -141,9 +138,9 @@ class GameHost(context: Context?, private val mainViewModel: MainViewModel) : Su
} }
c = 0 c = 0
mainViewModel.updateStats( mainViewModel.updateStats(
KenjinxNative.jnaInstance.deviceGetGameFifo(), KenjinxNative.deviceGetGameFifo(),
KenjinxNative.jnaInstance.deviceGetGameFrameRate(), KenjinxNative.deviceGetGameFrameRate(),
KenjinxNative.jnaInstance.deviceGetGameFrameTime() KenjinxNative.deviceGetGameFrameTime()
) )
} }
} }
@@ -151,7 +148,7 @@ class GameHost(context: Context?, private val mainViewModel: MainViewModel) : Su
} }
private fun runGame() { private fun runGame() {
KenjinxNative.jnaInstance.graphicsRendererRunLoop() KenjinxNative.graphicsRendererRunLoop()
game?.close() game?.close()
} }
@@ -16,6 +16,7 @@ import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import java.io.File import java.io.File
import androidx.core.net.toUri
class Helpers { class Helpers {
companion object { companion object {
@@ -31,11 +32,10 @@ class Helpers {
if ("primary".equals(type, ignoreCase = true)) { if ("primary".equals(type, ignoreCase = true)) {
return Environment.getExternalStorageDirectory().toString() + "/" + split[1] return Environment.getExternalStorageDirectory().toString() + "/" + split[1]
} }
} else if (isDownloadsDocument(uri)) { } else if (isDownloadsDocument(uri)) {
val id = DocumentsContract.getDocumentId(uri) val id = DocumentsContract.getDocumentId(uri)
val contentUri = ContentUris.withAppendedId( val contentUri = ContentUris.withAppendedId(
Uri.parse("content://downloads/public_downloads"), "content://downloads/public_downloads".toUri(),
java.lang.Long.valueOf(id) java.lang.Long.valueOf(id)
) )
return getDataColumn(context, contentUri, null, null) return getDataColumn(context, contentUri, null, null)
@@ -87,77 +87,53 @@ interface KenjinxNativeJna : Library {
fun loggingEnabledGraphicsLog(enabled: Boolean) fun loggingEnabledGraphicsLog(enabled: Boolean)
} }
class KenjinxNative { val jnaInstance: KenjinxNativeJna = Native.load(
"kenjinx",
KenjinxNativeJna::class.java,
Collections.singletonMap(Library.OPTION_ALLOW_OBJECTS, true)
)
companion object { object KenjinxNative : KenjinxNativeJna by jnaInstance {
val jnaInstance: KenjinxNativeJna = Native.load(
"kenjinx", fun loggingSetEnabled(logLevel: LogLevel, enabled: Boolean) = loggingSetEnabled(logLevel.ordinal, enabled)
KenjinxNativeJna::class.java,
Collections.singletonMap(Library.OPTION_ALLOW_OBJECTS, true) @JvmStatic
fun frameEnded() = MainActivity.frameEnded()
@JvmStatic
fun getSurfacePtr(): Long = MainActivity.mainViewModel?.gameHost?.currentSurface ?: -1
@JvmStatic
fun getWindowHandle(): Long =
MainActivity.mainViewModel?.gameHost?.currentWindowHandle ?: -1
@JvmStatic
fun updateProgress(infoPtr: Long, progress: Float) =
MainActivity.mainViewModel?.gameHost?.setProgress(
NativeHelpers.instance.getStringJava(infoPtr),
progress
) )
@JvmStatic @JvmStatic
fun test() fun updateUiHandler(
{ newTitlePointer: Long,
val i = 0 newMessagePointer: Long,
} newWatermarkPointer: Long,
newType: Int,
@JvmStatic min: Int,
fun frameEnded() max: Int,
{ nMode: Int,
MainActivity.frameEnded() newSubtitlePointer: Long,
} newInitialTextPointer: Long
) = MainActivity.mainViewModel?.activity?.uiHandler?.update(
@JvmStatic newTitle = NativeHelpers.instance.getStringJava(newTitlePointer),
fun getSurfacePtr() : Long newMessage = NativeHelpers.instance.getStringJava(newMessagePointer),
{ newWatermark = NativeHelpers.instance.getStringJava(newWatermarkPointer),
return MainActivity.mainViewModel?.gameHost?.currentSurface ?: -1 newType,
} min,
max,
@JvmStatic newMode = KeyboardMode.entries[nMode],
fun getWindowHandle() : Long newSubtitle = NativeHelpers.instance.getStringJava(newSubtitlePointer),
{ NativeHelpers.instance.getStringJava(newInitialTextPointer)
return MainActivity.mainViewModel?.gameHost?.currentWindowhandle ?: -1 )
}
@JvmStatic
fun updateProgress(infoPtr : Long, progress: Float)
{
val info = NativeHelpers.instance.getStringJava(infoPtr);
MainActivity.mainViewModel?.gameHost?.setProgress(info, progress)
}
@JvmStatic
fun updateUiHandler(
newTitlePointer: Long,
newMessagePointer: Long,
newWatermarkPointer: Long,
newType: Int,
min: Int,
max: Int,
nMode: Int,
newSubtitlePointer: Long,
newInitialTextPointer: Long
)
{
var uiHandler = MainActivity.mainViewModel?.activity?.uiHandler
uiHandler?.apply {
val newTitle = NativeHelpers.instance.getStringJava(newTitlePointer)
val newMessage = NativeHelpers.instance.getStringJava(newMessagePointer)
val newWatermark = NativeHelpers.instance.getStringJava(newWatermarkPointer)
val newSubtitle = NativeHelpers.instance.getStringJava(newSubtitlePointer)
val newInitialText = NativeHelpers.instance.getStringJava(newInitialTextPointer)
val newMode = KeyboardMode.entries[nMode]
update(newTitle,
newMessage,
newWatermark,
newType,
min,
max,
newMode,
newSubtitle,
newInitialText);
}
}
}
} }
@@ -58,6 +58,6 @@ class Logging(private var viewModel: MainViewModel) {
} }
} }
internal enum class LogLevel { enum class LogLevel {
Debug, Stub, Info, Warning, Error, Guest, AccessLog, Notice, Trace Debug, Stub, Info, Warning, Error, Guest, AccessLog, Notice, Trace
} }
@@ -25,6 +25,7 @@ import org.kenjinx.android.viewmodels.MainViewModel
import org.kenjinx.android.viewmodels.QuickSettings import org.kenjinx.android.viewmodels.QuickSettings
import org.kenjinx.android.viewmodels.GameModel import org.kenjinx.android.viewmodels.GameModel
import org.kenjinx.android.views.MainView import org.kenjinx.android.views.MainView
import androidx.core.net.toUri
class MainActivity : BaseActivity() { class MainActivity : BaseActivity() {
private var physicalControllerManager: PhysicalControllerManager = private var physicalControllerManager: PhysicalControllerManager =
@@ -47,7 +48,6 @@ class MainActivity : BaseActivity() {
var mainViewModel: MainViewModel? = null var mainViewModel: MainViewModel? = null
var AppPath: String = "" var AppPath: String = ""
var StorageHelper: SimpleStorageHelper? = null var StorageHelper: SimpleStorageHelper? = null
val performanceMonitor = PerformanceMonitor()
@JvmStatic @JvmStatic
fun frameEnded() { fun frameEnded() {
@@ -76,45 +76,43 @@ class MainActivity : BaseActivity() {
val appPath: String = AppPath val appPath: String = AppPath
var quickSettings = QuickSettings(this) var quickSettings = QuickSettings(this)
KenjinxNative.jnaInstance.loggingSetEnabled( KenjinxNative.loggingSetEnabled(
LogLevel.Info.ordinal, LogLevel.Info,
quickSettings.enableInfoLogs quickSettings.enableInfoLogs
) )
KenjinxNative.jnaInstance.loggingSetEnabled( KenjinxNative.loggingSetEnabled(
LogLevel.Stub.ordinal, LogLevel.Stub,
quickSettings.enableStubLogs quickSettings.enableStubLogs
) )
KenjinxNative.jnaInstance.loggingSetEnabled( KenjinxNative.loggingSetEnabled(
LogLevel.Warning.ordinal, LogLevel.Warning,
quickSettings.enableWarningLogs quickSettings.enableWarningLogs
) )
KenjinxNative.jnaInstance.loggingSetEnabled( KenjinxNative.loggingSetEnabled(
LogLevel.Error.ordinal, LogLevel.Error,
quickSettings.enableErrorLogs quickSettings.enableErrorLogs
) )
KenjinxNative.jnaInstance.loggingSetEnabled( KenjinxNative.loggingSetEnabled(
LogLevel.AccessLog.ordinal, LogLevel.AccessLog,
quickSettings.enableFsAccessLogs quickSettings.enableFsAccessLogs
) )
KenjinxNative.jnaInstance.loggingSetEnabled( KenjinxNative.loggingSetEnabled(
LogLevel.Guest.ordinal, LogLevel.Guest,
quickSettings.enableGuestLogs quickSettings.enableGuestLogs
) )
KenjinxNative.jnaInstance.loggingSetEnabled( KenjinxNative.loggingSetEnabled(
LogLevel.Trace.ordinal, LogLevel.Trace,
quickSettings.enableTraceLogs quickSettings.enableTraceLogs
) )
KenjinxNative.jnaInstance.loggingSetEnabled( KenjinxNative.loggingSetEnabled(
LogLevel.Debug.ordinal, LogLevel.Debug,
quickSettings.enableDebugLogs quickSettings.enableDebugLogs
) )
KenjinxNative.jnaInstance.loggingEnabledGraphicsLog( KenjinxNative.loggingEnabledGraphicsLog(
quickSettings.enableGraphicsLogs quickSettings.enableGraphicsLogs
) )
val success =
KenjinxNative.jnaInstance.javaInitialize(appPath, JNIEnv.CURRENT)
_isInit = success _isInit = KenjinxNative.javaInitialize(appPath, JNIEnv.CURRENT)
} }
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
@@ -235,7 +233,7 @@ class MainActivity : BaseActivity() {
val forceNceAndPptc = storedIntent.getBooleanExtra("forceNceAndPptc",false) val forceNceAndPptc = storedIntent.getBooleanExtra("forceNceAndPptc",false)
if (bootPath != null) { if (bootPath != null) {
val uri = android.net.Uri.parse(bootPath) val uri = bootPath.toUri()
val documentFile = DocumentFile.fromSingleUri(this, uri) val documentFile = DocumentFile.fromSingleUri(this, uri)
if (documentFile != null) { if (documentFile != null) {
@@ -92,8 +92,8 @@ class MotionSensorManager(val activity: MainActivity) : SensorEventListener2 {
isRegistered = false isRegistered = false
if (controllerId != -1) { if (controllerId != -1) {
KenjinxNative.jnaInstance.inputSetAccelerometerData(0.0F, 0.0F, 0.0F, controllerId) KenjinxNative.inputSetAccelerometerData(0.0F, 0.0F, 0.0F, controllerId)
KenjinxNative.jnaInstance.inputSetGyroData(0.0F, 0.0F, 0.0F, controllerId) KenjinxNative.inputSetGyroData(0.0F, 0.0F, 0.0F, controllerId)
} }
} }
@@ -107,7 +107,7 @@ class MotionSensorManager(val activity: MainActivity) : SensorEventListener2 {
val y = motionAcelOrientation[1] * event.values[0] val y = motionAcelOrientation[1] * event.values[0]
val z = motionAcelOrientation[2] * event.values[2] val z = motionAcelOrientation[2] * event.values[2]
KenjinxNative.jnaInstance.inputSetAccelerometerData( KenjinxNative.inputSetAccelerometerData(
x, x,
y, y,
z, z,
@@ -119,13 +119,13 @@ class MotionSensorManager(val activity: MainActivity) : SensorEventListener2 {
val x = motionGyroOrientation[0] * event.values[1] val x = motionGyroOrientation[0] * event.values[1]
val y = motionGyroOrientation[1] * event.values[0] val y = motionGyroOrientation[1] * event.values[0]
val z = motionGyroOrientation[2] * event.values[2] val z = motionGyroOrientation[2] * event.values[2]
KenjinxNative.jnaInstance.inputSetGyroData(x, y, z, controllerId) KenjinxNative.inputSetGyroData(x, y, z, controllerId)
} }
} }
} }
else { else {
KenjinxNative.jnaInstance.inputSetAccelerometerData(0.0F, 0.0F, 0.0F, controllerId) KenjinxNative.inputSetAccelerometerData(0.0F, 0.0F, 0.0F, controllerId)
KenjinxNative.jnaInstance.inputSetGyroData(0.0F, 0.0F, 0.0F, controllerId) KenjinxNative.inputSetGyroData(0.0F, 0.0F, 0.0F, controllerId)
} }
} }
@@ -7,12 +7,12 @@ class NativeWindow(val surface: SurfaceView) {
private val nativeHelpers: NativeHelpers = NativeHelpers.instance private val nativeHelpers: NativeHelpers = NativeHelpers.instance
private var _swapInterval: Int = 0 private var _swapInterval: Int = 0
var maxSwapInterval: Int = 0 val maxSwapInterval: Int
get() { get() {
return if (nativePointer == -1L) 0 else nativeHelpers.getMaxSwapInterval(nativePointer) return if (nativePointer == -1L) 0 else nativeHelpers.getMaxSwapInterval(nativePointer)
} }
var minSwapInterval: Int = 0 val minSwapInterval: Int
get() { get() {
return if (nativePointer == -1L) 0 else nativeHelpers.getMinSwapInterval(nativePointer) return if (nativePointer == -1L) 0 else nativeHelpers.getMinSwapInterval(nativePointer)
} }
@@ -6,23 +6,17 @@ import android.util.Log
import androidx.compose.runtime.MutableState import androidx.compose.runtime.MutableState
import java.io.RandomAccessFile import java.io.RandomAccessFile
class PerformanceMonitor { object PerformanceMonitor {
val numberOfCores = Runtime.getRuntime().availableProcessors()
fun getFrequencies(frequencies: MutableList<Double>){ fun getFrequencies(frequencies: MutableList<Double>){
frequencies.clear() frequencies.clear()
for (i in 0 until numberOfCores) { for (i in 0 until Runtime.getRuntime().availableProcessors()) {
var freq = 0.0 runCatching {
try { val raf = RandomAccessFile("/sys/devices/system/cpu/cpu$i/cpufreq/scaling_cur_freq", "r")
RandomAccessFile("/sys/devices/system/cpu/cpu${i}/cpufreq/scaling_cur_freq", "r").use { reader->
val f = reader.readLine()
freq = f.toDouble() / 1000.0
}
} catch (e: Exception) {
Log.e("Performance Monitor", "Failed to read CPU freq", e);
}
frequencies.add(freq) frequencies.add(raf.use { it.readLine().toDouble() / 1000.0 })
}.onFailure {
Log.e("Performance Monitor", "Failed to read frequency of CPU core $i", it)
}
} }
} }
@@ -40,4 +34,4 @@ class PerformanceMonitor {
totalMem.value = totalMemory.toInt() totalMem.value = totalMemory.toInt()
} }
} }
} }
@@ -15,11 +15,11 @@ class PhysicalControllerManager(val activity: MainActivity) {
if (/*controllerId != -1 &&*/ isNotFallback) { if (/*controllerId != -1 &&*/ isNotFallback) {
when (event.action) { when (event.action) {
KeyEvent.ACTION_UP -> { KeyEvent.ACTION_UP -> {
KenjinxNative.jnaInstance.inputSetButtonReleased(id.ordinal, controllerId) KenjinxNative.inputSetButtonReleased(id.ordinal, controllerId)
} }
KeyEvent.ACTION_DOWN -> { KeyEvent.ACTION_DOWN -> {
KenjinxNative.jnaInstance.inputSetButtonPressed(id.ordinal, controllerId) KenjinxNative.inputSetButtonPressed(id.ordinal, controllerId)
} }
} }
return true return true
@@ -38,13 +38,13 @@ class PhysicalControllerManager(val activity: MainActivity) {
val leftStickY = ev.getAxisValue(MotionEvent.AXIS_Y) val leftStickY = ev.getAxisValue(MotionEvent.AXIS_Y)
val rightStickX = ev.getAxisValue(MotionEvent.AXIS_Z) val rightStickX = ev.getAxisValue(MotionEvent.AXIS_Z)
val rightStickY = ev.getAxisValue(MotionEvent.AXIS_RZ) val rightStickY = ev.getAxisValue(MotionEvent.AXIS_RZ)
KenjinxNative.jnaInstance.inputSetStickAxis( KenjinxNative.inputSetStickAxis(
1, 1,
leftStickX, leftStickX,
-leftStickY, -leftStickY,
controllerId controllerId
) )
KenjinxNative.jnaInstance.inputSetStickAxis( KenjinxNative.inputSetStickAxis(
2, 2,
rightStickX, rightStickX,
-rightStickY, -rightStickY,
@@ -57,63 +57,63 @@ class PhysicalControllerManager(val activity: MainActivity) {
val dPadHor = ev.getAxisValue(MotionEvent.AXIS_HAT_X) val dPadHor = ev.getAxisValue(MotionEvent.AXIS_HAT_X)
val dPadVert = ev.getAxisValue(MotionEvent.AXIS_HAT_Y) val dPadVert = ev.getAxisValue(MotionEvent.AXIS_HAT_Y)
if (dPadVert == 0.0f) { if (dPadVert == 0.0f) {
KenjinxNative.jnaInstance.inputSetButtonReleased( KenjinxNative.inputSetButtonReleased(
GamePadButtonInputId.DpadUp.ordinal, GamePadButtonInputId.DpadUp.ordinal,
controllerId controllerId
) )
KenjinxNative.jnaInstance.inputSetButtonReleased( KenjinxNative.inputSetButtonReleased(
GamePadButtonInputId.DpadDown.ordinal, GamePadButtonInputId.DpadDown.ordinal,
controllerId controllerId
) )
} }
if (dPadHor == 0.0f) { if (dPadHor == 0.0f) {
KenjinxNative.jnaInstance.inputSetButtonReleased( KenjinxNative.inputSetButtonReleased(
GamePadButtonInputId.DpadLeft.ordinal, GamePadButtonInputId.DpadLeft.ordinal,
controllerId controllerId
) )
KenjinxNative.jnaInstance.inputSetButtonReleased( KenjinxNative.inputSetButtonReleased(
GamePadButtonInputId.DpadRight.ordinal, GamePadButtonInputId.DpadRight.ordinal,
controllerId controllerId
) )
} }
if (dPadVert < 0.0f) { if (dPadVert < 0.0f) {
KenjinxNative.jnaInstance.inputSetButtonPressed( KenjinxNative.inputSetButtonPressed(
GamePadButtonInputId.DpadUp.ordinal, GamePadButtonInputId.DpadUp.ordinal,
controllerId controllerId
) )
KenjinxNative.jnaInstance.inputSetButtonReleased( KenjinxNative.inputSetButtonReleased(
GamePadButtonInputId.DpadDown.ordinal, GamePadButtonInputId.DpadDown.ordinal,
controllerId controllerId
) )
} }
if (dPadHor < 0.0f) { if (dPadHor < 0.0f) {
KenjinxNative.jnaInstance.inputSetButtonPressed( KenjinxNative.inputSetButtonPressed(
GamePadButtonInputId.DpadLeft.ordinal, GamePadButtonInputId.DpadLeft.ordinal,
controllerId controllerId
) )
KenjinxNative.jnaInstance.inputSetButtonReleased( KenjinxNative.inputSetButtonReleased(
GamePadButtonInputId.DpadRight.ordinal, GamePadButtonInputId.DpadRight.ordinal,
controllerId controllerId
) )
} }
if (dPadVert > 0.0f) { if (dPadVert > 0.0f) {
KenjinxNative.jnaInstance.inputSetButtonReleased( KenjinxNative.inputSetButtonReleased(
GamePadButtonInputId.DpadUp.ordinal, GamePadButtonInputId.DpadUp.ordinal,
controllerId controllerId
) )
KenjinxNative.jnaInstance.inputSetButtonPressed( KenjinxNative.inputSetButtonPressed(
GamePadButtonInputId.DpadDown.ordinal, GamePadButtonInputId.DpadDown.ordinal,
controllerId controllerId
) )
} }
if (dPadHor > 0.0f) { if (dPadHor > 0.0f) {
KenjinxNative.jnaInstance.inputSetButtonReleased( KenjinxNative.inputSetButtonReleased(
GamePadButtonInputId.DpadLeft.ordinal, GamePadButtonInputId.DpadLeft.ordinal,
controllerId controllerId
) )
KenjinxNative.jnaInstance.inputSetButtonPressed( KenjinxNative.inputSetButtonPressed(
GamePadButtonInputId.DpadRight.ordinal, GamePadButtonInputId.DpadRight.ordinal,
controllerId controllerId
) )
@@ -125,7 +125,7 @@ class PhysicalControllerManager(val activity: MainActivity) {
} }
fun connect(): Int { fun connect(): Int {
controllerId = KenjinxNative.jnaInstance.inputConnectGamepad(0) controllerId = KenjinxNative.inputConnectGamepad(0)
return controllerId return controllerId
} }
@@ -52,7 +52,7 @@ class UiHandler {
var message: String = "" var message: String = ""
init { init {
KenjinxNative.jnaInstance.uiHandlerSetup() KenjinxNative.uiHandlerSetup()
} }
fun update( fun update(
@@ -96,7 +96,7 @@ class UiHandler {
fun validate(): Boolean { fun validate(): Boolean {
if (inputText.value.isEmpty()) { if (inputText.value.isEmpty()) {
validation.value = "Must be between ${minLength} and ${maxLength} characters" validation.value = "Must be between $minLength and $maxLength characters"
} else { } else {
return inputText.value.length < minLength || inputText.value.length > maxLength return inputText.value.length < minLength || inputText.value.length > maxLength
} }
@@ -120,7 +120,7 @@ class UiHandler {
if (inputListener.value.length < minLength || inputListener.value.length > maxLength) if (inputListener.value.length < minLength || inputListener.value.length > maxLength)
return return
} }
KenjinxNative.jnaInstance.uiHandlerSetResponse( KenjinxNative.uiHandlerSetResponse(
true, true,
if (type == 2) inputListener.value else "" if (type == 2) inputListener.value else ""
) )
@@ -105,7 +105,7 @@ class DlcViewModel(val titleId: String) {
if (!isDuplicate) { if (!isDuplicate) {
val contents = val contents =
KenjinxNative.jnaInstance.deviceGetDlcContentList( KenjinxNative.deviceGetDlcContentList(
path, path,
titleId.toLong(16) titleId.toLong(16)
) )
@@ -118,7 +118,7 @@ class DlcViewModel(val titleId: String) {
container.dlc_nca_list.add( container.dlc_nca_list.add(
DlcContainer( DlcContainer(
true, true,
KenjinxNative.jnaInstance.deviceGetDlcTitleId( KenjinxNative.deviceGetDlcTitleId(
contentPath, contentPath,
content content
).toLong(16), ).toLong(16),
@@ -172,7 +172,7 @@ class DlcViewModel(val titleId: String) {
enabled, enabled,
containerPath, containerPath,
dlc.path, dlc.path,
KenjinxNative.jnaInstance.deviceGetDlcTitleId( KenjinxNative.deviceGetDlcTitleId(
containerPath, containerPath,
dlc.path dlc.path
) )
@@ -35,7 +35,7 @@ class GameModel(var file: DocumentFile, val context: Context) {
fun getGameInfo() { fun getGameInfo() {
val pid = open() val pid = open()
val gameInfo = GameInfo() val gameInfo = GameInfo()
KenjinxNative.jnaInstance.deviceGetGameInfo(pid, file.extension, gameInfo) KenjinxNative.deviceGetGameInfo(pid, file.extension, gameInfo)
close() close()
fileSize = gameInfo.FileSize fileSize = gameInfo.FileSize
@@ -18,6 +18,7 @@ import org.kenjinx.android.PerformanceManager
import org.kenjinx.android.PhysicalControllerManager import org.kenjinx.android.PhysicalControllerManager
import org.kenjinx.android.RegionCode import org.kenjinx.android.RegionCode
import org.kenjinx.android.KenjinxNative import org.kenjinx.android.KenjinxNative
import org.kenjinx.android.PerformanceMonitor
import org.kenjinx.android.SystemLanguage import org.kenjinx.android.SystemLanguage
import org.kenjinx.android.UiHandler import org.kenjinx.android.UiHandler
import java.io.File import java.io.File
@@ -62,20 +63,20 @@ class MainViewModel(val activity: MainActivity) {
} }
fun refreshFirmwareVersion() { fun refreshFirmwareVersion() {
firmwareVersion = KenjinxNative.jnaInstance.deviceGetInstalledFirmwareVersion() firmwareVersion = KenjinxNative.deviceGetInstalledFirmwareVersion()
} }
fun closeGame() { fun closeGame() {
KenjinxNative.jnaInstance.deviceSignalEmulationClose() KenjinxNative.deviceSignalEmulationClose()
gameHost?.close() gameHost?.close()
KenjinxNative.jnaInstance.deviceCloseEmulation() KenjinxNative.deviceCloseEmulation()
motionSensorManager?.unregister() motionSensorManager?.unregister()
physicalControllerManager?.disconnect() physicalControllerManager?.disconnect()
motionSensorManager?.setControllerId(-1) motionSensorManager?.setControllerId(-1)
} }
fun loadGame(game: GameModel, overrideSettings: Boolean? = false, forceNceAndPptc: Boolean? = false): Int { fun loadGame(game: GameModel, overrideSettings: Boolean? = false, forceNceAndPptc: Boolean? = false): Int {
KenjinxNative.jnaInstance.deviceReinitEmulation() KenjinxNative.deviceReinitEmulation()
MainActivity.mainViewModel?.activity?.uiHandler = UiHandler() MainActivity.mainViewModel?.activity?.uiHandler = UiHandler()
val descriptor = game.open() val descriptor = game.open()
@@ -100,7 +101,7 @@ class MainViewModel(val activity: MainActivity) {
settings.overrideSettings(forceNceAndPptc); settings.overrideSettings(forceNceAndPptc);
} }
var success = KenjinxNative.jnaInstance.graphicsInitialize( var success = KenjinxNative.graphicsInitialize(
enableMacroHLE = settings.enableMacroHLE, enableMacroHLE = settings.enableMacroHLE,
enableShaderCache = settings.enableShaderCache, enableShaderCache = settings.enableShaderCache,
enableTextureRecompression = settings.enableTextureRecompression, enableTextureRecompression = settings.enableTextureRecompression,
@@ -156,7 +157,7 @@ class MainViewModel(val activity: MainActivity) {
val extensions = nativeInterop.VkRequiredExtensions val extensions = nativeInterop.VkRequiredExtensions
success = KenjinxNative.jnaInstance.graphicsInitializeRenderer( success = KenjinxNative.graphicsInitializeRenderer(
extensions!!, extensions!!,
extensions.size, extensions.size,
driverHandle driverHandle
@@ -169,7 +170,7 @@ class MainViewModel(val activity: MainActivity) {
semaphore.acquire() semaphore.acquire()
launchOnUiThread { launchOnUiThread {
// We are only able to initialize the emulation context on the main thread // We are only able to initialize the emulation context on the main thread
success = KenjinxNative.jnaInstance.deviceInitialize( success = KenjinxNative.deviceInitialize(
settings.memoryManagerMode.ordinal, settings.memoryManagerMode.ordinal,
settings.useNce, settings.useNce,
settings.memoryConfiguration.ordinal, settings.memoryConfiguration.ordinal,
@@ -194,7 +195,7 @@ class MainViewModel(val activity: MainActivity) {
if (!success) if (!success)
return 0 return 0
success = KenjinxNative.jnaInstance.deviceLoadDescriptor(descriptor, game.type.ordinal, update) success = KenjinxNative.deviceLoadDescriptor(descriptor, game.type.ordinal, update)
return if (success) 1 else 0 return if (success) 1 else 0
} }
@@ -205,7 +206,7 @@ class MainViewModel(val activity: MainActivity) {
val settings = QuickSettings(activity) val settings = QuickSettings(activity)
var success = KenjinxNative.jnaInstance.graphicsInitialize( var success = KenjinxNative.graphicsInitialize(
enableMacroHLE = settings.enableMacroHLE, enableMacroHLE = settings.enableMacroHLE,
enableShaderCache = settings.enableShaderCache, enableShaderCache = settings.enableShaderCache,
enableTextureRecompression = settings.enableTextureRecompression, enableTextureRecompression = settings.enableTextureRecompression,
@@ -262,7 +263,7 @@ class MainViewModel(val activity: MainActivity) {
val extensions = nativeInterop.VkRequiredExtensions val extensions = nativeInterop.VkRequiredExtensions
success = KenjinxNative.jnaInstance.graphicsInitializeRenderer( success = KenjinxNative.graphicsInitializeRenderer(
extensions!!, extensions!!,
extensions.size, extensions.size,
driverHandle driverHandle
@@ -275,7 +276,7 @@ class MainViewModel(val activity: MainActivity) {
semaphore.acquire() semaphore.acquire()
launchOnUiThread { launchOnUiThread {
// We are only able to initialize the emulation context on the main thread // We are only able to initialize the emulation context on the main thread
success = KenjinxNative.jnaInstance.deviceInitialize( success = KenjinxNative.deviceInitialize(
settings.memoryManagerMode.ordinal, settings.memoryManagerMode.ordinal,
settings.useNce, settings.useNce,
settings.memoryConfiguration.ordinal, settings.memoryConfiguration.ordinal,
@@ -300,7 +301,7 @@ class MainViewModel(val activity: MainActivity) {
if (!success) if (!success)
return false return false
success = KenjinxNative.jnaInstance.deviceLaunchMiiEditor() success = KenjinxNative.deviceLaunchMiiEditor()
return success return success
} }
@@ -399,13 +400,13 @@ class MainViewModel(val activity: MainActivity) {
} }
usedMemState?.let { usedMem -> usedMemState?.let { usedMem ->
totalMemState?.let { totalMem -> totalMemState?.let { totalMem ->
MainActivity.performanceMonitor.getMemoryUsage( PerformanceMonitor.getMemoryUsage(
usedMem, usedMem,
totalMem totalMem
) )
} }
} }
frequenciesState?.let { MainActivity.performanceMonitor.getFrequencies(it) } frequenciesState?.let { PerformanceMonitor.getFrequencies(it) }
} }
fun setGameController(controller: GameController) { fun setGameController(controller: GameController) {
@@ -173,15 +173,15 @@ class SettingsViewModel(val activity: MainActivity) {
editor.apply() editor.apply()
activity.storageHelper!!.onFolderSelected = previousFolderCallback activity.storageHelper!!.onFolderSelected = previousFolderCallback
KenjinxNative.jnaInstance.loggingSetEnabled(LogLevel.Info.ordinal, enableInfoLogs.value) KenjinxNative.loggingSetEnabled(LogLevel.Info, enableInfoLogs.value)
KenjinxNative.jnaInstance.loggingSetEnabled(LogLevel.Stub.ordinal, enableStubLogs.value) KenjinxNative.loggingSetEnabled(LogLevel.Stub, enableStubLogs.value)
KenjinxNative.jnaInstance.loggingSetEnabled(LogLevel.Warning.ordinal, enableWarningLogs.value) KenjinxNative.loggingSetEnabled(LogLevel.Warning, enableWarningLogs.value)
KenjinxNative.jnaInstance.loggingSetEnabled(LogLevel.Error.ordinal, enableErrorLogs.value) KenjinxNative.loggingSetEnabled(LogLevel.Error, enableErrorLogs.value)
KenjinxNative.jnaInstance.loggingSetEnabled(LogLevel.AccessLog.ordinal, enableFsAccessLogs.value) KenjinxNative.loggingSetEnabled(LogLevel.AccessLog, enableFsAccessLogs.value)
KenjinxNative.jnaInstance.loggingSetEnabled(LogLevel.Guest.ordinal, enableGuestLogs.value) KenjinxNative.loggingSetEnabled(LogLevel.Guest, enableGuestLogs.value)
KenjinxNative.jnaInstance.loggingSetEnabled(LogLevel.Trace.ordinal, enableTraceLogs.value) KenjinxNative.loggingSetEnabled(LogLevel.Trace, enableTraceLogs.value)
KenjinxNative.jnaInstance.loggingSetEnabled(LogLevel.Debug.ordinal, enableDebugLogs.value) KenjinxNative.loggingSetEnabled(LogLevel.Debug, enableDebugLogs.value)
KenjinxNative.jnaInstance.loggingEnabledGraphicsLog(enableGraphicsLogs.value) KenjinxNative.loggingEnabledGraphicsLog(enableGraphicsLogs.value)
} }
fun openGameFolder() { fun openGameFolder() {
@@ -236,7 +236,7 @@ class SettingsViewModel(val activity: MainActivity) {
outputFolder, outputFolder,
callback = object : FileCallback() { callback = object : FileCallback() {
override fun onCompleted(result: Any) { override fun onCompleted(result: Any) {
KenjinxNative.jnaInstance.deviceReloadFilesystem() KenjinxNative.deviceReloadFilesystem()
installState.value = KeyInstallState.Done installState.value = KeyInstallState.Done
} }
} }
@@ -264,7 +264,7 @@ class SettingsViewModel(val activity: MainActivity) {
Thread.sleep(1000) Thread.sleep(1000)
val descriptor = activity.contentResolver.openFileDescriptor(file.uri, "rw") val descriptor = activity.contentResolver.openFileDescriptor(file.uri, "rw")
descriptor?.use { d -> descriptor?.use { d ->
selectedFirmwareVersion = KenjinxNative.jnaInstance.deviceVerifyFirmware(d.fd, extension == "xci") selectedFirmwareVersion = KenjinxNative.deviceVerifyFirmware(d.fd, extension == "xci")
selectedFirmwareFile = file selectedFirmwareFile = file
if (!selectedFirmwareVersion.isEmpty()) { if (!selectedFirmwareVersion.isEmpty()) {
installState.value = FirmwareInstallState.Query installState.value = FirmwareInstallState.Query
@@ -299,7 +299,7 @@ class SettingsViewModel(val activity: MainActivity) {
Thread.sleep(1000) Thread.sleep(1000)
try { try {
KenjinxNative.jnaInstance.deviceInstallFirmware(descriptor.fd,extension == "xci") KenjinxNative.deviceInstallFirmware(descriptor.fd,extension == "xci")
} finally { } finally {
MainActivity.mainViewModel?.refreshFirmwareVersion() MainActivity.mainViewModel?.refreshFirmwareVersion()
installState.value = FirmwareInstallState.Done installState.value = FirmwareInstallState.Done
@@ -361,7 +361,7 @@ class SettingsViewModel(val activity: MainActivity) {
} }
} finally { } finally {
dataImportState.value = DataImportState.Done dataImportState.value = DataImportState.Done
KenjinxNative.jnaInstance.deviceReloadFilesystem() KenjinxNative.deviceReloadFilesystem()
MainActivity.mainViewModel?.refreshFirmwareVersion() MainActivity.mainViewModel?.refreshFirmwareVersion()
} }
} }
@@ -15,24 +15,24 @@ class UserViewModel {
userList.clear() userList.clear()
val decoder = Base64.getDecoder() val decoder = Base64.getDecoder()
openedUser = UserModel() openedUser = UserModel()
openedUser.id = KenjinxNative.jnaInstance.userGetOpenedUser() openedUser.id = KenjinxNative.userGetOpenedUser()
if (openedUser.id.isNotEmpty()) { if (openedUser.id.isNotEmpty()) {
openedUser.username = KenjinxNative.jnaInstance.userGetUserName(openedUser.id) openedUser.username = KenjinxNative.userGetUserName(openedUser.id)
openedUser.userPicture = decoder.decode( openedUser.userPicture = decoder.decode(
KenjinxNative.jnaInstance.userGetUserPicture( KenjinxNative.userGetUserPicture(
openedUser.id openedUser.id
) )
) )
} }
val users = KenjinxNative.jnaInstance.userGetAllUsers() val users = KenjinxNative.userGetAllUsers()
for (user in users) { for (user in users) {
userList.add( userList.add(
UserModel( UserModel(
user, user,
KenjinxNative.jnaInstance.userGetUserName(user), KenjinxNative.userGetUserName(user),
decoder.decode( decoder.decode(
KenjinxNative.jnaInstance.userGetUserPicture(user) KenjinxNative.userGetUserPicture(user)
) )
) )
) )
@@ -40,7 +40,7 @@ class UserViewModel {
} }
fun openUser(userModel: UserModel) { fun openUser(userModel: UserModel) {
KenjinxNative.jnaInstance.userOpenUser(userModel.id) KenjinxNative.userOpenUser(userModel.id)
refreshUsers() refreshUsers()
} }
@@ -130,19 +130,19 @@ class GameViews {
when (event.type) { when (event.type) {
PointerEventType.Press -> { PointerEventType.Press -> {
KenjinxNative.jnaInstance.inputSetTouchPoint( KenjinxNative.inputSetTouchPoint(
position.x.roundToInt(), position.x.roundToInt(),
position.y.roundToInt() position.y.roundToInt()
) )
} }
PointerEventType.Release -> { PointerEventType.Release -> {
KenjinxNative.jnaInstance.inputReleaseTouchPoint() KenjinxNative.inputReleaseTouchPoint()
} }
PointerEventType.Move -> { PointerEventType.Move -> {
KenjinxNative.jnaInstance.inputSetTouchPoint( KenjinxNative.inputSetTouchPoint(
position.x.roundToInt(), position.x.roundToInt(),
position.y.roundToInt() position.y.roundToInt()
) )
@@ -188,7 +188,7 @@ class GameViews {
IconButton(modifier = Modifier.padding(4.dp), onClick = { IconButton(modifier = Modifier.padding(4.dp), onClick = {
showMore.value = false showMore.value = false
showController.value = !showController.value showController.value = !showController.value
KenjinxNative.jnaInstance.inputReleaseTouchPoint() KenjinxNative.inputReleaseTouchPoint()
mainViewModel.controller?.setVisible(showController.value) mainViewModel.controller?.setVisible(showController.value)
}) { }) {
Icon( Icon(
@@ -207,7 +207,7 @@ class GameViews {
{ {
vSyncMode.value= VSyncMode.Switch vSyncMode.value= VSyncMode.Switch
} }
KenjinxNative.jnaInstance.graphicsRendererSetVsync( KenjinxNative.graphicsRendererSetVsync(
vSyncMode.value.ordinal vSyncMode.value.ordinal
) )
}) { }) {