diff options
Diffstat (limited to 'src/core/hle/service')
-rw-r--r-- | src/core/hle/service/apt/apt.cpp | 51 | ||||
-rw-r--r-- | src/core/hle/service/apt/apt.h | 44 | ||||
-rw-r--r-- | src/core/hle/service/apt/apt_a.cpp | 6 | ||||
-rw-r--r-- | src/core/hle/service/apt/apt_s.cpp | 8 | ||||
-rw-r--r-- | src/core/hle/service/apt/apt_u.cpp | 8 | ||||
-rw-r--r-- | src/core/hle/service/cfg/cfg.cpp | 42 | ||||
-rw-r--r-- | src/core/hle/service/ptm/ptm.cpp | 16 | ||||
-rw-r--r-- | src/core/hle/service/ptm/ptm.h | 8 | ||||
-rw-r--r-- | src/core/hle/service/ptm/ptm_sysm.cpp | 4 |
9 files changed, 148 insertions, 39 deletions
diff --git a/src/core/hle/service/apt/apt.cpp b/src/core/hle/service/apt/apt.cpp index e2304fa54..1e54a53dd 100644 --- a/src/core/hle/service/apt/apt.cpp +++ b/src/core/hle/service/apt/apt.cpp @@ -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; @@ -256,6 +260,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," @@ -374,6 +382,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]); @@ -409,6 +436,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); @@ -442,6 +492,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"); diff --git a/src/core/hle/service/apt/apt.h b/src/core/hle/service/apt/apt.h index 66cda1d4c..76b3a3807 100644 --- a/src/core/hle/service/apt/apt.h +++ b/src/core/hle/service/apt/apt.h @@ -374,6 +374,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(); diff --git a/src/core/hle/service/apt/apt_a.cpp b/src/core/hle/service/apt/apt_a.cpp index 9ff47701a..223c0a8bd 100644 --- a/src/core/hle/service/apt/apt_a.cpp +++ b/src/core/hle/service/apt/apt_a.cpp @@ -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() { diff --git a/src/core/hle/service/apt/apt_s.cpp b/src/core/hle/service/apt/apt_s.cpp index ca54e593c..f5c52fa3d 100644 --- a/src/core/hle/service/apt/apt_s.cpp +++ b/src/core/hle/service/apt/apt_s.cpp @@ -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() { diff --git a/src/core/hle/service/apt/apt_u.cpp b/src/core/hle/service/apt/apt_u.cpp index 0e85c6d08..0e60bd34f 100644 --- a/src/core/hle/service/apt/apt_u.cpp +++ b/src/core/hle/service/apt/apt_u.cpp @@ -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() { diff --git a/src/core/hle/service/cfg/cfg.cpp b/src/core/hle/service/cfg/cfg.cpp index 3921653e5..e067db645 100644 --- a/src/core/hle/service/cfg/cfg.cpp +++ b/src/core/hle/service/cfg/cfg.cpp @@ -47,6 +47,12 @@ struct UsernameBlock { }; static_assert(sizeof(UsernameBlock) == 0x1C, "UsernameBlock must be exactly 0x1C bytes"); +struct BirthdayBlock { + u8 month; ///< The month of the birthday + u8 day; ///< The day of the birthday +}; +static_assert(sizeof(BirthdayBlock) == 2, "BirthdayBlock must be exactly 2 bytes"); + struct ConsoleModelInfo { u8 model; ///< The console model (3DS, 2DS, etc) u8 unknown[3]; ///< Unknown data @@ -65,9 +71,8 @@ static const u64 CFG_SAVE_ID = 0x00010017; static const u64 CONSOLE_UNIQUE_ID = 0xDEADC0DE; static const ConsoleModelInfo CONSOLE_MODEL = { NINTENDO_3DS_XL, { 0, 0, 0 } }; static const u8 CONSOLE_LANGUAGE = LANGUAGE_EN; -static const char CONSOLE_USERNAME[0x14] = "CITRA"; -/// This will be initialized in Init, and will be used when creating the block -static UsernameBlock CONSOLE_USERNAME_BLOCK; +static const UsernameBlock CONSOLE_USERNAME_BLOCK = { u"CITRA", 0, 0 }; +static const BirthdayBlock PROFILE_BIRTHDAY = { 3, 25 }; // March 25th, 2014 /// TODO(Subv): Find out what this actually is static const u8 SOUND_OUTPUT_MODE = 2; static const u8 UNITED_STATES_COUNTRY_ID = 49; @@ -333,32 +338,22 @@ ResultCode FormatConfig() { res = CreateConfigInfoBlk(0x00050005, sizeof(STEREO_CAMERA_SETTINGS), 0xE, STEREO_CAMERA_SETTINGS.data()); if (!res.IsSuccess()) return res; + res = CreateConfigInfoBlk(0x00070001, sizeof(SOUND_OUTPUT_MODE), 0xE, &SOUND_OUTPUT_MODE); if (!res.IsSuccess()) return res; + res = CreateConfigInfoBlk(0x00090001, sizeof(CONSOLE_UNIQUE_ID), 0xE, &CONSOLE_UNIQUE_ID); if (!res.IsSuccess()) return res; - res = CreateConfigInfoBlk(0x000A0000, sizeof(CONSOLE_USERNAME_BLOCK), 0xE, &CONSOLE_USERNAME_BLOCK); - if (!res.IsSuccess()) return res; - // 0x000A0000 - Profile username - struct { - u16_le username[10]; - u8 unused[4]; - u32_le wordfilter_version; // Unused by Citra - } profile_username = {}; - - std::u16string username_string = Common::UTF8ToUTF16("Citra"); - std::copy(username_string.cbegin(), username_string.cend(), profile_username.username); - res = CreateConfigInfoBlk(0x000A0000, sizeof(profile_username), 0xE, &profile_username); + res = CreateConfigInfoBlk(0x000A0000, sizeof(CONSOLE_USERNAME_BLOCK), 0xE, &CONSOLE_USERNAME_BLOCK); if (!res.IsSuccess()) return res; - // 0x000A0001 - Profile birthday - const u8 profile_birthday[2] = {3, 25}; // March 25th, 2014 - res = CreateConfigInfoBlk(0x000A0001, sizeof(profile_birthday), 0xE, profile_birthday); + res = CreateConfigInfoBlk(0x000A0001, sizeof(PROFILE_BIRTHDAY), 0xE, &PROFILE_BIRTHDAY); if (!res.IsSuccess()) return res; res = CreateConfigInfoBlk(0x000A0002, sizeof(CONSOLE_LANGUAGE), 0xE, &CONSOLE_LANGUAGE); if (!res.IsSuccess()) return res; + res = CreateConfigInfoBlk(0x000B0000, sizeof(COUNTRY_INFO), 0xE, &COUNTRY_INFO); if (!res.IsSuccess()) return res; @@ -439,17 +434,6 @@ void Init() { return; } - // Initialize the Username block - // TODO(Subv): Initialize this directly in the variable when MSVC supports char16_t string literals - memset(&CONSOLE_USERNAME_BLOCK, 0, sizeof(CONSOLE_USERNAME_BLOCK)); - CONSOLE_USERNAME_BLOCK.ng_word = 0; - CONSOLE_USERNAME_BLOCK.zero = 0; - - // Copy string to buffer and pad with zeros at the end - auto size = Common::UTF8ToUTF16(CONSOLE_USERNAME).copy(CONSOLE_USERNAME_BLOCK.username, 0x14); - std::fill(std::begin(CONSOLE_USERNAME_BLOCK.username) + size, - std::end(CONSOLE_USERNAME_BLOCK.username), 0); - FormatConfig(); } diff --git a/src/core/hle/service/ptm/ptm.cpp b/src/core/hle/service/ptm/ptm.cpp index 94f494690..e2c17d93b 100644 --- a/src/core/hle/service/ptm/ptm.cpp +++ b/src/core/hle/service/ptm/ptm.cpp @@ -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_new_3ds; + + if (is_new_3ds) { + LOG_CRITICAL(Service_PTM, "The option 'is_new_3ds' is enabled as part of the 'System' settings. Citra does not fully support New 3DS 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); diff --git a/src/core/hle/service/ptm/ptm.h b/src/core/hle/service/ptm/ptm.h index 4cf7383d1..7ef8877c7 100644 --- a/src/core/hle/service/ptm/ptm.h +++ b/src/core/hle/service/ptm/ptm.h @@ -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(); diff --git a/src/core/hle/service/ptm/ptm_sysm.cpp b/src/core/hle/service/ptm/ptm_sysm.cpp index fe76dd108..cc4ef1101 100644 --- a/src/core/hle/service/ptm/ptm_sysm.cpp +++ b/src/core/hle/service/ptm/ptm_sysm.cpp @@ -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"}, |