mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-31 05:40:04 +00:00 
			
		
		
		
	core: Detect and return error if GBA virtual console is loaded. (#6257)
This commit is contained in:
		
							parent
							
								
									d704c6a3ac
								
							
						
					
					
						commit
						84e54a52a6
					
				
					 6 changed files with 33 additions and 6 deletions
				
			
		|  | @ -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…
	
	Add table
		Add a link
		
	
		Reference in a new issue