mirror of
				https://git.h3cjp.net/H3cJP/citra.git
				synced 2025-11-04 09:05:08 +00:00 
			
		
		
		
	core: Detect and return error if GBA virtual console is loaded. (#6257)
This commit is contained in:
		
							parent
							
								
									d704c6a3ac
								
							
						
					
					
						commit
						84e54a52a6
					
				| 
						 | 
				
			
			@ -1015,6 +1015,11 @@ bool GMainWindow::LoadROM(const QString& filename) {
 | 
			
		|||
                   "titles</a>."));
 | 
			
		||||
            break;
 | 
			
		||||
 | 
			
		||||
        case Core::System::ResultStatus::ErrorLoader_ErrorGbaTitle:
 | 
			
		||||
            QMessageBox::critical(this, tr("Unsupported ROM"),
 | 
			
		||||
                                  tr("GBA Virtual Console ROMs are not supported by Citra."));
 | 
			
		||||
            break;
 | 
			
		||||
 | 
			
		||||
        case Core::System::ResultStatus::ErrorVideoCore:
 | 
			
		||||
            QMessageBox::critical(
 | 
			
		||||
                this, tr("Video Core Error"),
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -268,6 +268,8 @@ System::ResultStatus System::Load(Frontend::EmuWindow& emu_window, const std::st
 | 
			
		|||
            return ResultStatus::ErrorLoader_ErrorEncrypted;
 | 
			
		||||
        case Loader::ResultStatus::ErrorInvalidFormat:
 | 
			
		||||
            return ResultStatus::ErrorLoader_ErrorInvalidFormat;
 | 
			
		||||
        case Loader::ResultStatus::ErrorGbaTitle:
 | 
			
		||||
            return ResultStatus::ErrorLoader_ErrorGbaTitle;
 | 
			
		||||
        default:
 | 
			
		||||
            return ResultStatus::ErrorSystemMode;
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			@ -292,7 +294,6 @@ System::ResultStatus System::Load(Frontend::EmuWindow& emu_window, const std::st
 | 
			
		|||
    telemetry_session->AddInitialInfo(*app_loader);
 | 
			
		||||
    std::shared_ptr<Kernel::Process> process;
 | 
			
		||||
    const Loader::ResultStatus load_result{app_loader->Load(process)};
 | 
			
		||||
    kernel->SetCurrentProcess(process);
 | 
			
		||||
    if (Loader::ResultStatus::Success != load_result) {
 | 
			
		||||
        LOG_CRITICAL(Core, "Failed to load ROM (Error {})!", load_result);
 | 
			
		||||
        System::Shutdown();
 | 
			
		||||
| 
						 | 
				
			
			@ -302,10 +303,13 @@ System::ResultStatus System::Load(Frontend::EmuWindow& emu_window, const std::st
 | 
			
		|||
            return ResultStatus::ErrorLoader_ErrorEncrypted;
 | 
			
		||||
        case Loader::ResultStatus::ErrorInvalidFormat:
 | 
			
		||||
            return ResultStatus::ErrorLoader_ErrorInvalidFormat;
 | 
			
		||||
        case Loader::ResultStatus::ErrorGbaTitle:
 | 
			
		||||
            return ResultStatus::ErrorLoader_ErrorGbaTitle;
 | 
			
		||||
        default:
 | 
			
		||||
            return ResultStatus::ErrorLoader;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    kernel->SetCurrentProcess(process);
 | 
			
		||||
    cheat_engine = std::make_unique<Cheats::CheatEngine>(*this);
 | 
			
		||||
    title_id = 0;
 | 
			
		||||
    if (app_loader->ReadProgramId(title_id) != Loader::ResultStatus::Success) {
 | 
			
		||||
| 
						 | 
				
			
			@ -539,7 +543,8 @@ void System::Shutdown(bool is_deserializing) {
 | 
			
		|||
                                perf_results.emulation_speed * 100.0);
 | 
			
		||||
    telemetry_session->AddField(performance, "Shutdown_Framerate", perf_results.game_fps);
 | 
			
		||||
    telemetry_session->AddField(performance, "Shutdown_Frametime", perf_results.frametime * 1000.0);
 | 
			
		||||
    telemetry_session->AddField(performance, "Mean_Frametime_MS", perf_stats->GetMeanFrametime());
 | 
			
		||||
    telemetry_session->AddField(performance, "Mean_Frametime_MS",
 | 
			
		||||
                                perf_stats ? perf_stats->GetMeanFrametime() : 0);
 | 
			
		||||
 | 
			
		||||
    // Shutdown emulation session
 | 
			
		||||
    VideoCore::Shutdown();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -82,10 +82,12 @@ public:
 | 
			
		|||
        ErrorSystemMode,            ///< Error determining the system mode
 | 
			
		||||
        ErrorLoader,                ///< Error loading the specified application
 | 
			
		||||
        ErrorLoader_ErrorEncrypted, ///< Error loading the specified application due to encryption
 | 
			
		||||
        ErrorLoader_ErrorInvalidFormat,     ///< Error loading the specified application due to an
 | 
			
		||||
                                            /// invalid format
 | 
			
		||||
        ErrorSystemFiles,                   ///< Error in finding system files
 | 
			
		||||
        ErrorVideoCore,                     ///< Error in the video core
 | 
			
		||||
        ErrorLoader_ErrorInvalidFormat, ///< Error loading the specified application due to an
 | 
			
		||||
                                        /// invalid format
 | 
			
		||||
        ErrorLoader_ErrorGbaTitle, ///< Error loading the specified application as it is GBA Virtual
 | 
			
		||||
                                   ///< Console
 | 
			
		||||
        ErrorSystemFiles,          ///< Error in finding system files
 | 
			
		||||
        ErrorVideoCore,            ///< Error in the video core
 | 
			
		||||
        ErrorVideoCore_ErrorGenericDrivers, ///< Error in the video core due to the user having
 | 
			
		||||
                                            /// generic drivers installed
 | 
			
		||||
        ErrorVideoCore_ErrorBelowGL43,      ///< Error in the video core due to the user not having
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -75,6 +75,7 @@ enum class ResultStatus {
 | 
			
		|||
    ErrorAlreadyLoaded,
 | 
			
		||||
    ErrorMemoryAllocationFailed,
 | 
			
		||||
    ErrorEncrypted,
 | 
			
		||||
    ErrorGbaTitle,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
constexpr u32 MakeMagic(char a, char b, char c, char d) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -85,6 +85,11 @@ ResultStatus AppLoader_NCCH::LoadExec(std::shared_ptr<Kernel::Process>& process)
 | 
			
		|||
    u64_le program_id;
 | 
			
		||||
    if (ResultStatus::Success == ReadCode(code) &&
 | 
			
		||||
        ResultStatus::Success == ReadProgramId(program_id)) {
 | 
			
		||||
        if (IsGbaVirtualConsole(code)) {
 | 
			
		||||
            LOG_ERROR(Loader, "Encountered unsupported GBA Virtual Console code section.");
 | 
			
		||||
            return ResultStatus::ErrorGbaTitle;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        std::string process_name = Common::StringFromFixedZeroTerminatedBuffer(
 | 
			
		||||
            (const char*)overlay_ncch->exheader_header.codeset_info.name, 8);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -177,6 +182,12 @@ void AppLoader_NCCH::ParseRegionLockoutInfo() {
 | 
			
		|||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool AppLoader_NCCH::IsGbaVirtualConsole(const std::vector<u8>& code) {
 | 
			
		||||
    const u32* gbaVcHeader = reinterpret_cast<const u32*>(code.data() + code.size() - 0x10);
 | 
			
		||||
    return code.size() >= 0x10 && gbaVcHeader[0] == MakeMagic('.', 'C', 'A', 'A') &&
 | 
			
		||||
           gbaVcHeader[1] == 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ResultStatus AppLoader_NCCH::Load(std::shared_ptr<Kernel::Process>& process) {
 | 
			
		||||
    u64_le ncch_program_id;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -78,6 +78,9 @@ private:
 | 
			
		|||
    /// Reads the region lockout info in the SMDH and send it to CFG service
 | 
			
		||||
    void ParseRegionLockoutInfo();
 | 
			
		||||
 | 
			
		||||
    /// Detects whether the NCCH contains GBA Virtual Console.
 | 
			
		||||
    bool IsGbaVirtualConsole(const std::vector<u8>& code);
 | 
			
		||||
 | 
			
		||||
    FileSys::NCCHContainer base_ncch;
 | 
			
		||||
    FileSys::NCCHContainer update_ncch;
 | 
			
		||||
    FileSys::NCCHContainer* overlay_ncch;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue