From 8f8f9e996a28bad5601156d3064ed9df2eead801 Mon Sep 17 00:00:00 2001
From: Emmanuel Hansen <emmausssss@gmail.com>
Date: Sat, 5 Aug 2023 13:07:14 +0000
Subject: [PATCH] switch to using stream base game loading

---
 .../main/java/org/ryujinx/android/GameHost.kt   |  7 ++++++-
 .../org/ryujinx/android/viewmodels/GameModel.kt | 17 +++++++++++++++--
 .../ryujinx/android/viewmodels/MainViewModel.kt | 12 +++++++++---
 .../java/org/ryujinx/android/views/HomeViews.kt |  5 ++++-
 4 files changed, 34 insertions(+), 7 deletions(-)

diff --git a/src/RyujinxAndroid/app/src/main/java/org/ryujinx/android/GameHost.kt b/src/RyujinxAndroid/app/src/main/java/org/ryujinx/android/GameHost.kt
index 38cd171b1..a85b6852c 100644
--- a/src/RyujinxAndroid/app/src/main/java/org/ryujinx/android/GameHost.kt
+++ b/src/RyujinxAndroid/app/src/main/java/org/ryujinx/android/GameHost.kt
@@ -12,6 +12,7 @@ import java.io.File
 import kotlin.concurrent.thread
 
 class GameHost(context: Context?, val mainViewModel: MainViewModel) : SurfaceView(context), SurfaceHolder.Callback {
+    private var game: GameModel? = null
     private var _isClosed: Boolean = false
     private var _renderingThreadWatcher: Thread? = null
     private var _height: Int = 0
@@ -71,6 +72,8 @@ class GameHost(context: Context?, val mainViewModel: MainViewModel) : SurfaceVie
         if(_isStarted)
             return;
 
+        game = mainViewModel.gameModel
+
         _nativeRyujinx.inputInitialize(width, height)
 
         val settings = QuickSettings(mainViewModel.activity)
@@ -130,5 +133,7 @@ class GameHost(context: Context?, val mainViewModel: MainViewModel) : SurfaceVie
             }
         }
         _nativeRyujinx.graphicsRendererRunLoop()
+
+        game?.close()
     }
-}
\ No newline at end of file
+}
diff --git a/src/RyujinxAndroid/app/src/main/java/org/ryujinx/android/viewmodels/GameModel.kt b/src/RyujinxAndroid/app/src/main/java/org/ryujinx/android/viewmodels/GameModel.kt
index 0a29d717e..a06edcaff 100644
--- a/src/RyujinxAndroid/app/src/main/java/org/ryujinx/android/viewmodels/GameModel.kt
+++ b/src/RyujinxAndroid/app/src/main/java/org/ryujinx/android/viewmodels/GameModel.kt
@@ -2,6 +2,7 @@ package org.ryujinx.android.viewmodels
 
 import android.content.Context
 import android.net.Uri
+import android.os.ParcelFileDescriptor
 import androidx.documentfile.provider.DocumentFile
 import com.anggrayudi.storage.file.extension
 import org.ryujinx.android.Helpers
@@ -9,6 +10,7 @@ import org.ryujinx.android.RyujinxNative
 
 
 class GameModel(var file: DocumentFile, val context: Context) {
+    private var descriptor: ParcelFileDescriptor? = null
     var fileName: String?
     var fileSize = 0.0
     var titleName: String? = null
@@ -37,7 +39,18 @@ class GameModel(var file: DocumentFile, val context: Context) {
         return uri.path
     }
 
-    fun getIsXci() : Boolean {
+    fun open() : Int {
+        descriptor = context.contentResolver.openFileDescriptor(file.uri, "rw")
+
+        return descriptor?.fd ?: 0
+    }
+
+    fun close() {
+        descriptor?.close()
+        descriptor = null
+    }
+
+    fun isXci() : Boolean {
         return file.extension == "xci"
     }
 }
@@ -49,4 +62,4 @@ class GameInfo {
     var Developer: String? = null
     var Version: String? = null
     var IconCache: String? = null
-}
\ No newline at end of file
+}
diff --git a/src/RyujinxAndroid/app/src/main/java/org/ryujinx/android/viewmodels/MainViewModel.kt b/src/RyujinxAndroid/app/src/main/java/org/ryujinx/android/viewmodels/MainViewModel.kt
index e8361e455..b86d7d799 100644
--- a/src/RyujinxAndroid/app/src/main/java/org/ryujinx/android/viewmodels/MainViewModel.kt
+++ b/src/RyujinxAndroid/app/src/main/java/org/ryujinx/android/viewmodels/MainViewModel.kt
@@ -20,6 +20,7 @@ import java.io.File
 
 @SuppressLint("WrongConstant")
 class MainViewModel(val activity: MainActivity) {
+    var gameModel: GameModel? = null
     var gameHost: GameHost? = null
     var controller: GameController? = null
     var performanceManager: PerformanceManager? = null
@@ -54,7 +55,12 @@ class MainViewModel(val activity: MainActivity) {
     fun loadGame(game:GameModel) : Boolean {
         var nativeRyujinx = RyujinxNative()
 
-        val path = game.getPath() ?: return false
+        val descriptor = game.open()
+
+        if(descriptor == 0)
+            return false
+
+        gameModel = game;
 
         val settings = QuickSettings(activity)
 
@@ -131,7 +137,7 @@ class MainViewModel(val activity: MainActivity) {
         if(!success)
             return false
 
-        success = nativeRyujinx.deviceLoad(path)
+        success = nativeRyujinx.deviceLoadDescriptor(descriptor, game.isXci())
 
         if(!success)
             return false
@@ -171,4 +177,4 @@ class MainViewModel(val activity: MainActivity) {
 
     fun backCalled() {
     }
-}
\ No newline at end of file
+}
diff --git a/src/RyujinxAndroid/app/src/main/java/org/ryujinx/android/views/HomeViews.kt b/src/RyujinxAndroid/app/src/main/java/org/ryujinx/android/views/HomeViews.kt
index 4d9b56fea..2e4567340 100644
--- a/src/RyujinxAndroid/app/src/main/java/org/ryujinx/android/views/HomeViews.kt
+++ b/src/RyujinxAndroid/app/src/main/java/org/ryujinx/android/views/HomeViews.kt
@@ -358,6 +358,9 @@ class HomeViews {
                                                 viewModel.mainViewModel?.navController?.navigate("game")
                                             }
                                         }
+                                        else {
+                                            gameModel.close()
+                                        }
                                         showLoading.value = false
                                     }
                                 }
@@ -421,4 +424,4 @@ class HomeViews {
     fun HomePreview() {
         Home()
     }
-}
\ No newline at end of file
+}