mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-31 13:50:03 +00:00 
			
		
		
		
	Merge pull request #1520 from JamePeng/checknew3ds
Implement CheckNew3DS and CheckNew3DSApp
This commit is contained in:
		
						commit
						2e5e7d9be0
					
				
					 11 changed files with 145 additions and 14 deletions
				
			
		|  | @ -14,6 +14,7 @@ | |||
| #include "core/hle/service/apt/apt_u.h" | ||||
| #include "core/hle/service/apt/bcfnt/bcfnt.h" | ||||
| #include "core/hle/service/fs/archive.h" | ||||
| #include "core/hle/service/ptm/ptm.h" | ||||
| 
 | ||||
| #include "core/hle/kernel/event.h" | ||||
| #include "core/hle/kernel/mutex.h" | ||||
|  | @ -33,6 +34,9 @@ static Kernel::SharedPtr<Kernel::Event> parameter_event; ///< APT parameter even | |||
| 
 | ||||
| static u32 cpu_percent; ///< CPU time available to the running application
 | ||||
| 
 | ||||
| // APT::CheckNew3DSApp will check this unknown_ns_state_field to determine processing mode
 | ||||
| static u8 unknown_ns_state_field; | ||||
| 
 | ||||
| /// Parameter data to be returned in the next call to Glance/ReceiveParameter
 | ||||
| static MessageParameter next_parameter; | ||||
| 
 | ||||
