mirror of
				https://git.suyu.dev/suyu/suyu
				synced 2025-11-04 00:49:02 -06:00 
			
		
		
		
	Merge pull request #10691 from t895/nro-check
android: Add proper homebrew check
This commit is contained in:
		@@ -223,6 +223,8 @@ object NativeLibrary {
 | 
			
		||||
 | 
			
		||||
    external fun getCompany(filename: String): String
 | 
			
		||||
 | 
			
		||||
    external fun isHomebrew(filename: String): Boolean
 | 
			
		||||
 | 
			
		||||
    external fun setAppDirectory(directory: String)
 | 
			
		||||
 | 
			
		||||
    external fun initializeGpuDriver(
 | 
			
		||||
 
 | 
			
		||||
@@ -127,13 +127,7 @@ class SearchFragment : Fragment() {
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            R.id.chip_homebrew -> {
 | 
			
		||||
                baseList.filter {
 | 
			
		||||
                    Log.error("Guh - ${it.path}")
 | 
			
		||||
                    FileUtil.hasExtension(it.path, "nro")
 | 
			
		||||
                            || FileUtil.hasExtension(it.path, "nso")
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            R.id.chip_homebrew -> baseList.filter { it.isHomebrew }
 | 
			
		||||
 | 
			
		||||
            R.id.chip_retail -> baseList.filter {
 | 
			
		||||
                FileUtil.hasExtension(it.path, "xci")
 | 
			
		||||
 
 | 
			
		||||
@@ -16,7 +16,8 @@ class Game(
 | 
			
		||||
    val regions: String,
 | 
			
		||||
    val path: String,
 | 
			
		||||
    val gameId: String,
 | 
			
		||||
    val company: String
 | 
			
		||||
    val company: String,
 | 
			
		||||
    val isHomebrew: Boolean
 | 
			
		||||
) : Parcelable {
 | 
			
		||||
    val keyAddedToLibraryTime get() = "${gameId}_AddedToLibraryTime"
 | 
			
		||||
    val keyLastPlayedTime get() = "${gameId}_LastPlayed"
 | 
			
		||||
@@ -31,6 +32,7 @@ class Game(
 | 
			
		||||
                && path == other.path
 | 
			
		||||
                && gameId == other.gameId
 | 
			
		||||
                && company == other.company
 | 
			
		||||
                && isHomebrew == other.isHomebrew
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    companion object {
 | 
			
		||||
 
 | 
			
		||||
@@ -13,6 +13,8 @@ import androidx.preference.PreferenceManager
 | 
			
		||||
import kotlinx.coroutines.Dispatchers
 | 
			
		||||
import kotlinx.coroutines.launch
 | 
			
		||||
import kotlinx.coroutines.withContext
 | 
			
		||||
import kotlinx.serialization.ExperimentalSerializationApi
 | 
			
		||||
import kotlinx.serialization.MissingFieldException
 | 
			
		||||
import kotlinx.serialization.decodeFromString
 | 
			
		||||
import kotlinx.serialization.json.Json
 | 
			
		||||
import org.yuzu.yuzu_emu.NativeLibrary
 | 
			
		||||
@@ -20,6 +22,7 @@ import org.yuzu.yuzu_emu.YuzuApplication
 | 
			
		||||
import org.yuzu.yuzu_emu.utils.GameHelper
 | 
			
		||||
import java.util.Locale
 | 
			
		||||
 | 
			
		||||
@OptIn(ExperimentalSerializationApi::class)
 | 
			
		||||
class GamesViewModel : ViewModel() {
 | 
			
		||||
    private val _games = MutableLiveData<List<Game>>(emptyList())
 | 
			
		||||
    val games: LiveData<List<Game>> get() = _games
 | 
			
		||||
@@ -49,7 +52,13 @@ class GamesViewModel : ViewModel() {
 | 
			
		||||
        if (storedGames!!.isNotEmpty()) {
 | 
			
		||||
            val deserializedGames = mutableSetOf<Game>()
 | 
			
		||||
            storedGames.forEach {
 | 
			
		||||
                val game: Game = Json.decodeFromString(it)
 | 
			
		||||
                val game: Game
 | 
			
		||||
                try {
 | 
			
		||||
                    game = Json.decodeFromString(it)
 | 
			
		||||
                } catch (e: MissingFieldException) {
 | 
			
		||||
                    return@forEach
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                val gameExists =
 | 
			
		||||
                    DocumentFile.fromSingleUri(YuzuApplication.appContext, Uri.parse(game.path))
 | 
			
		||||
                        ?.exists()
 | 
			
		||||
 
 | 
			
		||||
@@ -6,7 +6,6 @@ package org.yuzu.yuzu_emu.utils
 | 
			
		||||
import android.content.SharedPreferences
 | 
			
		||||
import android.net.Uri
 | 
			
		||||
import androidx.preference.PreferenceManager
 | 
			
		||||
import kotlinx.serialization.decodeFromString
 | 
			
		||||
import kotlinx.serialization.encodeToString
 | 
			
		||||
import kotlinx.serialization.json.Json
 | 
			
		||||
import org.yuzu.yuzu_emu.NativeLibrary
 | 
			
		||||
@@ -83,7 +82,8 @@ object GameHelper {
 | 
			
		||||
            NativeLibrary.getRegions(filePath),
 | 
			
		||||
            filePath,
 | 
			
		||||
            gameId,
 | 
			
		||||
            NativeLibrary.getCompany(filePath)
 | 
			
		||||
            NativeLibrary.getCompany(filePath),
 | 
			
		||||
            NativeLibrary.isHomebrew(filePath)
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
        val addedTime = preferences.getLong(newGame.keyAddedToLibraryTime, 0L)
 | 
			
		||||
 
 | 
			
		||||
@@ -13,6 +13,7 @@
 | 
			
		||||
 | 
			
		||||
#include <android/api-level.h>
 | 
			
		||||
#include <android/native_window_jni.h>
 | 
			
		||||
#include <core/loader/nro.h>
 | 
			
		||||
 | 
			
		||||
#include "common/detached_tasks.h"
 | 
			
		||||
#include "common/dynamic_library.h"
 | 
			
		||||
@@ -281,6 +282,10 @@ public:
 | 
			
		||||
        return GetRomMetadata(path).icon;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool GetIsHomebrew(const std::string& path) {
 | 
			
		||||
        return GetRomMetadata(path).isHomebrew;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void ResetRomMetadata() {
 | 
			
		||||
        m_rom_metadata_cache.clear();
 | 
			
		||||
    }
 | 
			
		||||
@@ -348,6 +353,7 @@ private:
 | 
			
		||||
    struct RomMetadata {
 | 
			
		||||
        std::string title;
 | 
			
		||||
        std::vector<u8> icon;
 | 
			
		||||
        bool isHomebrew;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    RomMetadata GetRomMetadata(const std::string& path) {
 | 
			
		||||
@@ -360,11 +366,17 @@ private:
 | 
			
		||||
 | 
			
		||||
    RomMetadata CacheRomMetadata(const std::string& path) {
 | 
			
		||||
        const auto file = Core::GetGameFileFromPath(m_vfs, path);
 | 
			
		||||
        const auto loader = Loader::GetLoader(EmulationSession::GetInstance().System(), file, 0, 0);
 | 
			
		||||
        auto loader = Loader::GetLoader(EmulationSession::GetInstance().System(), file, 0, 0);
 | 
			
		||||
 | 
			
		||||
        RomMetadata entry;
 | 
			
		||||
        loader->ReadTitle(entry.title);
 | 
			
		||||
        loader->ReadIcon(entry.icon);
 | 
			
		||||
        if (loader->GetFileType() == Loader::FileType::NRO) {
 | 
			
		||||
            auto loader_nro = dynamic_cast<Loader::AppLoader_NRO*>(loader.get());
 | 
			
		||||
            entry.isHomebrew = loader_nro->IsHomebrew();
 | 
			
		||||
        } else {
 | 
			
		||||
            entry.isHomebrew = false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        m_rom_metadata_cache[path] = entry;
 | 
			
		||||
 | 
			
		||||
@@ -662,6 +674,12 @@ jstring Java_org_yuzu_yuzu_1emu_NativeLibrary_getCompany([[maybe_unused]] JNIEnv
 | 
			
		||||
    return env->NewStringUTF("");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
jboolean Java_org_yuzu_yuzu_1emu_NativeLibrary_isHomebrew([[maybe_unused]] JNIEnv* env,
 | 
			
		||||
                                                          [[maybe_unused]] jclass clazz,
 | 
			
		||||
                                                          [[maybe_unused]] jstring j_filename) {
 | 
			
		||||
    return EmulationSession::GetInstance().GetIsHomebrew(GetJString(env, j_filename));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Java_org_yuzu_yuzu_1emu_NativeLibrary_initializeEmulation
 | 
			
		||||
    [[maybe_unused]] (JNIEnv* env, [[maybe_unused]] jclass clazz) {
 | 
			
		||||
    // Create the default config.ini.
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user