summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/citra/config.cpp5
-rw-r--r--src/citra_qt/config.cpp6
-rw-r--r--src/core/hle/service/apt/apt.cpp51
-rw-r--r--src/core/hle/service/apt/apt.h44
-rw-r--r--src/core/hle/service/apt/apt_a.cpp6
-rw-r--r--src/core/hle/service/apt/apt_s.cpp8
-rw-r--r--src/core/hle/service/apt/apt_u.cpp8
-rw-r--r--src/core/hle/service/ptm/ptm.cpp16
-rw-r--r--src/core/hle/service/ptm/ptm.h8
-rw-r--r--src/core/hle/service/ptm/ptm_sysm.cpp4
-rw-r--r--src/core/settings.h3
11 files changed, 145 insertions, 14 deletions
diff --git a/src/citra/config.cpp b/src/citra/config.cpp
index 6b6617352..ebea5f840 100644
--- a/src/citra/config.cpp
+++ b/src/citra/config.cpp
@@ -73,8 +73,9 @@ void Config::ReadValues() {
// Data Storage
Settings::values.use_virtual_sd = sdl2_config->GetBoolean("Data Storage", "use_virtual_sd", true);
- // System Region
- Settings::values.region_value = sdl2_config->GetInteger("System Region", "region_value", 1);
+ // System
+ Settings::values.is_new3ds = sdl2_config->GetBoolean("System", "is_new3ds", false);
+ Settings::values.region_value = sdl2_config->GetInteger("System", "region_value", 1);
// Miscellaneous
Settings::values.log_filter = sdl2_config->Get("Miscellaneous", "log_filter", "*:Info");
diff --git a/src/citra_qt/config.cpp b/src/citra_qt/config.cpp
index 8e247ff5c..66271aa7b 100644
--- a/src/citra_qt/config.cpp
+++ b/src/citra_qt/config.cpp
@@ -55,7 +55,8 @@ void Config::ReadValues() {
Settings::values.use_virtual_sd = qt_config->value("use_virtual_sd", true).toBool();
qt_config->endGroup();
- qt_config->beginGroup("System Region");
+ qt_config->beginGroup("System");
+ Settings::values.is_new3ds = qt_config->value("is_new3ds", false).toBool();
Settings::values.region_value = qt_config->value("region_value", 1).toInt();
qt_config->endGroup();
@@ -95,7 +96,8 @@ void Config::SaveValues() {
qt_config->setValue("use_virtual_sd", Settings::values.use_virtual_sd);
qt_config->endGroup();
- qt_config->beginGroup("System Region");
+ qt_config->beginGroup("System");
+ qt_config->setValue("is_new3ds", Settings::values.is_new3ds);
qt_config->setValue("region_value", Settings::values.region_value);
qt_config->endGroup();
diff --git a/src/core/hle/service/apt/apt.cpp b/src/core/hle/service/apt/apt.cpp
index 6d72e8188..e6fcbc714 100644
--- a/src/core/hle/service/apt/apt.cpp
+++ b/src/core/hle/service/apt/apt.cpp
@@ -13,6 +13,7 @@
#include "core/hle/service/apt/apt_s.h"
#include "core/hle/service/apt/apt_u.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"
@@ -41,6 +42,9 @@ static std::shared_ptr<std::vector<u8>> shared_font;
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;
@@ -264,6 +268,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,"
@@ -379,6 +387,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]);
@@ -414,6 +441,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);
@@ -449,6 +499,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 668b4a66f..fd3c2bd37 100644
--- a/src/core/hle/service/apt/apt.h
+++ b/src/core/hle/service/apt/apt.h
@@ -361,6 +361,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/ptm/ptm.cpp b/src/core/hle/service/ptm/ptm.cpp
index 94f494690..3a0331ee1 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_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);
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"},
diff --git a/src/core/settings.h b/src/core/settings.h
index 97ddcdff9..4034b795a 100644
--- a/src/core/settings.h
+++ b/src/core/settings.h
@@ -40,6 +40,9 @@ static const std::array<Values, NUM_INPUTS> All = {{
struct Values {
+ // CheckNew3DS
+ bool is_new3ds;
+
// Controls
std::array<int, NativeInput::NUM_INPUTS> input_mappings;