|  | @ -258,6 +262,10 @@ void PrepareToStartApplication(Service::Interface* self) { | |||
|     u32 title_info4  = cmd_buff[4]; | ||||
|     u32 flags        = cmd_buff[5]; | ||||
| 
 | ||||
|     if (flags & 0x00000100) { | ||||
|         unknown_ns_state_field = 1; | ||||
|     } | ||||
| 
 | ||||
|     cmd_buff[1] = RESULT_SUCCESS.raw; // No error
 | ||||
| 
 | ||||
|     LOG_WARNING(Service_APT, "(STUBBED) called title_info1=0x%08X, title_info2=0x%08X, title_info3=0x%08X," | ||||
|  | @ -373,6 +381,25 @@ void StartLibraryApplet(Service::Interface* self) { | |||
|     cmd_buff[1] = applet->Start(parameter).raw; | ||||
| } | ||||
| 
 | ||||
| void SetNSStateField(Service::Interface* self) { | ||||
|     u32* cmd_buff = Kernel::GetCommandBuffer(); | ||||
| 
 | ||||
|     unknown_ns_state_field = cmd_buff[1]; | ||||
| 
 | ||||
|     cmd_buff[0] = IPC::MakeHeader(0x55, 1, 0); | ||||
|     cmd_buff[1] = RESULT_SUCCESS.raw; | ||||
|     LOG_WARNING(Service_APT, "(STUBBED) unknown_ns_state_field=%u", unknown_ns_state_field); | ||||
| } | ||||
| 
 | ||||
| void GetNSStateField(Service::Interface* self) { | ||||
|     u32* cmd_buff = Kernel::GetCommandBuffer(); | ||||
| 
 | ||||
|     cmd_buff[0] = IPC::MakeHeader(0x56, 2, 0); | ||||
|     cmd_buff[1] = RESULT_SUCCESS.raw; | ||||
|     cmd_buff[8] = unknown_ns_state_field; | ||||
|     LOG_WARNING(Service_APT, "(STUBBED) unknown_ns_state_field=%u", unknown_ns_state_field); | ||||
| } | ||||
| 
 | ||||
| void GetAppletInfo(Service::Interface* self) { | ||||
|     u32* cmd_buff = Kernel::GetCommandBuffer(); | ||||
|     auto app_id = static_cast<AppletId>(cmd_buff[1]); | ||||
|  | @ -408,6 +435,29 @@ void GetStartupArgument(Service::Interface* self) { | |||
|     cmd_buff[2] = (parameter_size > 0) ? 1 : 0; | ||||
| } | ||||
| 
 | ||||
| void CheckNew3DSApp(Service::Interface* self) { | ||||
|     u32* cmd_buff = Kernel::GetCommandBuffer(); | ||||
| 
 | ||||
|     if (unknown_ns_state_field) { | ||||
|         cmd_buff[1] = RESULT_SUCCESS.raw; | ||||
|         cmd_buff[2] = 0; | ||||
|     } else { | ||||
|         PTM::CheckNew3DS(self); | ||||
|     } | ||||
| 
 | ||||
|     cmd_buff[0] = IPC::MakeHeader(0x101, 2, 0); | ||||
|     LOG_WARNING(Service_APT, "(STUBBED) called"); | ||||
| } | ||||
| 
 | ||||
| void CheckNew3DS(Service::Interface* self) { | ||||
|     u32* cmd_buff = Kernel::GetCommandBuffer(); | ||||
| 
 | ||||
|     PTM::CheckNew3DS(self); | ||||
| 
 | ||||
|     cmd_buff[0] = IPC::MakeHeader(0x102, 2, 0); | ||||
|     LOG_WARNING(Service_APT, "(STUBBED) called"); | ||||
| } | ||||
| 
 | ||||
| void Init() { | ||||
|     AddService(new APT_A_Interface); | ||||
|     AddService(new APT_S_Interface); | ||||
|  | @ -441,6 +491,7 @@ void Init() { | |||
|     lock = Kernel::Mutex::Create(false, "APT_U:Lock"); | ||||
| 
 | ||||
|     cpu_percent = 0; | ||||
|     unknown_ns_state_field = 0; | ||||
| 
 | ||||
|     // TODO(bunnei): Check if these are created in Initialize or on APT process startup.
 | ||||
|     notification_event = Kernel::Event::Create(Kernel::ResetType::OneShot, "APT_U:Notification"); | ||||
|  |  | |||
|  | @ -376,6 +376,50 @@ void StartLibraryApplet(Service::Interface* self); | |||
|  */ | ||||
| void GetStartupArgument(Service::Interface* self); | ||||
| 
 | ||||
| /**
 | ||||
|  * APT::SetNSStateField service function | ||||
|  *  Inputs: | ||||
|  *      1 : u8 NS state field | ||||
|  *  Outputs: | ||||
|  *      1 : Result of function, 0 on success, otherwise error code | ||||
|  *  Note: | ||||
|  *      This writes the input u8 to a NS state field. | ||||
|  */ | ||||
| void SetNSStateField(Service::Interface* self); | ||||
| 
 | ||||
| /**
 | ||||
|  * APT::GetNSStateField service function | ||||
|  *  Outputs: | ||||
|  *      1 : Result of function, 0 on success, otherwise error code | ||||
|  *      8 : u8 NS state field | ||||
|  *  Note: | ||||
|  *      This returns a u8 NS state field(which can be set by cmd 0x00550040), at cmdreply+8. | ||||
|  */ | ||||
| void GetNSStateField(Service::Interface* self); | ||||
| 
 | ||||
| /**
 | ||||
|  * APT::CheckNew3DSApp service function | ||||
|  *  Outputs: | ||||
|  *      1: Result code, 0 on success, otherwise error code | ||||
|  *      2: u8 output: 0 = Old3DS, 1 = New3DS. | ||||
|  *  Note: | ||||
|  *  This uses PTMSYSM:CheckNew3DS. | ||||
|  *  When a certain NS state field is non-zero, the output value is zero, | ||||
|  *  Otherwise the output is from PTMSYSM:CheckNew3DS. | ||||
|  *  Normally this NS state field is zero, however this state field is set to 1 | ||||
|  *  when APT:PrepareToStartApplication is used with flags bit8 is set. | ||||
|  */ | ||||
| void CheckNew3DSApp(Service::Interface* self); | ||||
| 
 | ||||
| /**
 | ||||
|  * Wrapper for PTMSYSM:CheckNew3DS | ||||
|  * APT::CheckNew3DS service function | ||||
|  *  Outputs: | ||||
|  *      1: Result code, 0 on success, otherwise error code | ||||
|  *      2: u8 output: 0 = Old3DS, 1 = New3DS. | ||||
|  */ | ||||
| void CheckNew3DS(Service::Interface* self); | ||||
| 
 | ||||
| /// Initialize the APT service
 | ||||
| void Init(); | ||||
| 
 | ||||
|  |  | |||
|  | @ -21,6 +21,7 @@ const Interface::FunctionInfo FunctionTable[] = { | |||
|     {0x000D0080, ReceiveParameter,             "ReceiveParameter"}, | ||||
|     {0x000E0080, GlanceParameter,              "GlanceParameter"}, | ||||
|     {0x000F0100, CancelParameter,              "CancelParameter"}, | ||||
|     {0x00150140, PrepareToStartApplication,    "PrepareToStartApplication"}, | ||||
|     {0x00160040, PreloadLibraryApplet,         "PreloadLibraryApplet"}, | ||||
|     {0x00180040, PrepareToStartLibraryApplet,  "PrepareToStartLibraryApplet"}, | ||||
|     {0x001E0084, StartLibraryApplet,           "StartLibraryApplet"}, | ||||
|  | @ -32,7 +33,10 @@ const Interface::FunctionInfo FunctionTable[] = { | |||
|     {0x004F0080, SetAppCpuTimeLimit,           "SetAppCpuTimeLimit"}, | ||||
|     {0x00500040, GetAppCpuTimeLimit,           "GetAppCpuTimeLimit"}, | ||||
|     {0x00510080, GetStartupArgument,           "GetStartupArgument"}, | ||||
|     {0x00550040, nullptr,                      "WriteInputToNsState?"}, | ||||
|     {0x00550040, SetNSStateField,              "SetNSStateField?"}, | ||||
|     {0x00560000, GetNSStateField,              "GetNSStateField?"}, | ||||
|     {0x01010000, CheckNew3DSApp,               "CheckNew3DSApp"}, | ||||
|     {0x01020000, CheckNew3DS,                  "CheckNew3DS"} | ||||
| }; | ||||
| 
 | ||||
| APT_A_Interface::APT_A_Interface() { | ||||
|  |  | |||
|  | @ -29,7 +29,7 @@ const Interface::FunctionInfo FunctionTable[] = { | |||
|     {0x00120040, nullptr,               "SetHomeMenuAppletIdForDebug"}, | ||||
|     {0x00130000, nullptr,               "GetPreparationState"}, | ||||
|     {0x00140040, nullptr,               "SetPreparationState"}, | ||||
|     {0x00150140, nullptr,               "PrepareToStartApplication"}, | ||||
|     {0x00150140, PrepareToStartApplication, "PrepareToStartApplication"}, | ||||
|     {0x00160040, PreloadLibraryApplet,  "PreloadLibraryApplet"}, | ||||
|     {0x00170040, nullptr,               "FinishPreloadingLibraryApplet"}, | ||||
|     {0x00180040, PrepareToStartLibraryApplet,"PrepareToStartLibraryApplet"}, | ||||
|  | @ -92,9 +92,11 @@ const Interface::FunctionInfo FunctionTable[] = { | |||
|     {0x00510080, GetStartupArgument,    "GetStartupArgument"}, | ||||
|     {0x00520104, nullptr,               "Wrap1"}, | ||||
|     {0x00530104, nullptr,               "Unwrap1"}, | ||||
|     {0x00550040, SetNSStateField,       "SetNSStateField?" }, | ||||
|     {0x00560000, GetNSStateField,       "GetNSStateField?" }, | ||||
|     {0x00580002, nullptr,               "GetProgramID"}, | ||||
|     {0x01010000, nullptr,               "CheckNew3DSApp"}, | ||||
|     {0x01020000, nullptr,               "CheckNew3DS"} | ||||
|     {0x01010000, CheckNew3DSApp,        "CheckNew3DSApp"}, | ||||
|     {0x01020000, CheckNew3DS,           "CheckNew3DS"} | ||||
| }; | ||||
| 
 | ||||
| APT_S_Interface::APT_S_Interface() { | ||||
|  |  | |||
|  | @ -29,7 +29,7 @@ const Interface::FunctionInfo FunctionTable[] = { | |||
|     {0x00120040, nullptr,                         "SetHomeMenuAppletIdForDebug"}, | ||||
|     {0x00130000, nullptr,                         "GetPreparationState"}, | ||||
|     {0x00140040, nullptr,                         "SetPreparationState"}, | ||||
|     {0x00150140, nullptr,                         "PrepareToStartApplication"}, | ||||
|     {0x00150140, PrepareToStartApplication,       "PrepareToStartApplication"}, | ||||
|     {0x00160040, PreloadLibraryApplet,            "PreloadLibraryApplet"}, | ||||
|     {0x00170040, nullptr,                         "FinishPreloadingLibraryApplet"}, | ||||
|     {0x00180040, PrepareToStartLibraryApplet,     "PrepareToStartLibraryApplet"}, | ||||
|  | @ -92,9 +92,11 @@ const Interface::FunctionInfo FunctionTable[] = { | |||
|     {0x00510080, GetStartupArgument,              "GetStartupArgument"}, | ||||
|     {0x00520104, nullptr,                         "Wrap1"}, | ||||
|     {0x00530104, nullptr,                         "Unwrap1"}, | ||||
|     {0x00550040, SetNSStateField,                 "SetNSStateField?"}, | ||||
|     {0x00560000, GetNSStateField,                 "GetNSStateField?"}, | ||||
|     {0x00580002, nullptr,                         "GetProgramID"}, | ||||
|     {0x01010000, nullptr,                         "CheckNew3DSApp"}, | ||||
|     {0x01020000, nullptr,                         "CheckNew3DS"} | ||||
|     {0x01010000, CheckNew3DSApp,                  "CheckNew3DSApp"}, | ||||
|     {0x01020000, CheckNew3DS,                     "CheckNew3DS"} | ||||
| }; | ||||
| 
 | ||||
| APT_U_Interface::APT_U_Interface() { | ||||
|  |  | |||
|  | @ -3,7 +3,7 @@ | |||
| // Refer to the license.txt file included.
 | ||||
| 
 | ||||
| #include "common/logging/log.h" | ||||
| 
 | ||||
| #include "core/settings.h" | ||||
| #include "core/file_sys/file_backend.h" | ||||
| #include "core/hle/service/fs/archive.h" | ||||
| #include "core/hle/service/ptm/ptm.h" | ||||
|  | @ -89,6 +89,20 @@ void IsLegacyPowerOff(Service::Interface* self) { | |||
|     LOG_WARNING(Service_PTM, "(STUBBED) called"); | ||||
| } | ||||
| 
 | ||||
| void CheckNew3DS(Service::Interface* self) { | ||||
|     u32* cmd_buff = Kernel::GetCommandBuffer(); | ||||
|     const bool is_new_3ds = Settings::values.is_new3ds; | ||||
| 
 | ||||
|     if (is_new_3ds) { | ||||
|         LOG_CRITICAL(Service_PTM, "The option 'is_new3ds' is enabled as part of the 'System' settings. Citra does not fully support New3DS emulation yet!"); | ||||
|     } | ||||
| 
 | ||||
|     cmd_buff[1] = RESULT_SUCCESS.raw; | ||||
|     cmd_buff[2] = is_new_3ds ? 1 : 0; | ||||
| 
 | ||||
|     LOG_WARNING(Service_PTM, "(STUBBED) called isNew3DS = 0x%08x", static_cast<u32>(is_new_3ds)); | ||||
| } | ||||
| 
 | ||||
| void Init() { | ||||
|     AddService(new PTM_Play_Interface); | ||||
|     AddService(new PTM_Sysm_Interface); | ||||
|  |  | |||
|  | @ -88,6 +88,14 @@ void GetTotalStepCount(Interface* self); | |||
|  */ | ||||
| void IsLegacyPowerOff(Interface* self); | ||||
| 
 | ||||
| /**
 | ||||
|  * PTM::CheckNew3DS service function | ||||
|  *  Outputs: | ||||
|  *      1: Result code, 0 on success, otherwise error code | ||||
|  *      2: u8 output: 0 = Old3DS, 1 = New3DS. | ||||
|  */ | ||||
| void CheckNew3DS(Interface* self); | ||||
| 
 | ||||
| /// Initialize the PTM service
 | ||||
| void Init(); | ||||
| 
 | ||||
|  |  | |||
|  | @ -18,7 +18,7 @@ const Interface::FunctionInfo FunctionTable[] = { | |||
|     {0x040700C0, nullptr,             "ShutdownAsync"}, | ||||
|     {0x04080000, nullptr,             "Awake"}, | ||||
|     {0x04090080, nullptr,             "RebootAsync"}, | ||||
|     {0x040A0000, nullptr,             "CheckNew3DS"}, | ||||
|     {0x040A0000, CheckNew3DS,         "CheckNew3DS"}, | ||||
|     {0x08010640, nullptr,             "SetInfoLEDPattern"}, | ||||
|     {0x08020040, nullptr,             "SetInfoLEDPatternHeader"}, | ||||
|     {0x08030000, nullptr,             "GetInfoLEDStatus"}, | ||||
|  | @ -35,7 +35,7 @@ const Interface::FunctionInfo FunctionTable[] = { | |||
|     {0x080E0140, nullptr,             "NotifyPlayEvent"}, | ||||
|     {0x080F0000, IsLegacyPowerOff,    "IsLegacyPowerOff"}, | ||||
|     {0x08100000, nullptr,             "ClearLegacyPowerOff"}, | ||||
|     {0x08110000, nullptr,             "GetShellStatus"}, | ||||
|     {0x08110000, GetShellState,       "GetShellState"}, | ||||
|     {0x08120000, nullptr,             "IsShutdownByBatteryEmpty"}, | ||||
|     {0x08130000, nullptr,             "FormatSavedata"}, | ||||
|     {0x08140000, nullptr,             "GetLegacyJumpProhibitedFlag"}, | ||||
|  |  | |||
|  | @ -41,6 +41,9 @@ static const std::array<Values, NUM_INPUTS> All = {{ | |||
| 
 | ||||
| 
 | ||||
| struct Values { | ||||
|     // CheckNew3DS
 | ||||
|     bool is_new3ds; | ||||
| 
 | ||||
|     // Controls
 | ||||
|     std::array<int, NativeInput::NUM_INPUTS> input_mappings; | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue