mirror of
				https://git.zaroz.cloud/nintendo-back-up/yuzu/yuzu.git
				synced 2025-05-12 00:45:25 +00:00 
			
		
		
		
	Loader, Frontends: Refactor loader creation and game loading
This allows frontends to keep a single loader and use it multiple times e.g. for code loading and SMDH parsing.
This commit is contained in:
		
							parent
							
								
									51ee2d2eb1
								
							
						
					
					
						commit
						8fc9c03126
					
				@ -114,7 +114,13 @@ int main(int argc, char **argv) {
 | 
			
		||||
    System::Init(emu_window.get());
 | 
			
		||||
    SCOPE_EXIT({ System::Shutdown(); });
 | 
			
		||||
 | 
			
		||||
    Loader::ResultStatus load_result = Loader::LoadFile(boot_filename);
 | 
			
		||||
    std::unique_ptr<Loader::AppLoader> loader = Loader::GetFileLoader(boot_filename);
 | 
			
		||||
    if (!loader) {
 | 
			
		||||
        LOG_CRITICAL(Frontend, "Failed to obtain loader for %s!", boot_filename.c_str());
 | 
			
		||||
        return -1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Loader::ResultStatus load_result = loader->Load();
 | 
			
		||||
    if (Loader::ResultStatus::Success != load_result) {
 | 
			
		||||
        LOG_CRITICAL(Frontend, "Failed to load ROM (Error %i)!", load_result);
 | 
			
		||||
        return -1;
 | 
			
		||||
 | 
			
		||||
@ -272,7 +272,15 @@ bool GMainWindow::InitializeSystem() {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool GMainWindow::LoadROM(const std::string& filename) {
 | 
			
		||||
    Loader::ResultStatus result = Loader::LoadFile(filename);
 | 
			
		||||
    std::unique_ptr<Loader::AppLoader> app_loader = Loader::GetFileLoader(filename);
 | 
			
		||||
    if (!app_loader) {
 | 
			
		||||
        LOG_CRITICAL(Frontend, "Failed to obtain loader for %s!", filename.c_str());
 | 
			
		||||
        QMessageBox::critical(this, tr("Error while loading ROM!"),
 | 
			
		||||
                              tr("The ROM format is not supported."));
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Loader::ResultStatus result = app_loader->Load();
 | 
			
		||||
    if (Loader::ResultStatus::Success != result) {
 | 
			
		||||
        LOG_CRITICAL(Frontend, "Failed to load ROM!");
 | 
			
		||||
        System::Shutdown();
 | 
			
		||||
 | 
			
		||||
@ -10,6 +10,7 @@
 | 
			
		||||
#include "core/file_sys/archive_romfs.h"
 | 
			
		||||
#include "core/hle/kernel/process.h"
 | 
			
		||||
#include "core/hle/kernel/resource_limit.h"
 | 
			
		||||
#include "core/hle/service/fs/archive.h"
 | 
			
		||||
#include "core/loader/3dsx.h"
 | 
			
		||||
#include "core/memory.h"
 | 
			
		||||
 | 
			
		||||
@ -263,6 +264,8 @@ ResultStatus AppLoader_THREEDSX::Load() {
 | 
			
		||||
 | 
			
		||||
    Kernel::g_current_process->Run(48, Kernel::DEFAULT_STACK_SIZE);
 | 
			
		||||
 | 
			
		||||
    Service::FS::RegisterArchiveType(std::make_unique<FileSys::ArchiveFactory_RomFS>(*this), Service::FS::ArchiveIdCode::RomFS);
 | 
			
		||||
 | 
			
		||||
    is_loaded = true;
 | 
			
		||||
    return ResultStatus::Success;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -8,9 +8,7 @@
 | 
			
		||||
#include "common/logging/log.h"
 | 
			
		||||
#include "common/string_util.h"
 | 
			
		||||
 | 
			
		||||
#include "core/file_sys/archive_romfs.h"
 | 
			
		||||
#include "core/hle/kernel/process.h"
 | 
			
		||||
#include "core/hle/service/fs/archive.h"
 | 
			
		||||
#include "core/loader/3dsx.h"
 | 
			
		||||
#include "core/loader/elf.h"
 | 
			
		||||
#include "core/loader/ncch.h"
 | 
			
		||||
@ -67,6 +65,9 @@ FileType GuessFromExtension(const std::string& extension_) {
 | 
			
		||||
    if (extension == ".3dsx")
 | 
			
		||||
        return FileType::THREEDSX;
 | 
			
		||||
 | 
			
		||||
    if (extension == ".cia")
 | 
			
		||||
        return FileType::CIA;
 | 
			
		||||
 | 
			
		||||
    return FileType::Unknown;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -108,15 +109,15 @@ std::unique_ptr<AppLoader> GetLoader(FileUtil::IOFile&& file, FileType type,
 | 
			
		||||
        return std::make_unique<AppLoader_NCCH>(std::move(file), filepath);
 | 
			
		||||
 | 
			
		||||
    default:
 | 
			
		||||
        return std::unique_ptr<AppLoader>();
 | 
			
		||||
        return nullptr;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ResultStatus LoadFile(const std::string& filename) {
 | 
			
		||||
std::unique_ptr<AppLoader> GetFileLoader(const std::string& filename) {
 | 
			
		||||
    FileUtil::IOFile file(filename, "rb");
 | 
			
		||||
    if (!file.IsOpen()) {
 | 
			
		||||
        LOG_ERROR(Loader, "Failed to load file %s", filename.c_str());
 | 
			
		||||
        return ResultStatus::Error;
 | 
			
		||||
        return nullptr;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    std::string filename_filename, filename_extension;
 | 
			
		||||
@ -133,44 +134,7 @@ ResultStatus LoadFile(const std::string& filename) {
 | 
			
		||||
 | 
			
		||||
    LOG_INFO(Loader, "Loading file %s as %s...", filename.c_str(), GetFileTypeString(type));
 | 
			
		||||
 | 
			
		||||
    std::unique_ptr<AppLoader> app_loader = GetLoader(std::move(file), type, filename_filename, filename);
 | 
			
		||||
 | 
			
		||||
    switch (type) {
 | 
			
		||||
 | 
			
		||||
    // 3DSX file format...
 | 
			
		||||
    // or NCCH/NCSD container formats...
 | 
			
		||||
    case FileType::THREEDSX:
 | 
			
		||||
    case FileType::CXI:
 | 
			
		||||
    case FileType::CCI:
 | 
			
		||||
    {
 | 
			
		||||
        // Load application and RomFS
 | 
			
		||||
        ResultStatus result = app_loader->Load();
 | 
			
		||||
        if (ResultStatus::Success == result) {
 | 
			
		||||
            Service::FS::RegisterArchiveType(std::make_unique<FileSys::ArchiveFactory_RomFS>(*app_loader), Service::FS::ArchiveIdCode::RomFS);
 | 
			
		||||
            return ResultStatus::Success;
 | 
			
		||||
        }
 | 
			
		||||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Standard ELF file format...
 | 
			
		||||
    case FileType::ELF:
 | 
			
		||||
        return app_loader->Load();
 | 
			
		||||
 | 
			
		||||
    // CIA file format...
 | 
			
		||||
    case FileType::CIA:
 | 
			
		||||
        return ResultStatus::ErrorNotImplemented;
 | 
			
		||||
 | 
			
		||||
    // Error occurred durring IdentifyFile...
 | 
			
		||||
    case FileType::Error:
 | 
			
		||||
 | 
			
		||||
    // IdentifyFile could know identify file type...
 | 
			
		||||
    case FileType::Unknown:
 | 
			
		||||
    {
 | 
			
		||||
        LOG_CRITICAL(Loader, "File %s is of unknown type.", filename.c_str());
 | 
			
		||||
        return ResultStatus::ErrorInvalidFormat;
 | 
			
		||||
    }
 | 
			
		||||
    }
 | 
			
		||||
    return ResultStatus::Error;
 | 
			
		||||
    return GetLoader(std::move(file), type, filename_filename, filename);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
} // namespace Loader
 | 
			
		||||
 | 
			
		||||
@ -207,10 +207,10 @@ extern const std::initializer_list<Kernel::AddressMapping> default_address_mappi
 | 
			
		||||
std::unique_ptr<AppLoader> GetLoader(FileUtil::IOFile&& file, FileType type, const std::string& filename, const std::string& filepath);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Identifies and loads a bootable file
 | 
			
		||||
 * Identifies a bootable file and return a suitable loader
 | 
			
		||||
 * @param filename String filename of bootable file
 | 
			
		||||
 * @return ResultStatus result of function
 | 
			
		||||
 * @return best loader for this file
 | 
			
		||||
 */
 | 
			
		||||
ResultStatus LoadFile(const std::string& filename);
 | 
			
		||||
std::unique_ptr<AppLoader> GetFileLoader(const std::string& filename);
 | 
			
		||||
 | 
			
		||||
} // namespace
 | 
			
		||||
 | 
			
		||||
@ -10,8 +10,10 @@
 | 
			
		||||
#include "common/string_util.h"
 | 
			
		||||
#include "common/swap.h"
 | 
			
		||||
 | 
			
		||||
#include "core/file_sys/archive_romfs.h"
 | 
			
		||||
#include "core/hle/kernel/process.h"
 | 
			
		||||
#include "core/hle/kernel/resource_limit.h"
 | 
			
		||||
#include "core/hle/service/fs/archive.h"
 | 
			
		||||
#include "core/loader/ncch.h"
 | 
			
		||||
#include "core/memory.h"
 | 
			
		||||
 | 
			
		||||
@ -303,7 +305,12 @@ ResultStatus AppLoader_NCCH::Load() {
 | 
			
		||||
 | 
			
		||||
    is_loaded = true; // Set state to loaded
 | 
			
		||||
 | 
			
		||||
    return LoadExec(); // Load the executable into memory for booting
 | 
			
		||||
    result = LoadExec(); // Load the executable into memory for booting
 | 
			
		||||
    if (ResultStatus::Success != result)
 | 
			
		||||
        return result;
 | 
			
		||||
 | 
			
		||||
    Service::FS::RegisterArchiveType(std::make_unique<FileSys::ArchiveFactory_RomFS>(*this), Service::FS::ArchiveIdCode::RomFS);
 | 
			
		||||
    return ResultStatus::Success;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ResultStatus AppLoader_NCCH::ReadCode(std::vector<u8>& buffer) {
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user