|
|
|
@ -20,132 +20,96 @@ struct RomMetadata { |
|
|
|
std::vector<u8> icon; |
|
|
|
bool isHomebrew; |
|
|
|
}; |
|
|
|
|
|
|
|
ankerl::unordered_dense::map<std::string, RomMetadata> m_rom_metadata_cache; |
|
|
|
|
|
|
|
RomMetadata CacheRomMetadata(const std::string& path) { |
|
|
|
const auto file = |
|
|
|
Core::GetGameFileFromPath(EmulationSession::GetInstance().System().GetFilesystem(), path); |
|
|
|
auto loader = Loader::GetLoader(EmulationSession::GetInstance().System(), file, 0, 0); |
|
|
|
|
|
|
|
RomMetadata entry; |
|
|
|
loader->ReadTitle(entry.title); |
|
|
|
loader->ReadProgramId(entry.programId); |
|
|
|
loader->ReadIcon(entry.icon); |
|
|
|
|
|
|
|
const FileSys::PatchManager pm{ |
|
|
|
entry.programId, EmulationSession::GetInstance().System().GetFileSystemController(), |
|
|
|
EmulationSession::GetInstance().System().GetContentProvider()}; |
|
|
|
const auto control = pm.GetControlMetadata(); |
|
|
|
|
|
|
|
if (control.first != nullptr) { |
|
|
|
entry.developer = control.first->GetDeveloperName(); |
|
|
|
entry.version = control.first->GetVersionString(); |
|
|
|
} else { |
|
|
|
FileSys::NACP nacp; |
|
|
|
if (loader->ReadControlData(nacp) == Loader::ResultStatus::Success) { |
|
|
|
entry.developer = nacp.GetDeveloperName(); |
|
|
|
static ankerl::unordered_dense::map<std::string, RomMetadata> m_rom_metadata_cache; |
|
|
|
|
|
|
|
static RomMetadata CacheRomMetadata(const std::string& path) { |
|
|
|
auto& instance = EmulationSession::GetInstance(); |
|
|
|
const auto file = Core::GetGameFileFromPath(instance.System().GetFilesystem(), path); |
|
|
|
if (auto loader = Loader::GetLoader(instance.System(), file, 0, 0); loader) { |
|
|
|
RomMetadata entry; |
|
|
|
loader->ReadTitle(entry.title); |
|
|
|
loader->ReadProgramId(entry.programId); |
|
|
|
loader->ReadIcon(entry.icon); |
|
|
|
|
|
|
|
const FileSys::PatchManager pm{ |
|
|
|
entry.programId, |
|
|
|
instance.System().GetFileSystemController(), |
|
|
|
instance.System().GetContentProvider() |
|
|
|
}; |
|
|
|
const auto control = pm.GetControlMetadata(); |
|
|
|
|
|
|
|
if (control.first != nullptr) { |
|
|
|
entry.developer = control.first->GetDeveloperName(); |
|
|
|
entry.version = control.first->GetVersionString(); |
|
|
|
} else { |
|
|
|
entry.developer = ""; |
|
|
|
FileSys::NACP nacp{}; |
|
|
|
entry.developer = loader->ReadControlData(nacp) == Loader::ResultStatus::Success |
|
|
|
? nacp.GetDeveloperName() |
|
|
|
: ""; |
|
|
|
entry.version = "1.0.0"; |
|
|
|
} |
|
|
|
|
|
|
|
entry.version = "1.0.0"; |
|
|
|
} |
|
|
|
|
|
|
|
if (loader->GetFileType() == Loader::FileType::NRO) { |
|
|
|
auto loader_nro = reinterpret_cast<Loader::AppLoader_NRO*>(loader.get()); |
|
|
|
entry.isHomebrew = loader_nro->IsHomebrew(); |
|
|
|
} else { |
|
|
|
entry.isHomebrew = false; |
|
|
|
if (loader->GetFileType() == Loader::FileType::NRO) { |
|
|
|
auto loader_nro = reinterpret_cast<Loader::AppLoader_NRO*>(loader.get()); |
|
|
|
entry.isHomebrew = loader_nro->IsHomebrew(); |
|
|
|
} else { |
|
|
|
entry.isHomebrew = false; |
|
|
|
} |
|
|
|
m_rom_metadata_cache[path] = entry; |
|
|
|
return entry; |
|
|
|
} |
|
|
|
|
|
|
|
m_rom_metadata_cache[path] = entry; |
|
|
|
|
|
|
|
return entry; |
|
|
|
return {}; |
|
|
|
} |
|
|
|
|
|
|
|
RomMetadata GetRomMetadata(const std::string& path, bool reload = false) { |
|
|
|
if (reload) { |
|
|
|
static RomMetadata GetRomMetadata(const std::string& path, bool reload = false) { |
|
|
|
if (reload) |
|
|
|
return CacheRomMetadata(path); |
|
|
|
} |
|
|
|
|
|
|
|
if (auto search = m_rom_metadata_cache.find(path); search != m_rom_metadata_cache.end()) { |
|
|
|
return search->second; |
|
|
|
} |
|
|
|
|
|
|
|
if (auto it = m_rom_metadata_cache.find(path); it != m_rom_metadata_cache.end()) |
|
|
|
return it->second; |
|
|
|
return CacheRomMetadata(path); |
|
|
|
} |
|
|
|
|
|
|
|
extern "C" { |
|
|
|
|
|
|
|
jboolean Java_org_yuzu_yuzu_1emu_utils_GameMetadata_getIsValid(JNIEnv* env, jobject obj, |
|
|
|
jstring jpath) { |
|
|
|
const auto file = EmulationSession::GetInstance().System().GetFilesystem()->OpenFile( |
|
|
|
Common::Android::GetJString(env, jpath), FileSys::OpenMode::Read); |
|
|
|
if (!file) { |
|
|
|
return false; |
|
|
|
} |
|
|
|
|
|
|
|
auto loader = Loader::GetLoader(EmulationSession::GetInstance().System(), file); |
|
|
|
if (!loader) { |
|
|
|
return false; |
|
|
|
} |
|
|
|
|
|
|
|
const auto file_type = loader->GetFileType(); |
|
|
|
if (file_type == Loader::FileType::Unknown || file_type == Loader::FileType::Error) { |
|
|
|
return false; |
|
|
|
} |
|
|
|
|
|
|
|
if ((file_type == Loader::FileType::NSP || file_type == Loader::FileType::XCI) && |
|
|
|
!Loader::IsBootableGameContainer(file, file_type)) { |
|
|
|
return false; |
|
|
|
} |
|
|
|
|
|
|
|
u64 program_id = 0; |
|
|
|
Loader::ResultStatus res = loader->ReadProgramId(program_id); |
|
|
|
if (res != Loader::ResultStatus::Success) { |
|
|
|
return false; |
|
|
|
jboolean Java_org_yuzu_yuzu_1emu_utils_GameMetadata_getIsValid(JNIEnv* env, jobject obj, jstring jpath) { |
|
|
|
if (auto const file = EmulationSession::GetInstance().System().GetFilesystem()->OpenFile(Common::Android::GetJString(env, jpath), FileSys::OpenMode::Read); file) { |
|
|
|
if (auto loader = Loader::GetLoader(EmulationSession::GetInstance().System(), file); loader) { |
|
|
|
auto const file_type = loader->GetFileType(); |
|
|
|
if (file_type == Loader::FileType::Unknown || file_type == Loader::FileType::Error) |
|
|
|
return false; |
|
|
|
if ((file_type == Loader::FileType::NSP || file_type == Loader::FileType::XCI) && !Loader::IsBootableGameContainer(file, file_type)) |
|
|
|
return false; |
|
|
|
u64 program_id = 0; |
|
|
|
return loader->ReadProgramId(program_id) == Loader::ResultStatus::Success; |
|
|
|
} |
|
|
|
} |
|
|
|
return true; |
|
|
|
return false; |
|
|
|
} |
|
|
|
|
|
|
|
jstring Java_org_yuzu_yuzu_1emu_utils_GameMetadata_getTitle(JNIEnv* env, jobject obj, |
|
|
|
jstring jpath) { |
|
|
|
return Common::Android::ToJString( |
|
|
|
env, GetRomMetadata(Common::Android::GetJString(env, jpath)).title); |
|
|
|
jstring Java_org_yuzu_yuzu_1emu_utils_GameMetadata_getTitle(JNIEnv* env, jobject obj, jstring jpath) { |
|
|
|
return Common::Android::ToJString(env, GetRomMetadata(Common::Android::GetJString(env, jpath)).title); |
|
|
|
} |
|
|
|
|
|
|
|
jstring Java_org_yuzu_yuzu_1emu_utils_GameMetadata_getProgramId(JNIEnv* env, jobject obj, |
|
|
|
jstring jpath) { |
|
|
|
return Common::Android::ToJString( |
|
|
|
env, std::to_string(GetRomMetadata(Common::Android::GetJString(env, jpath)).programId)); |
|
|
|
jstring Java_org_yuzu_yuzu_1emu_utils_GameMetadata_getProgramId(JNIEnv* env, jobject obj, jstring jpath) { |
|
|
|
return Common::Android::ToJString(env, std::to_string(GetRomMetadata(Common::Android::GetJString(env, jpath)).programId)); |
|
|
|
} |
|
|
|
|
|
|
|
jstring Java_org_yuzu_yuzu_1emu_utils_GameMetadata_getDeveloper(JNIEnv* env, jobject obj, |
|
|
|
jstring jpath) { |
|
|
|
return Common::Android::ToJString( |
|
|
|
env, GetRomMetadata(Common::Android::GetJString(env, jpath)).developer); |
|
|
|
jstring Java_org_yuzu_yuzu_1emu_utils_GameMetadata_getDeveloper(JNIEnv* env, jobject obj, jstring jpath) { |
|
|
|
return Common::Android::ToJString(env, GetRomMetadata(Common::Android::GetJString(env, jpath)).developer); |
|
|
|
} |
|
|
|
|
|
|
|
jstring Java_org_yuzu_yuzu_1emu_utils_GameMetadata_getVersion(JNIEnv* env, jobject obj, |
|
|
|
jstring jpath, jboolean jreload) { |
|
|
|
return Common::Android::ToJString( |
|
|
|
env, GetRomMetadata(Common::Android::GetJString(env, jpath), jreload).version); |
|
|
|
jstring Java_org_yuzu_yuzu_1emu_utils_GameMetadata_getVersion(JNIEnv* env, jobject obj, jstring jpath, jboolean jreload) { |
|
|
|
return Common::Android::ToJString(env, GetRomMetadata(Common::Android::GetJString(env, jpath), jreload).version); |
|
|
|
} |
|
|
|
|
|
|
|
jbyteArray Java_org_yuzu_yuzu_1emu_utils_GameMetadata_getIcon(JNIEnv* env, jobject obj, |
|
|
|
jstring jpath) { |
|
|
|
jbyteArray Java_org_yuzu_yuzu_1emu_utils_GameMetadata_getIcon(JNIEnv* env, jobject obj, jstring jpath) { |
|
|
|
auto icon_data = GetRomMetadata(Common::Android::GetJString(env, jpath)).icon; |
|
|
|
jbyteArray icon = env->NewByteArray(static_cast<jsize>(icon_data.size())); |
|
|
|
env->SetByteArrayRegion(icon, 0, env->GetArrayLength(icon), |
|
|
|
reinterpret_cast<jbyte*>(icon_data.data())); |
|
|
|
jbyteArray icon = env->NewByteArray(jsize(icon_data.size())); |
|
|
|
env->SetByteArrayRegion(icon, 0, env->GetArrayLength(icon), reinterpret_cast<jbyte*>(icon_data.data())); |
|
|
|
return icon; |
|
|
|
} |
|
|
|
|
|
|
|
jboolean Java_org_yuzu_yuzu_1emu_utils_GameMetadata_getIsHomebrew(JNIEnv* env, jobject obj, |
|
|
|
jstring jpath) { |
|
|
|
return static_cast<jboolean>( |
|
|
|
GetRomMetadata(Common::Android::GetJString(env, jpath)).isHomebrew); |
|
|
|
jboolean Java_org_yuzu_yuzu_1emu_utils_GameMetadata_getIsHomebrew(JNIEnv* env, jobject obj, jstring jpath) { |
|
|
|
return jboolean(GetRomMetadata(Common::Android::GetJString(env, jpath)).isHomebrew); |
|
|
|
} |
|
|
|
|
|
|
|
void Java_org_yuzu_yuzu_1emu_utils_GameMetadata_resetMetadata(JNIEnv* env, jobject obj) { |
|
|
|
|