mirror of
https://github.com/azahar-emu/azahar
synced 2025-11-06 15:09:58 +01:00
Z3DS: Mark compressed files in UI and other minor fixes (#1249)
This commit is contained in:
parent
c95b942ec2
commit
25d7db7bbe
@ -343,8 +343,9 @@ class GameAdapter(private val activity: AppCompatActivity, private val inflater:
|
||||
bottomSheetView.findViewById<TextView>(R.id.about_game_title).text = game.title
|
||||
bottomSheetView.findViewById<TextView>(R.id.about_game_company).text = game.company
|
||||
bottomSheetView.findViewById<TextView>(R.id.about_game_region).text = game.regions
|
||||
bottomSheetView.findViewById<TextView>(R.id.about_game_id).text = "ID: " + String.format("%016X", game.titleId)
|
||||
bottomSheetView.findViewById<TextView>(R.id.about_game_filename).text = "File: " + game.filename
|
||||
bottomSheetView.findViewById<TextView>(R.id.about_game_id).text = context.getString(R.string.game_context_id) + " " + String.format("%016X", game.titleId)
|
||||
bottomSheetView.findViewById<TextView>(R.id.about_game_filename).text = context.getString(R.string.game_context_file) + " " + game.filename
|
||||
bottomSheetView.findViewById<TextView>(R.id.about_game_filetype).text = context.getString(R.string.game_context_type) + " " + game.fileType
|
||||
GameIconUtils.loadGameIcon(activity, game, bottomSheetView.findViewById(R.id.game_icon))
|
||||
|
||||
bottomSheetView.findViewById<MaterialButton>(R.id.about_game_play).setOnClickListener {
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
// Copyright Citra Emulator Project / Lime3DS Emulator Project
|
||||
// Copyright Citra Emulator Project / Azahar Emulator Project
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
@ -26,7 +26,8 @@ class Game(
|
||||
val isSystemTitle: Boolean = false,
|
||||
val isVisibleSystemTitle: Boolean = false,
|
||||
val icon: IntArray? = null,
|
||||
val filename: String
|
||||
val fileType: String = "",
|
||||
val filename: String,
|
||||
) : Parcelable {
|
||||
val keyAddedToLibraryTime get() = "${filename}_AddedToLibraryTime"
|
||||
val keyLastPlayedTime get() = "${filename}_LastPlayed"
|
||||
|
||||
@ -13,25 +13,30 @@ class GameInfo(path: String) {
|
||||
|
||||
init {
|
||||
pointer = initialize(path)
|
||||
if (pointer == 0L) {
|
||||
throw IOException()
|
||||
}
|
||||
}
|
||||
|
||||
protected external fun finalize()
|
||||
|
||||
external fun getTitle(): String
|
||||
|
||||
external fun isValid(): Boolean
|
||||
|
||||
external fun isEncrypted(): Boolean
|
||||
|
||||
external fun getTitleID(): Long
|
||||
|
||||
external fun getRegions(): String
|
||||
|
||||
external fun getCompany(): String
|
||||
|
||||
external fun getIcon(): IntArray?
|
||||
|
||||
external fun isSystemTitle(): Boolean
|
||||
|
||||
external fun getIsVisibleSystemTitle(): Boolean
|
||||
|
||||
external fun getFileType(): String
|
||||
|
||||
companion object {
|
||||
@JvmStatic
|
||||
private external fun initialize(path: String): Long
|
||||
|
||||
@ -70,29 +70,26 @@ object GameHelper {
|
||||
|
||||
fun getGame(uri: Uri, isInstalled: Boolean, addedToLibrary: Boolean): Game {
|
||||
val filePath = uri.toString()
|
||||
var gameInfo: GameInfo? = try {
|
||||
GameInfo(filePath)
|
||||
} catch (e: IOException) {
|
||||
null
|
||||
var gameInfo: GameInfo? = GameInfo(filePath)
|
||||
|
||||
if (gameInfo?.isValid() == false) {
|
||||
gameInfo = null
|
||||
}
|
||||
|
||||
var isEncrypted = false
|
||||
if (gameInfo?.isEncrypted() == true) {
|
||||
gameInfo = null
|
||||
isEncrypted = true
|
||||
}
|
||||
val isEncrypted = gameInfo?.isEncrypted() == true
|
||||
|
||||
val newGame = Game(
|
||||
(gameInfo?.getTitle() ?: FileUtil.getFilename(uri)).replace("[\\t\\n\\r]+".toRegex(), " "),
|
||||
filePath.replace("\n", " "),
|
||||
filePath,
|
||||
NativeLibrary.getTitleId(filePath),
|
||||
gameInfo?.getTitleID() ?: 0,
|
||||
gameInfo?.getCompany() ?: "",
|
||||
gameInfo?.getRegions() ?: (if (isEncrypted) { CitraApplication.appContext.getString(R.string.unsupported_encrypted) } else { CitraApplication.appContext.getString(R.string.invalid_region) }),
|
||||
if (isEncrypted) { CitraApplication.appContext.getString(R.string.unsupported_encrypted) } else { gameInfo?.getRegions() ?: "" },
|
||||
isInstalled,
|
||||
NativeLibrary.getIsSystemTitle(filePath),
|
||||
gameInfo?.isSystemTitle() ?: false,
|
||||
gameInfo?.getIsVisibleSystemTitle() ?: false,
|
||||
gameInfo?.getIcon(),
|
||||
gameInfo?.getFileType() ?: "",
|
||||
if (FileUtil.isNativePath(filePath)) {
|
||||
CitraApplication.documentsTree.getFilename(filePath)
|
||||
} else {
|
||||
|
||||
@ -17,28 +17,41 @@
|
||||
|
||||
namespace {
|
||||
|
||||
std::vector<u8> GetSMDHData(const std::string& path, bool& is_encrypted) {
|
||||
std::unique_ptr<Loader::AppLoader> loader = Loader::GetLoader(path);
|
||||
if (!loader) {
|
||||
return {};
|
||||
}
|
||||
static constexpr u64 UPDATE_TID_HIGH = 0x0004000e00000000;
|
||||
|
||||
struct GameInfoData {
|
||||
Loader::SMDH smdh;
|
||||
u64 title_id = 0;
|
||||
bool loaded = false;
|
||||
bool is_encrypted = false;
|
||||
std::string file_type = "";
|
||||
};
|
||||
|
||||
GameInfoData* GetNewGameInfoData(const std::string& path) {
|
||||
std::unique_ptr<Loader::AppLoader> loader = Loader::GetLoader(path);
|
||||
u64 program_id = 0;
|
||||
loader->ReadProgramId(program_id);
|
||||
bool is_encrypted = false;
|
||||
|
||||
if (!loader || loader->ReadProgramId(program_id) != Loader::ResultStatus::Success) {
|
||||
GameInfoData* gid = new GameInfoData();
|
||||
memset(&gid->smdh, 0, sizeof(Loader::SMDH));
|
||||
return gid;
|
||||
}
|
||||
|
||||
std::vector<u8> smdh = [program_id, &loader, &is_encrypted]() -> std::vector<u8> {
|
||||
std::vector<u8> original_smdh;
|
||||
auto result = loader->ReadIcon(original_smdh);
|
||||
if (result == Loader::ResultStatus::ErrorEncrypted) {
|
||||
is_encrypted = true;
|
||||
return original_smdh;
|
||||
if (result != Loader::ResultStatus::Success) {
|
||||
is_encrypted = result == Loader::ResultStatus::ErrorEncrypted;
|
||||
return {};
|
||||
}
|
||||
|
||||
if (program_id < 0x00040000'00000000 || program_id > 0x00040000'FFFFFFFF)
|
||||
return original_smdh;
|
||||
|
||||
std::string update_path = Service::AM::GetTitleContentPath(
|
||||
Service::FS::MediaType::SDMC, program_id + 0x0000000E'00000000);
|
||||
u64 update_tid = (program_id & 0xFFFFFFFFULL) | UPDATE_TID_HIGH;
|
||||
std::string update_path =
|
||||
Service::AM::GetTitleContentPath(Service::FS::MediaType::SDMC, update_tid);
|
||||
|
||||
if (!FileUtil::Exists(update_path))
|
||||
return original_smdh;
|
||||
@ -49,41 +62,50 @@ std::vector<u8> GetSMDHData(const std::string& path, bool& is_encrypted) {
|
||||
return original_smdh;
|
||||
|
||||
std::vector<u8> update_smdh;
|
||||
update_loader->ReadIcon(update_smdh);
|
||||
result = update_loader->ReadIcon(update_smdh);
|
||||
if (result != Loader::ResultStatus::Success) {
|
||||
is_encrypted = result == Loader::ResultStatus::ErrorEncrypted;
|
||||
return {};
|
||||
}
|
||||
return update_smdh;
|
||||
}();
|
||||
|
||||
return smdh;
|
||||
GameInfoData* gid = new GameInfoData();
|
||||
if (smdh.empty()) {
|
||||
std::memset(&gid->smdh, 0, sizeof(Loader::SMDH));
|
||||
} else {
|
||||
std::memcpy(&gid->smdh, smdh.data(), smdh.size());
|
||||
}
|
||||
gid->loaded = true;
|
||||
gid->is_encrypted = is_encrypted;
|
||||
gid->title_id = program_id;
|
||||
gid->file_type = Loader::GetFileTypeString(loader->GetFileType(), loader->IsFileCompressed());
|
||||
|
||||
return gid;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
extern "C" {
|
||||
|
||||
static Loader::SMDH* GetPointer(JNIEnv* env, jobject obj) {
|
||||
return reinterpret_cast<Loader::SMDH*>(env->GetLongField(obj, IDCache::GetGameInfoPointer()));
|
||||
static GameInfoData* GetPointer(JNIEnv* env, jobject obj) {
|
||||
return reinterpret_cast<GameInfoData*>(env->GetLongField(obj, IDCache::GetGameInfoPointer()));
|
||||
}
|
||||
|
||||
JNIEXPORT jlong JNICALL Java_org_citra_citra_1emu_model_GameInfo_initialize(JNIEnv* env, jclass,
|
||||
jstring j_path) {
|
||||
bool is_encrypted = false;
|
||||
std::vector<u8> smdh_data = GetSMDHData(GetJString(env, j_path), is_encrypted);
|
||||
GameInfoData* game_info_data = GetNewGameInfoData(GetJString(env, j_path));
|
||||
return reinterpret_cast<jlong>(game_info_data);
|
||||
}
|
||||
|
||||
Loader::SMDH* smdh = nullptr;
|
||||
if (is_encrypted) {
|
||||
smdh = new Loader::SMDH;
|
||||
smdh->magic = 0xDEADDEAD;
|
||||
} else if (Loader::IsValidSMDH(smdh_data)) {
|
||||
smdh = new Loader::SMDH;
|
||||
std::memcpy(smdh, smdh_data.data(), sizeof(Loader::SMDH));
|
||||
}
|
||||
return reinterpret_cast<jlong>(smdh);
|
||||
JNIEXPORT jboolean JNICALL Java_org_citra_citra_1emu_model_GameInfo_isValid(JNIEnv* env,
|
||||
jobject obj) {
|
||||
return GetPointer(env, obj)->loaded;
|
||||
}
|
||||
|
||||
JNIEXPORT jboolean JNICALL Java_org_citra_citra_1emu_model_GameInfo_isEncrypted(JNIEnv* env,
|
||||
jobject obj) {
|
||||
Loader::SMDH* smdh = GetPointer(env, obj);
|
||||
return smdh->magic == 0xDEADDEAD;
|
||||
return GetPointer(env, obj)->is_encrypted;
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_org_citra_citra_1emu_model_GameInfo_finalize(JNIEnv* env, jobject obj) {
|
||||
@ -91,7 +113,11 @@ JNIEXPORT void JNICALL Java_org_citra_citra_1emu_model_GameInfo_finalize(JNIEnv*
|
||||
}
|
||||
|
||||
jstring Java_org_citra_citra_1emu_model_GameInfo_getTitle(JNIEnv* env, jobject obj) {
|
||||
Loader::SMDH* smdh = GetPointer(env, obj);
|
||||
Loader::SMDH* smdh = &GetPointer(env, obj)->smdh;
|
||||
if (!smdh->IsValid()) {
|
||||
return ToJString(env, "");
|
||||
}
|
||||
|
||||
Loader::SMDH::TitleLanguage language = Loader::SMDH::TitleLanguage::English;
|
||||
|
||||
// Get the title from SMDH in UTF-16 format
|
||||
@ -102,7 +128,11 @@ jstring Java_org_citra_citra_1emu_model_GameInfo_getTitle(JNIEnv* env, jobject o
|
||||
}
|
||||
|
||||
jstring Java_org_citra_citra_1emu_model_GameInfo_getCompany(JNIEnv* env, jobject obj) {
|
||||
Loader::SMDH* smdh = GetPointer(env, obj);
|
||||
Loader::SMDH* smdh = &GetPointer(env, obj)->smdh;
|
||||
if (!smdh->IsValid()) {
|
||||
return ToJString(env, "");
|
||||
}
|
||||
|
||||
Loader::SMDH::TitleLanguage language = Loader::SMDH::TitleLanguage::English;
|
||||
|
||||
// Get the Publisher's name from SMDH in UTF-16 format
|
||||
@ -113,8 +143,15 @@ jstring Java_org_citra_citra_1emu_model_GameInfo_getCompany(JNIEnv* env, jobject
|
||||
return ToJString(env, Common::UTF16ToUTF8(publisher).data());
|
||||
}
|
||||
|
||||
jlong Java_org_citra_citra_1emu_model_GameInfo_getTitleID(JNIEnv* env, jobject obj) {
|
||||
return static_cast<jlong>(GetPointer(env, obj)->title_id);
|
||||
}
|
||||
|
||||
jstring Java_org_citra_citra_1emu_model_GameInfo_getRegions(JNIEnv* env, jobject obj) {
|
||||
Loader::SMDH* smdh = GetPointer(env, obj);
|
||||
Loader::SMDH* smdh = &GetPointer(env, obj)->smdh;
|
||||
if (!smdh->IsValid()) {
|
||||
return ToJString(env, "");
|
||||
}
|
||||
|
||||
using GameRegion = Loader::SMDH::GameRegion;
|
||||
static const std::map<GameRegion, const char*> regions_map = {
|
||||
@ -147,7 +184,10 @@ jstring Java_org_citra_citra_1emu_model_GameInfo_getRegions(JNIEnv* env, jobject
|
||||
}
|
||||
|
||||
jintArray Java_org_citra_citra_1emu_model_GameInfo_getIcon(JNIEnv* env, jobject obj) {
|
||||
Loader::SMDH* smdh = GetPointer(env, obj);
|
||||
Loader::SMDH* smdh = &GetPointer(env, obj)->smdh;
|
||||
if (!smdh->IsValid()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Always get a 48x48(large) icon
|
||||
std::vector<u16> icon_data = smdh->GetIcon(true);
|
||||
@ -162,12 +202,23 @@ jintArray Java_org_citra_citra_1emu_model_GameInfo_getIcon(JNIEnv* env, jobject
|
||||
return icon;
|
||||
}
|
||||
|
||||
jboolean Java_org_citra_citra_1emu_model_GameInfo_isSystemTitle(JNIEnv* env, jobject obj) {
|
||||
return ((GetPointer(env, obj)->title_id >> 32) & 0xFFFFFFFF) == 0x00040010;
|
||||
}
|
||||
|
||||
jboolean Java_org_citra_citra_1emu_model_GameInfo_getIsVisibleSystemTitle(JNIEnv* env,
|
||||
jobject obj) {
|
||||
Loader::SMDH* smdh = GetPointer(env, obj);
|
||||
if (smdh == nullptr) {
|
||||
Loader::SMDH* smdh = &GetPointer(env, obj)->smdh;
|
||||
if (!smdh->IsValid()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return smdh->flags & Loader::SMDH::Flags::Visible;
|
||||
}
|
||||
|
||||
jstring Java_org_citra_citra_1emu_model_GameInfo_getFileType(JNIEnv* env, jobject obj) {
|
||||
std::string& file_type = GetPointer(env, obj)->file_type;
|
||||
|
||||
return ToJString(env, file_type);
|
||||
}
|
||||
}
|
||||
|
||||
@ -86,12 +86,21 @@
|
||||
tools:text="Application Filename" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/about_game_playtime"
|
||||
android:id="@+id/about_game_filetype"
|
||||
style="?attr/textAppearanceBodyMedium"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintStart_toStartOf="@id/about_game_title"
|
||||
app:layout_constraintTop_toBottomOf="@+id/about_game_filename"
|
||||
tools:text="Game Filetype" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/about_game_playtime"
|
||||
style="?attr/textAppearanceBodyMedium"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintStart_toStartOf="@id/about_game_title"
|
||||
app:layout_constraintTop_toBottomOf="@+id/about_game_filetype"
|
||||
tools:text="Game Playtime" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
@ -539,7 +539,6 @@
|
||||
<string name="save_load_error">Save/Load Error</string>
|
||||
<string name="fatal_error">Fatal Error</string>
|
||||
<string name="fatal_error_message">A fatal error occurred. Check the log for details.\nContinuing emulation may result in crashes and bugs.</string>
|
||||
<string name="invalid_region">Invalid region</string>
|
||||
<string name="unsupported_encrypted">Unsupported encrypted application</string>
|
||||
|
||||
<!-- Disk Shader Cache -->
|
||||
@ -565,6 +564,9 @@
|
||||
<string name="create_shortcut">Create Shortcut</string>
|
||||
<string name="shortcut_name_empty">Shortcut name cannot be empty</string>
|
||||
<string name="shortcut_image_stretch_toggle">Stretch to fit image</string>
|
||||
<string name="game_context_id">ID:</string>
|
||||
<string name="game_context_file">File:</string>
|
||||
<string name="game_context_type">Type:</string>
|
||||
|
||||
<!-- Performance Overlay settings -->
|
||||
<string name="performance_overlay_show">Show Performance Overlay</string>
|
||||
|
||||
@ -173,8 +173,8 @@ void ConfigurePerGame::LoadConfiguration() {
|
||||
|
||||
ui->display_filepath->setText(QString::fromStdString(filename));
|
||||
|
||||
ui->display_format->setText(
|
||||
QString::fromStdString(Loader::GetFileTypeString(loader->GetFileType())));
|
||||
ui->display_format->setText(QString::fromStdString(
|
||||
Loader::GetFileTypeString(loader->GetFileType(), loader->IsFileCompressed())));
|
||||
|
||||
const auto valueText = ReadableByteSize(FileUtil::GetSize(filename));
|
||||
ui->display_size->setText(valueText);
|
||||
|
||||
@ -1,3 +1,7 @@
|
||||
// Copyright Citra Emulator Project / Azahar Emulator Project
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
// Copyright 2018 yuzu emulator team
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
@ -112,8 +116,8 @@ void GameListWorker::AddFstEntriesToGameList(const std::string& dir_path, unsign
|
||||
res == Loader::ResultStatus::ErrorEncrypted),
|
||||
new GameListItemCompat(compatibility),
|
||||
new GameListItemRegion(smdh),
|
||||
new GameListItem(
|
||||
QString::fromStdString(Loader::GetFileTypeString(loader->GetFileType()))),
|
||||
new GameListItem(QString::fromStdString(Loader::GetFileTypeString(
|
||||
loader->GetFileType(), loader->IsFileCompressed()))),
|
||||
new GameListItemSize(FileUtil::GetSize(physical_name)),
|
||||
new GameListItemPlayTime(play_time_manager.GetPlayTime(program_id)),
|
||||
},
|
||||
|
||||
@ -346,6 +346,10 @@ AppLoader::CompressFileInfo AppLoader_THREEDSX::GetCompressFileInfo() {
|
||||
return info;
|
||||
}
|
||||
|
||||
bool AppLoader_THREEDSX::IsFileCompressed() {
|
||||
return FileUtil::Z3DSReadIOFile::GetUnderlyingFileMagic(file.get()) != std::nullopt;
|
||||
}
|
||||
|
||||
ResultStatus AppLoader_THREEDSX::ReadIcon(std::vector<u8>& buffer) {
|
||||
if (!file->IsOpen())
|
||||
return ResultStatus::Error;
|
||||
|
||||
@ -41,6 +41,8 @@ public:
|
||||
|
||||
CompressFileInfo GetCompressFileInfo() override;
|
||||
|
||||
bool IsFileCompressed() override;
|
||||
|
||||
private:
|
||||
std::string filename;
|
||||
std::string filepath;
|
||||
|
||||
@ -63,18 +63,18 @@ FileType GuessFromExtension(const std::string& extension_) {
|
||||
return FileType::Unknown;
|
||||
}
|
||||
|
||||
const char* GetFileTypeString(FileType type) {
|
||||
const char* GetFileTypeString(FileType type, bool is_compressed) {
|
||||
switch (type) {
|
||||
case FileType::CCI:
|
||||
return "NCSD";
|
||||
return is_compressed ? "NCSD (Z)" : "NCSD";
|
||||
case FileType::CXI:
|
||||
return "NCCH";
|
||||
return is_compressed ? "NCCH (Z)" : "NCCH";
|
||||
case FileType::CIA:
|
||||
return "CIA";
|
||||
return is_compressed ? "CIA (Z)" : "CIA";
|
||||
case FileType::ELF:
|
||||
return "ELF";
|
||||
case FileType::THREEDSX:
|
||||
return "3DSX";
|
||||
return is_compressed ? "3DSX (Z)" : "3DSX";
|
||||
case FileType::ARTIC:
|
||||
return "ARTIC";
|
||||
case FileType::Error:
|
||||
|
||||
@ -60,7 +60,7 @@ FileType GuessFromExtension(const std::string& extension);
|
||||
/**
|
||||
* Convert a FileType into a string which can be displayed to the user.
|
||||
*/
|
||||
const char* GetFileTypeString(FileType type);
|
||||
const char* GetFileTypeString(FileType type, bool is_compressed = false);
|
||||
|
||||
/// Return type for functions in Loader namespace
|
||||
enum class ResultStatus {
|
||||
@ -294,6 +294,10 @@ public:
|
||||
return info;
|
||||
}
|
||||
|
||||
virtual bool IsFileCompressed() {
|
||||
return false;
|
||||
}
|
||||
|
||||
protected:
|
||||
Core::System& system;
|
||||
std::unique_ptr<FileUtil::IOFile> file;
|
||||
|
||||
@ -60,9 +60,12 @@ FileType AppLoader_NCCH::IdentifyType(FileUtil::IOFile* file) {
|
||||
if (MakeMagic('N', 'C', 'C', 'H') == magic)
|
||||
return FileType::CXI;
|
||||
|
||||
std::optional<u32> magic_zstd;
|
||||
if (FileUtil::Z3DSReadIOFile::GetUnderlyingFileMagic(file) != std::nullopt ||
|
||||
FileUtil::Z3DSReadIOFile::GetUnderlyingFileMagic(file_crypto.get()) != std::nullopt) {
|
||||
std::optional<u32> magic_zstd = FileUtil::Z3DSReadIOFile::GetUnderlyingFileMagic(file);
|
||||
if (!magic_zstd.has_value()) {
|
||||
magic_zstd = FileUtil::Z3DSReadIOFile::GetUnderlyingFileMagic(file_crypto.get());
|
||||
}
|
||||
|
||||
if (magic_zstd.has_value()) {
|
||||
if (MakeMagic('N', 'C', 'S', 'D') == magic_zstd)
|
||||
return FileType::CCI;
|
||||
|
||||
@ -437,4 +440,11 @@ AppLoader::CompressFileInfo AppLoader_NCCH::GetCompressFileInfo() {
|
||||
return info;
|
||||
}
|
||||
|
||||
bool AppLoader_NCCH::IsFileCompressed() {
|
||||
if (base_ncch.LoadHeader() != ResultStatus::Success) {
|
||||
return false;
|
||||
}
|
||||
return base_ncch.IsFileCompressed();
|
||||
}
|
||||
|
||||
} // namespace Loader
|
||||
|
||||
@ -76,6 +76,8 @@ public:
|
||||
|
||||
CompressFileInfo GetCompressFileInfo() override;
|
||||
|
||||
bool IsFileCompressed() override;
|
||||
|
||||
private:
|
||||
/**
|
||||
* Loads .code section into memory for booting
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user