summaryrefslogtreecommitdiffstats
path: root/src/core/hle/service
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/hle/service')
-rw-r--r--src/core/hle/service/am/am.cpp17
-rw-r--r--src/core/hle/service/am/applets/applet_cabinet.cpp5
-rw-r--r--src/core/hle/service/am/applets/applet_cabinet.h1
-rw-r--r--src/core/hle/service/am/applets/applet_controller.cpp17
-rw-r--r--src/core/hle/service/am/applets/applet_controller.h10
-rw-r--r--src/core/hle/service/am/applets/applet_error.cpp5
-rw-r--r--src/core/hle/service/am/applets/applet_error.h1
-rw-r--r--src/core/hle/service/am/applets/applet_general_backend.cpp15
-rw-r--r--src/core/hle/service/am/applets/applet_general_backend.h3
-rw-r--r--src/core/hle/service/am/applets/applet_mii_edit.cpp5
-rw-r--r--src/core/hle/service/am/applets/applet_mii_edit.h1
-rw-r--r--src/core/hle/service/am/applets/applet_profile_select.cpp57
-rw-r--r--src/core/hle/service/am/applets/applet_profile_select.h103
-rw-r--r--src/core/hle/service/am/applets/applet_software_keyboard.cpp5
-rw-r--r--src/core/hle/service/am/applets/applet_software_keyboard.h1
-rw-r--r--src/core/hle/service/am/applets/applet_web_browser.cpp5
-rw-r--r--src/core/hle/service/am/applets/applet_web_browser.h1
-rw-r--r--src/core/hle/service/am/applets/applets.h1
-rw-r--r--src/core/hle/service/hid/controllers/console_sixaxis.cpp5
-rw-r--r--src/core/hle/service/hid/controllers/console_sixaxis.h6
-rw-r--r--src/core/hle/service/hid/controllers/npad.cpp41
-rw-r--r--src/core/hle/service/hid/controllers/npad.h4
-rw-r--r--src/core/hle/service/hid/controllers/palma.cpp2
-rw-r--r--src/core/hle/service/hid/controllers/palma.h6
-rw-r--r--src/core/hle/service/hid/hid.cpp41
-rw-r--r--src/core/hle/service/hid/hid.h1
-rw-r--r--src/core/hle/service/hid/hidbus/hidbus_base.cpp2
-rw-r--r--src/core/hle/service/hid/hidbus/hidbus_base.h6
-rw-r--r--src/core/hle/service/hid/hidbus/ringcon.cpp4
-rw-r--r--src/core/hle/service/hid/irsensor/image_transfer_processor.cpp20
-rw-r--r--src/core/hle/service/hid/irsensor/image_transfer_processor.h6
-rw-r--r--src/core/hle/service/hle_ipc.cpp3
-rw-r--r--src/core/hle/service/jit/jit.cpp10
-rw-r--r--src/core/hle/service/ldr/ldr.cpp15
-rw-r--r--src/core/hle/service/mii/mii_manager.cpp35
-rw-r--r--src/core/hle/service/mii/mii_manager.h7
-rw-r--r--src/core/hle/service/mii/types.h60
-rw-r--r--src/core/hle/service/nfc/nfc_device.cpp16
-rw-r--r--src/core/hle/service/nfc/nfc_device.h1
-rw-r--r--src/core/hle/service/nfp/amiibo_crypto.cpp10
-rw-r--r--src/core/hle/service/nfp/amiibo_crypto.h3
-rw-r--r--src/core/hle/service/nfp/nfp_device.cpp139
-rw-r--r--src/core/hle/service/nfp/nfp_device.h4
-rw-r--r--src/core/hle/service/nfp/nfp_types.h13
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp4
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp4
46 files changed, 559 insertions, 162 deletions
diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp
index deeca925d..a17c46121 100644
--- a/src/core/hle/service/am/am.cpp
+++ b/src/core/hle/service/am/am.cpp
@@ -945,7 +945,7 @@ public:
{0, &ILibraryAppletAccessor::GetAppletStateChangedEvent, "GetAppletStateChangedEvent"},
{1, &ILibraryAppletAccessor::IsCompleted, "IsCompleted"},
{10, &ILibraryAppletAccessor::Start, "Start"},
- {20, nullptr, "RequestExit"},
+ {20, &ILibraryAppletAccessor::RequestExit, "RequestExit"},
{25, nullptr, "Terminate"},
{30, &ILibraryAppletAccessor::GetResult, "GetResult"},
{50, nullptr, "SetOutOfFocusApplicationSuspendingEnabled"},
@@ -1010,6 +1010,15 @@ private:
rb.Push(ResultSuccess);
}
+ void RequestExit(HLERequestContext& ctx) {
+ LOG_DEBUG(Service_AM, "called");
+
+ ASSERT(applet != nullptr);
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(applet->RequestExit());
+ }
+
void PushInData(HLERequestContext& ctx) {
LOG_DEBUG(Service_AM, "called");
@@ -1265,7 +1274,8 @@ void ILibraryAppletCreator::CreateTransferMemoryStorage(HLERequestContext& ctx)
}
std::vector<u8> memory(transfer_mem->GetSize());
- system.Memory().ReadBlock(transfer_mem->GetSourceAddress(), memory.data(), memory.size());
+ system.ApplicationMemory().ReadBlock(transfer_mem->GetSourceAddress(), memory.data(),
+ memory.size());
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(ResultSuccess);
@@ -1298,7 +1308,8 @@ void ILibraryAppletCreator::CreateHandleStorage(HLERequestContext& ctx) {
}
std::vector<u8> memory(transfer_mem->GetSize());
- system.Memory().ReadBlock(transfer_mem->GetSourceAddress(), memory.data(), memory.size());
+ system.ApplicationMemory().ReadBlock(transfer_mem->GetSourceAddress(), memory.data(),
+ memory.size());
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(ResultSuccess);
diff --git a/src/core/hle/service/am/applets/applet_cabinet.cpp b/src/core/hle/service/am/applets/applet_cabinet.cpp
index 162687b29..93c9f2a55 100644
--- a/src/core/hle/service/am/applets/applet_cabinet.cpp
+++ b/src/core/hle/service/am/applets/applet_cabinet.cpp
@@ -174,4 +174,9 @@ void Cabinet::Cancel() {
broker.SignalStateChanged();
}
+Result Cabinet::RequestExit() {
+ frontend.Close();
+ R_SUCCEED();
+}
+
} // namespace Service::AM::Applets
diff --git a/src/core/hle/service/am/applets/applet_cabinet.h b/src/core/hle/service/am/applets/applet_cabinet.h
index 84197a807..edd295a27 100644
--- a/src/core/hle/service/am/applets/applet_cabinet.h
+++ b/src/core/hle/service/am/applets/applet_cabinet.h
@@ -89,6 +89,7 @@ public:
void Execute() override;
void DisplayCompleted(bool apply_changes, std::string_view amiibo_name);
void Cancel();
+ Result RequestExit() override;
private:
const Core::Frontend::CabinetApplet& frontend;
diff --git a/src/core/hle/service/am/applets/applet_controller.cpp b/src/core/hle/service/am/applets/applet_controller.cpp
index 58484519b..9840d2547 100644
--- a/src/core/hle/service/am/applets/applet_controller.cpp
+++ b/src/core/hle/service/am/applets/applet_controller.cpp
@@ -224,7 +224,8 @@ void Controller::Execute() {
parameters.allow_dual_joycons, parameters.allow_left_joycon,
parameters.allow_right_joycon);
- frontend.ReconfigureControllers([this] { ConfigurationComplete(); }, parameters);
+ frontend.ReconfigureControllers(
+ [this](bool is_success) { ConfigurationComplete(is_success); }, parameters);
break;
}
case ControllerSupportMode::ShowControllerStrapGuide:
@@ -232,16 +233,16 @@ void Controller::Execute() {
case ControllerSupportMode::ShowControllerKeyRemappingForSystem:
UNIMPLEMENTED_MSG("ControllerSupportMode={} is not implemented",
controller_private_arg.mode);
- ConfigurationComplete();
+ ConfigurationComplete(true);
break;
default: {
- ConfigurationComplete();
+ ConfigurationComplete(true);
break;
}
}
}
-void Controller::ConfigurationComplete() {
+void Controller::ConfigurationComplete(bool is_success) {
ControllerSupportResultInfo result_info{};
// If enable_single_mode is enabled, player_count is 1 regardless of any other parameters.
@@ -250,7 +251,8 @@ void Controller::ConfigurationComplete() {
result_info.selected_id = static_cast<u32>(system.HIDCore().GetFirstNpadId());
- result_info.result = 0;
+ result_info.result =
+ is_success ? ControllerSupportResult::Success : ControllerSupportResult::Cancel;
LOG_DEBUG(Service_HID, "Result Info: player_count={}, selected_id={}, result={}",
result_info.player_count, result_info.selected_id, result_info.result);
@@ -262,4 +264,9 @@ void Controller::ConfigurationComplete() {
broker.SignalStateChanged();
}
+Result Controller::RequestExit() {
+ frontend.Close();
+ R_SUCCEED();
+}
+
} // namespace Service::AM::Applets
diff --git a/src/core/hle/service/am/applets/applet_controller.h b/src/core/hle/service/am/applets/applet_controller.h
index 1f9adec65..f6c64f633 100644
--- a/src/core/hle/service/am/applets/applet_controller.h
+++ b/src/core/hle/service/am/applets/applet_controller.h
@@ -48,6 +48,11 @@ enum class ControllerSupportCaller : u8 {
MaxControllerSupportCaller,
};
+enum class ControllerSupportResult : u32 {
+ Success = 0,
+ Cancel = 2,
+};
+
struct ControllerSupportArgPrivate {
u32 arg_private_size{};
u32 arg_size{};
@@ -112,7 +117,7 @@ struct ControllerSupportResultInfo {
s8 player_count{};
INSERT_PADDING_BYTES(3);
u32 selected_id{};
- u32 result{};
+ ControllerSupportResult result{};
};
static_assert(sizeof(ControllerSupportResultInfo) == 0xC,
"ControllerSupportResultInfo has incorrect size.");
@@ -129,8 +134,9 @@ public:
Result GetStatus() const override;
void ExecuteInteractive() override;
void Execute() override;
+ Result RequestExit() override;
- void ConfigurationComplete();
+ void ConfigurationComplete(bool is_success);
private:
const Core::Frontend::ControllerApplet& frontend;
diff --git a/src/core/hle/service/am/applets/applet_error.cpp b/src/core/hle/service/am/applets/applet_error.cpp
index b013896b4..b46ea840c 100644
--- a/src/core/hle/service/am/applets/applet_error.cpp
+++ b/src/core/hle/service/am/applets/applet_error.cpp
@@ -209,4 +209,9 @@ void Error::DisplayCompleted() {
broker.SignalStateChanged();
}
+Result Error::RequestExit() {
+ frontend.Close();
+ R_SUCCEED();
+}
+
} // namespace Service::AM::Applets
diff --git a/src/core/hle/service/am/applets/applet_error.h b/src/core/hle/service/am/applets/applet_error.h
index d78d6f1d1..d822a32bb 100644
--- a/src/core/hle/service/am/applets/applet_error.h
+++ b/src/core/hle/service/am/applets/applet_error.h
@@ -34,6 +34,7 @@ public:
Result GetStatus() const override;
void ExecuteInteractive() override;
void Execute() override;
+ Result RequestExit() override;
void DisplayCompleted();
diff --git a/src/core/hle/service/am/applets/applet_general_backend.cpp b/src/core/hle/service/am/applets/applet_general_backend.cpp
index 1eefa85e3..8b352020e 100644
--- a/src/core/hle/service/am/applets/applet_general_backend.cpp
+++ b/src/core/hle/service/am/applets/applet_general_backend.cpp
@@ -150,6 +150,11 @@ void Auth::AuthFinished(bool is_successful) {
broker.SignalStateChanged();
}
+Result Auth::RequestExit() {
+ frontend.Close();
+ R_SUCCEED();
+}
+
PhotoViewer::PhotoViewer(Core::System& system_, LibraryAppletMode applet_mode_,
const Core::Frontend::PhotoViewerApplet& frontend_)
: Applet{system_, applet_mode_}, frontend{frontend_}, system{system_} {}
@@ -202,6 +207,11 @@ void PhotoViewer::ViewFinished() {
broker.SignalStateChanged();
}
+Result PhotoViewer::RequestExit() {
+ frontend.Close();
+ R_SUCCEED();
+}
+
StubApplet::StubApplet(Core::System& system_, AppletId id_, LibraryAppletMode applet_mode_)
: Applet{system_, applet_mode_}, id{id_}, system{system_} {}
@@ -250,4 +260,9 @@ void StubApplet::Execute() {
broker.SignalStateChanged();
}
+Result StubApplet::RequestExit() {
+ // Nothing to do.
+ R_SUCCEED();
+}
+
} // namespace Service::AM::Applets
diff --git a/src/core/hle/service/am/applets/applet_general_backend.h b/src/core/hle/service/am/applets/applet_general_backend.h
index a9f2535a2..34ecaebb9 100644
--- a/src/core/hle/service/am/applets/applet_general_backend.h
+++ b/src/core/hle/service/am/applets/applet_general_backend.h
@@ -28,6 +28,7 @@ public:
Result GetStatus() const override;
void ExecuteInteractive() override;
void Execute() override;
+ Result RequestExit() override;
void AuthFinished(bool is_successful = true);
@@ -59,6 +60,7 @@ public:
Result GetStatus() const override;
void ExecuteInteractive() override;
void Execute() override;
+ Result RequestExit() override;
void ViewFinished();
@@ -80,6 +82,7 @@ public:
Result GetStatus() const override;
void ExecuteInteractive() override;
void Execute() override;
+ Result RequestExit() override;
private:
AppletId id;
diff --git a/src/core/hle/service/am/applets/applet_mii_edit.cpp b/src/core/hle/service/am/applets/applet_mii_edit.cpp
index ae80ef506..d1f652c09 100644
--- a/src/core/hle/service/am/applets/applet_mii_edit.cpp
+++ b/src/core/hle/service/am/applets/applet_mii_edit.cpp
@@ -135,4 +135,9 @@ void MiiEdit::MiiEditOutputForCharInfoEditing(MiiEditResult result,
broker.SignalStateChanged();
}
+Result MiiEdit::RequestExit() {
+ frontend.Close();
+ R_SUCCEED();
+}
+
} // namespace Service::AM::Applets
diff --git a/src/core/hle/service/am/applets/applet_mii_edit.h b/src/core/hle/service/am/applets/applet_mii_edit.h
index d18dd3cf5..3f46fae1b 100644
--- a/src/core/hle/service/am/applets/applet_mii_edit.h
+++ b/src/core/hle/service/am/applets/applet_mii_edit.h
@@ -25,6 +25,7 @@ public:
Result GetStatus() const override;
void ExecuteInteractive() override;
void Execute() override;
+ Result RequestExit() override;
void MiiEditOutput(MiiEditResult result, s32 index);
diff --git a/src/core/hle/service/am/applets/applet_profile_select.cpp b/src/core/hle/service/am/applets/applet_profile_select.cpp
index 1d69f5447..89cb323e9 100644
--- a/src/core/hle/service/am/applets/applet_profile_select.cpp
+++ b/src/core/hle/service/am/applets/applet_profile_select.cpp
@@ -25,13 +25,29 @@ void ProfileSelect::Initialize() {
final_data.clear();
Applet::Initialize();
+ profile_select_version = ProfileSelectAppletVersion{common_args.library_version};
const auto user_config_storage = broker.PopNormalDataToApplet();
ASSERT(user_config_storage != nullptr);
const auto& user_config = user_config_storage->GetData();
- ASSERT(user_config.size() >= sizeof(UserSelectionConfig));
- std::memcpy(&config, user_config.data(), sizeof(UserSelectionConfig));
+ LOG_INFO(Service_AM, "Initializing Profile Select Applet with version={}",
+ profile_select_version);
+
+ switch (profile_select_version) {
+ case ProfileSelectAppletVersion::Version1:
+ ASSERT(user_config.size() == sizeof(UiSettingsV1));
+ std::memcpy(&config_old, user_config.data(), sizeof(UiSettingsV1));
+ break;
+ case ProfileSelectAppletVersion::Version2:
+ case ProfileSelectAppletVersion::Version3:
+ ASSERT(user_config.size() == sizeof(UiSettings));
+ std::memcpy(&config, user_config.data(), sizeof(UiSettings));
+ break;
+ default:
+ UNIMPLEMENTED_MSG("Unknown profile_select_version = {}", profile_select_version);
+ break;
+ }
}
bool ProfileSelect::TransactionComplete() const {
@@ -52,11 +68,37 @@ void ProfileSelect::Execute() {
return;
}
- frontend.SelectProfile([this](std::optional<Common::UUID> uuid) { SelectionComplete(uuid); });
+ Core::Frontend::ProfileSelectParameters parameters{};
+
+ switch (profile_select_version) {
+ case ProfileSelectAppletVersion::Version1:
+ parameters = {
+ .mode = config_old.mode,
+ .invalid_uid_list = config_old.invalid_uid_list,
+ .display_options = config_old.display_options,
+ .purpose = UserSelectionPurpose::General,
+ };
+ break;
+ case ProfileSelectAppletVersion::Version2:
+ case ProfileSelectAppletVersion::Version3:
+ parameters = {
+ .mode = config.mode,
+ .invalid_uid_list = config.invalid_uid_list,
+ .display_options = config.display_options,
+ .purpose = config.purpose,
+ };
+ break;
+ default:
+ UNIMPLEMENTED_MSG("Unknown profile_select_version = {}", profile_select_version);
+ break;
+ }
+
+ frontend.SelectProfile([this](std::optional<Common::UUID> uuid) { SelectionComplete(uuid); },
+ parameters);
}
void ProfileSelect::SelectionComplete(std::optional<Common::UUID> uuid) {
- UserSelectionOutput output{};
+ UiReturnArg output{};
if (uuid.has_value() && uuid->IsValid()) {
output.result = 0;
@@ -67,10 +109,15 @@ void ProfileSelect::SelectionComplete(std::optional<Common::UUID> uuid) {
output.uuid_selected = Common::InvalidUUID;
}
- final_data = std::vector<u8>(sizeof(UserSelectionOutput));
+ final_data = std::vector<u8>(sizeof(UiReturnArg));
std::memcpy(final_data.data(), &output, final_data.size());
broker.PushNormalDataFromApplet(std::make_shared<IStorage>(system, std::move(final_data)));
broker.SignalStateChanged();
}
+Result ProfileSelect::RequestExit() {
+ frontend.Close();
+ R_SUCCEED();
+}
+
} // namespace Service::AM::Applets
diff --git a/src/core/hle/service/am/applets/applet_profile_select.h b/src/core/hle/service/am/applets/applet_profile_select.h
index b77f1d205..369f9250f 100644
--- a/src/core/hle/service/am/applets/applet_profile_select.h
+++ b/src/core/hle/service/am/applets/applet_profile_select.h
@@ -16,19 +16,100 @@ class System;
namespace Service::AM::Applets {
-struct UserSelectionConfig {
- // TODO(DarkLordZach): RE this structure
- // It seems to be flags and the like that determine the UI of the applet on the switch... from
- // my research this is safe to ignore for now.
- INSERT_PADDING_BYTES(0xA0);
+enum class ProfileSelectAppletVersion : u32 {
+ Version1 = 0x1, // 1.0.0+
+ Version2 = 0x10000, // 2.0.0+
+ Version3 = 0x20000, // 6.0.0+
};
-static_assert(sizeof(UserSelectionConfig) == 0xA0, "UserSelectionConfig has incorrect size.");
-struct UserSelectionOutput {
+// This is nn::account::UiMode
+enum class UiMode {
+ UserSelector,
+ UserCreator,
+ EnsureNetworkServiceAccountAvailable,
+ UserIconEditor,
+ UserNicknameEditor,
+ UserCreatorForStarter,
+ NintendoAccountAuthorizationRequestContext,
+ IntroduceExternalNetworkServiceAccount,
+ IntroduceExternalNetworkServiceAccountForRegistration,
+ NintendoAccountNnidLinker,
+ LicenseRequirementsForNetworkService,
+ LicenseRequirementsForNetworkServiceWithUserContextImpl,
+ UserCreatorForImmediateNaLoginTest,
+ UserQualificationPromoter,
+};
+
+// This is nn::account::UserSelectionPurpose
+enum class UserSelectionPurpose {
+ General,
+ GameCardRegistration,
+ EShopLaunch,
+ EShopItemShow,
+ PicturePost,
+ NintendoAccountLinkage,
+ SettingsUpdate,
+ SaveDataDeletion,
+ UserMigration,
+ SaveDataTransfer,
+};
+
+// This is nn::account::NintendoAccountStartupDialogType
+enum class NintendoAccountStartupDialogType {
+ LoginAndCreate,
+ Login,
+ Create,
+};
+
+// This is nn::account::UserSelectionSettingsForSystemService
+struct UserSelectionSettingsForSystemService {
+ UserSelectionPurpose purpose;
+ bool enable_user_creation;
+ INSERT_PADDING_BYTES(0x3);
+};
+static_assert(sizeof(UserSelectionSettingsForSystemService) == 0x8,
+ "UserSelectionSettingsForSystemService has incorrect size.");
+
+struct UiSettingsDisplayOptions {
+ bool is_network_service_account_required;
+ bool is_skip_enabled;
+ bool is_system_or_launcher;
+ bool is_registration_permitted;
+ bool show_skip_button;
+ bool aditional_select;
+ bool show_user_selector;
+ bool is_unqualified_user_selectable;
+};
+static_assert(sizeof(UiSettingsDisplayOptions) == 0x8,
+ "UiSettingsDisplayOptions has incorrect size.");
+
+struct UiSettingsV1 {
+ UiMode mode;
+ INSERT_PADDING_BYTES(0x4);
+ std::array<Common::UUID, 8> invalid_uid_list;
+ u64 application_id;
+ UiSettingsDisplayOptions display_options;
+};
+static_assert(sizeof(UiSettingsV1) == 0x98, "UiSettings has incorrect size.");
+
+// This is nn::account::UiSettings
+struct UiSettings {
+ UiMode mode;
+ INSERT_PADDING_BYTES(0x4);
+ std::array<Common::UUID, 8> invalid_uid_list;
+ u64 application_id;
+ UiSettingsDisplayOptions display_options;
+ UserSelectionPurpose purpose;
+ INSERT_PADDING_BYTES(0x4);
+};
+static_assert(sizeof(UiSettings) == 0xA0, "UiSettings has incorrect size.");
+
+// This is nn::account::UiReturnArg
+struct UiReturnArg {
u64 result;
Common::UUID uuid_selected;
};
-static_assert(sizeof(UserSelectionOutput) == 0x18, "UserSelectionOutput has incorrect size.");
+static_assert(sizeof(UiReturnArg) == 0x18, "UiReturnArg has incorrect size.");
class ProfileSelect final : public Applet {
public:
@@ -42,13 +123,17 @@ public:
Result GetStatus() const override;
void ExecuteInteractive() override;
void Execute() override;
+ Result RequestExit() override;
void SelectionComplete(std::optional<Common::UUID> uuid);
private:
const Core::Frontend::ProfileSelectApplet& frontend;
- UserSelectionConfig config;
+ UiSettings config;
+ UiSettingsV1 config_old;
+ ProfileSelectAppletVersion profile_select_version;
+
bool complete = false;
Result status = ResultSuccess;
std::vector<u8> final_data;
diff --git a/src/core/hle/service/am/applets/applet_software_keyboard.cpp b/src/core/hle/service/am/applets/applet_software_keyboard.cpp
index c18236045..4145bb84f 100644
--- a/src/core/hle/service/am/applets/applet_software_keyboard.cpp
+++ b/src/core/hle/service/am/applets/applet_software_keyboard.cpp
@@ -770,6 +770,11 @@ void SoftwareKeyboard::ExitKeyboard() {
broker.SignalStateChanged();
}
+Result SoftwareKeyboard::RequestExit() {
+ frontend.Close();
+ R_SUCCEED();
+}
+
// Inline Software Keyboard Requests
void SoftwareKeyboard::RequestFinalize(const std::vector<u8>& request_data) {
diff --git a/src/core/hle/service/am/applets/applet_software_keyboard.h b/src/core/hle/service/am/applets/applet_software_keyboard.h
index b01b31c98..2e919811b 100644
--- a/src/core/hle/service/am/applets/applet_software_keyboard.h
+++ b/src/core/hle/service/am/applets/applet_software_keyboard.h
@@ -31,6 +31,7 @@ public:
Result GetStatus() const override;
void ExecuteInteractive() override;
void Execute() override;
+ Result RequestExit() override;
/**
* Submits the input text to the application.
diff --git a/src/core/hle/service/am/applets/applet_web_browser.cpp b/src/core/hle/service/am/applets/applet_web_browser.cpp
index f061bae80..2accf7898 100644
--- a/src/core/hle/service/am/applets/applet_web_browser.cpp
+++ b/src/core/hle/service/am/applets/applet_web_browser.cpp
@@ -363,6 +363,11 @@ void WebBrowser::WebBrowserExit(WebExitReason exit_reason, std::string last_url)
broker.SignalStateChanged();
}
+Result WebBrowser::RequestExit() {
+ frontend.Close();
+ R_SUCCEED();
+}
+
bool WebBrowser::InputTLVExistsInMap(WebArgInputTLVType input_tlv_type) const {
return web_arg_input_tlv_map.find(input_tlv_type) != web_arg_input_tlv_map.end();
}
diff --git a/src/core/hle/service/am/applets/applet_web_browser.h b/src/core/hle/service/am/applets/applet_web_browser.h
index fd727fac8..99fe18659 100644
--- a/src/core/hle/service/am/applets/applet_web_browser.h
+++ b/src/core/hle/service/am/applets/applet_web_browser.h
@@ -35,6 +35,7 @@ public:
Result GetStatus() const override;
void ExecuteInteractive() override;
void Execute() override;
+ Result RequestExit() override;
void ExtractOfflineRomFS();
diff --git a/src/core/hle/service/am/applets/applets.h b/src/core/hle/service/am/applets/applets.h
index a22eb62a8..12f374199 100644
--- a/src/core/hle/service/am/applets/applets.h
+++ b/src/core/hle/service/am/applets/applets.h
@@ -142,6 +142,7 @@ public:
virtual Result GetStatus() const = 0;
virtual void ExecuteInteractive() = 0;
virtual void Execute() = 0;
+ virtual Result RequestExit() = 0;
AppletDataBroker& GetBroker() {
return broker;
diff --git a/src/core/hle/service/hid/controllers/console_sixaxis.cpp b/src/core/hle/service/hid/controllers/console_sixaxis.cpp
index 478d38590..bcb272eaf 100644
--- a/src/core/hle/service/hid/controllers/console_sixaxis.cpp
+++ b/src/core/hle/service/hid/controllers/console_sixaxis.cpp
@@ -60,10 +60,11 @@ void Controller_ConsoleSixAxis::OnUpdate(const Core::Timing::CoreTiming& core_ti
// Update seven six axis transfer memory
seven_sixaxis_lifo.WriteNextEntry(next_seven_sixaxis_state);
- system.Memory().WriteBlock(transfer_memory, &seven_sixaxis_lifo, sizeof(seven_sixaxis_lifo));
+ system.ApplicationMemory().WriteBlock(transfer_memory, &seven_sixaxis_lifo,
+ sizeof(seven_sixaxis_lifo));
}
-void Controller_ConsoleSixAxis::SetTransferMemoryAddress(VAddr t_mem) {
+void Controller_ConsoleSixAxis::SetTransferMemoryAddress(Common::ProcessAddress t_mem) {
transfer_memory = t_mem;
}
diff --git a/src/core/hle/service/hid/controllers/console_sixaxis.h b/src/core/hle/service/hid/controllers/console_sixaxis.h
index 8d3e4081b..7015d924c 100644
--- a/src/core/hle/service/hid/controllers/console_sixaxis.h
+++ b/src/core/hle/service/hid/controllers/console_sixaxis.h
@@ -5,8 +5,8 @@
#include <array>
-#include "common/common_types.h"
#include "common/quaternion.h"
+#include "common/typed_address.h"
#include "core/hle/service/hid/controllers/controller_base.h"
#include "core/hle/service/hid/ring_lifo.h"
@@ -34,7 +34,7 @@ public:
void OnUpdate(const Core::Timing::CoreTiming& core_timing) override;
// Called on InitializeSevenSixAxisSensor
- void SetTransferMemoryAddress(VAddr t_mem);
+ void SetTransferMemoryAddress(Common::ProcessAddress t_mem);
// Called on ResetSevenSixAxisSensorTimestamp
void ResetTimestamp();
@@ -66,7 +66,7 @@ private:
static_assert(sizeof(seven_sixaxis_lifo) == 0xA70, "SevenSixAxisState is an invalid size");
SevenSixAxisState next_seven_sixaxis_state{};
- VAddr transfer_memory{};
+ Common::ProcessAddress transfer_memory{};
ConsoleSharedMemory* shared_memory = nullptr;
Core::HID::EmulatedConsole* console = nullptr;
diff --git a/src/core/hle/service/hid/controllers/npad.cpp b/src/core/hle/service/hid/controllers/npad.cpp
index ba6f04d8d..8abf71608 100644
--- a/src/core/hle/service/hid/controllers/npad.cpp
+++ b/src/core/hle/service/hid/controllers/npad.cpp
@@ -70,7 +70,6 @@ Result Controller_NPad::VerifyValidSixAxisSensorHandle(
const Core::HID::SixAxisSensorHandle& device_handle) {
const auto npad_id = IsNpadIdValid(static_cast<Core::HID::NpadIdType>(device_handle.npad_id));
const bool device_index = device_handle.device_index < Core::HID::DeviceIndex::MaxDeviceIndex;
- const bool npad_type = device_handle.npad_type < Core::HID::NpadStyleIndex::MaxNpadType;
if (!npad_id) {
return InvalidNpadId;
@@ -78,10 +77,6 @@ Result Controller_NPad::VerifyValidSixAxisSensorHandle(
if (!device_index) {
return NpadDeviceIndexOutOfRange;
}
- // This doesn't get validated on nnsdk
- if (!npad_type) {
- return NpadInvalidHandle;
- }
return ResultSuccess;
}
@@ -819,12 +814,12 @@ Controller_NPad::NpadCommunicationMode Controller_NPad::GetNpadCommunicationMode
return communication_mode;
}
-Result Controller_NPad::SetNpadMode(Core::HID::NpadIdType npad_id,
- NpadJoyDeviceType npad_device_type,
- NpadJoyAssignmentMode assignment_mode) {
+bool Controller_NPad::SetNpadMode(Core::HID::NpadIdType& new_npad_id, Core::HID::NpadIdType npad_id,
+ NpadJoyDeviceType npad_device_type,
+ NpadJoyAssignmentMode assignment_mode) {
if (!IsNpadIdValid(npad_id)) {
LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id:{}", npad_id);
- return InvalidNpadId;
+ return false;
}
auto& controller = GetControllerFromNpadIdType(npad_id);
@@ -833,7 +828,7 @@ Result Controller_NPad::SetNpadMode(Core::HID::NpadIdType npad_id,
}
if (!controller.device->IsConnected()) {
- return ResultSuccess;
+ return false;
}
if (assignment_mode == NpadJoyAssignmentMode::Dual) {
@@ -842,52 +837,52 @@ Result Controller_NPad::SetNpadMode(Core::HID::NpadIdType npad_id,
controller.is_dual_left_connected = true;
controller.is_dual_right_connected = false;
UpdateControllerAt(Core::HID::NpadStyleIndex::JoyconDual, npad_id, true);
- return ResultSuccess;
+ return false;
}
if (controller.device->GetNpadStyleIndex() == Core::HID::NpadStyleIndex::JoyconRight) {
DisconnectNpad(npad_id);
controller.is_dual_left_connected = false;
controller.is_dual_right_connected = true;
UpdateControllerAt(Core::HID::NpadStyleIndex::JoyconDual, npad_id, true);
- return ResultSuccess;
+ return false;
}
- return ResultSuccess;
+ return false;
}
// This is for NpadJoyAssignmentMode::Single
// Only JoyconDual get affected by this function
if (controller.device->GetNpadStyleIndex() != Core::HID::NpadStyleIndex::JoyconDual) {
- return ResultSuccess;
+ return false;
}
if (controller.is_dual_left_connected && !controller.is_dual_right_connected) {
DisconnectNpad(npad_id);
UpdateControllerAt(Core::HID::NpadStyleIndex::JoyconLeft, npad_id, true);
- return ResultSuccess;
+ return false;
}
if (!controller.is_dual_left_connected && controller.is_dual_right_connected) {
DisconnectNpad(npad_id);
UpdateControllerAt(Core::HID::NpadStyleIndex::JoyconRight, npad_id, true);
- return ResultSuccess;
+ return false;
}
// We have two controllers connected to the same npad_id we need to split them
- const auto npad_id_2 = hid_core.GetFirstDisconnectedNpadId();
- auto& controller_2 = GetControllerFromNpadIdType(npad_id_2);
+ new_npad_id = hid_core.GetFirstDisconnectedNpadId();
+ auto& controller_2 = GetControllerFromNpadIdType(new_npad_id);
DisconnectNpad(npad_id);
if (npad_device_type == NpadJoyDeviceType::Left) {
UpdateControllerAt(Core::HID::NpadStyleIndex::JoyconLeft, npad_id, true);
controller_2.is_dual_left_connected = false;
controller_2.is_dual_right_connected = true;
- UpdateControllerAt(Core::HID::NpadStyleIndex::JoyconDual, npad_id_2, true);
+ UpdateControllerAt(Core::HID::NpadStyleIndex::JoyconDual, new_npad_id, true);
} else {
UpdateControllerAt(Core::HID::NpadStyleIndex::JoyconRight, npad_id, true);
controller_2.is_dual_left_connected = true;
controller_2.is_dual_right_connected = false;
- UpdateControllerAt(Core::HID::NpadStyleIndex::JoyconDual, npad_id_2, true);
+ UpdateControllerAt(Core::HID::NpadStyleIndex::JoyconDual, new_npad_id, true);
}
- return ResultSuccess;
+ return true;
}
bool Controller_NPad::VibrateControllerAtIndex(Core::HID::NpadIdType npad_id,
@@ -1131,6 +1126,7 @@ Result Controller_NPad::DisconnectNpad(Core::HID::NpadIdType npad_id) {
WriteEmptyEntry(shared_memory);
return ResultSuccess;
}
+
Result Controller_NPad::SetGyroscopeZeroDriftMode(
const Core::HID::SixAxisSensorHandle& sixaxis_handle,
Core::HID::GyroscopeZeroDriftMode drift_mode) {
@@ -1388,7 +1384,8 @@ Result Controller_NPad::MergeSingleJoyAsDualJoy(Core::HID::NpadIdType npad_id_1,
return NpadIsDualJoycon;
}
- // Disconnect the joycon at the second id and connect the dual joycon at the first index.
+ // Disconnect the joycons and connect them as dual joycon at the first index.
+ DisconnectNpad(npad_id_1);
DisconnectNpad(npad_id_2);
controller_1.is_dual_left_connected = true;
controller_1.is_dual_right_connected = true;
diff --git a/src/core/hle/service/hid/controllers/npad.h b/src/core/hle/service/hid/controllers/npad.h
index a5998c453..9cfe298f1 100644
--- a/src/core/hle/service/hid/controllers/npad.h
+++ b/src/core/hle/service/hid/controllers/npad.h
@@ -102,8 +102,8 @@ public:
void SetNpadCommunicationMode(NpadCommunicationMode communication_mode_);
NpadCommunicationMode GetNpadCommunicationMode() const;
- Result SetNpadMode(Core::HID::NpadIdType npad_id, NpadJoyDeviceType npad_device_type,
- NpadJoyAssignmentMode assignment_mode);
+ bool SetNpadMode(Core::HID::NpadIdType& new_npad_id, Core::HID::NpadIdType npad_id,
+ NpadJoyDeviceType npad_device_type, NpadJoyAssignmentMode assignment_mode);
bool VibrateControllerAtIndex(Core::HID::NpadIdType npad_id, std::size_t device_index,
const Core::HID::VibrationValue& vibration_value);
diff --git a/src/core/hle/service/hid/controllers/palma.cpp b/src/core/hle/service/hid/controllers/palma.cpp
index bce51285c..14c67e454 100644
--- a/src/core/hle/service/hid/controllers/palma.cpp
+++ b/src/core/hle/service/hid/controllers/palma.cpp
@@ -152,7 +152,7 @@ Result Controller_Palma::WritePalmaRgbLedPatternEntry(const PalmaConnectionHandl
}
Result Controller_Palma::WritePalmaWaveEntry(const PalmaConnectionHandle& handle, PalmaWaveSet wave,
- VAddr t_mem, u64 size) {
+ Common::ProcessAddress t_mem, u64 size) {
if (handle.npad_id != active_handle.npad_id) {
return InvalidPalmaHandle;
}
diff --git a/src/core/hle/service/hid/controllers/palma.h b/src/core/hle/service/hid/controllers/palma.h
index cf62f0dbc..a0491a819 100644
--- a/src/core/hle/service/hid/controllers/palma.h
+++ b/src/core/hle/service/hid/controllers/palma.h
@@ -5,7 +5,7 @@
#include <array>
#include "common/common_funcs.h"
-#include "common/common_types.h"
+#include "common/typed_address.h"
#include "core/hle/service/hid/controllers/controller_base.h"
#include "core/hle/service/hid/errors.h"
@@ -125,8 +125,8 @@ public:
Result ReadPalmaUniqueCode(const PalmaConnectionHandle& handle);
Result SetPalmaUniqueCodeInvalid(const PalmaConnectionHandle& handle);
Result WritePalmaRgbLedPatternEntry(const PalmaConnectionHandle& handle, u64 unknown);
- Result WritePalmaWaveEntry(const PalmaConnectionHandle& handle, PalmaWaveSet wave, VAddr t_mem,
- u64 size);
+ Result WritePalmaWaveEntry(const PalmaConnectionHandle& handle, PalmaWaveSet wave,
+ Common::ProcessAddress t_mem, u64 size);
Result SetPalmaDataBaseIdentificationVersion(const PalmaConnectionHandle& handle,
s32 database_id_version_);
Result GetPalmaDataBaseIdentificationVersion(const PalmaConnectionHandle& handle);
diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp
index 4529ad643..87e7b864a 100644
--- a/src/core/hle/service/hid/hid.cpp
+++ b/src/core/hle/service/hid/hid.cpp
@@ -302,7 +302,7 @@ Hid::Hid(Core::System& system_)
{130, &Hid::SwapNpadAssignment, "SwapNpadAssignment"},
{131, &Hid::IsUnintendedHomeButtonInputProtectionEnabled, "IsUnintendedHomeButtonInputProtectionEnabled"},
{132, &Hid::EnableUnintendedHomeButtonInputProtection, "EnableUnintendedHomeButtonInputProtection"},
- {133, nullptr, "SetNpadJoyAssignmentModeSingleWithDestination"},
+ {133, &Hid::SetNpadJoyAssignmentModeSingleWithDestination, "SetNpadJoyAssignmentModeSingleWithDestination"},
{134, &Hid::SetNpadAnalogStickUseCenterClamp, "SetNpadAnalogStickUseCenterClamp"},
{135, &Hid::SetNpadCaptureButtonAssignment, "SetNpadCaptureButtonAssignment"},
{136, &Hid::ClearNpadCaptureButtonAssignment, "ClearNpadCaptureButtonAssignment"},
@@ -1180,8 +1180,10 @@ void Hid::SetNpadJoyAssignmentModeSingleByDefault(HLERequestContext& ctx) {
const auto parameters{rp.PopRaw<Parameters>()};
+ Core::HID::NpadIdType new_npad_id{};
auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad);
- controller.SetNpadMode(parameters.npad_id, Controller_NPad::NpadJoyDeviceType::Left,
+ controller.SetNpadMode(new_npad_id, parameters.npad_id,
+ Controller_NPad::NpadJoyDeviceType::Left,
Controller_NPad::NpadJoyAssignmentMode::Single);
LOG_INFO(Service_HID, "called, npad_id={}, applet_resource_user_id={}", parameters.npad_id,
@@ -1203,8 +1205,9 @@ void Hid::SetNpadJoyAssignmentModeSingle(HLERequestContext& ctx) {
const auto parameters{rp.PopRaw<Parameters>()};
+ Core::HID::NpadIdType new_npad_id{};
auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad);
- controller.SetNpadMode(parameters.npad_id, parameters.npad_joy_device_type,
+ controller.SetNpadMode(new_npad_id, parameters.npad_id, parameters.npad_joy_device_type,
Controller_NPad::NpadJoyAssignmentMode::Single);
LOG_INFO(Service_HID, "called, npad_id={}, applet_resource_user_id={}, npad_joy_device_type={}",
@@ -1226,8 +1229,10 @@ void Hid::SetNpadJoyAssignmentModeDual(HLERequestContext& ctx) {
const auto parameters{rp.PopRaw<Parameters>()};
+ Core::HID::NpadIdType new_npad_id{};
auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad);
- controller.SetNpadMode(parameters.npad_id, {}, Controller_NPad::NpadJoyAssignmentMode::Dual);
+ controller.SetNpadMode(new_npad_id, parameters.npad_id, {},
+ Controller_NPad::NpadJoyAssignmentMode::Dual);
LOG_INFO(Service_HID, "called, npad_id={}, applet_resource_user_id={}", parameters.npad_id,
parameters.applet_resource_user_id);
@@ -1369,6 +1374,34 @@ void Hid::EnableUnintendedHomeButtonInputProtection(HLERequestContext& ctx) {
rb.Push(result);
}
+void Hid::SetNpadJoyAssignmentModeSingleWithDestination(HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ struct Parameters {
+ Core::HID::NpadIdType npad_id;
+ INSERT_PADDING_WORDS_NOINIT(1);
+ u64 applet_resource_user_id;
+ Controller_NPad::NpadJoyDeviceType npad_joy_device_type;
+ };
+ static_assert(sizeof(Parameters) == 0x18, "Parameters has incorrect size.");
+
+ const auto parameters{rp.PopRaw<Parameters>()};
+
+ Core::HID::NpadIdType new_npad_id{};
+ auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad);
+ const auto is_reassigned =
+ controller.SetNpadMode(new_npad_id, parameters.npad_id, parameters.npad_joy_device_type,
+ Controller_NPad::NpadJoyAssignmentMode::Single);
+
+ LOG_INFO(Service_HID, "called, npad_id={}, applet_resource_user_id={}, npad_joy_device_type={}",
+ parameters.npad_id, parameters.applet_resource_user_id,
+ parameters.npad_joy_device_type);
+
+ IPC::ResponseBuilder rb{ctx, 4};
+ rb.Push(ResultSuccess);
+ rb.Push(is_reassigned);
+ rb.PushEnum(new_npad_id);
+}
+
void Hid::SetNpadAnalogStickUseCenterClamp(HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
struct Parameters {
diff --git a/src/core/hle/service/hid/hid.h b/src/core/hle/service/hid/hid.h
index c69e5f3fb..f247b83c2 100644
--- a/src/core/hle/service/hid/hid.h
+++ b/src/core/hle/service/hid/hid.h
@@ -151,6 +151,7 @@ private:
void SwapNpadAssignment(HLERequestContext& ctx);
void IsUnintendedHomeButtonInputProtectionEnabled(HLERequestContext& ctx);
void EnableUnintendedHomeButtonInputProtection(HLERequestContext& ctx);
+ void SetNpadJoyAssignmentModeSingleWithDestination(HLERequestContext& ctx);
void SetNpadAnalogStickUseCenterClamp(HLERequestContext& ctx);
void SetNpadCaptureButtonAssignment(HLERequestContext& ctx);
void ClearNpadCaptureButtonAssignment(HLERequestContext& ctx);
diff --git a/src/core/hle/service/hid/hidbus/hidbus_base.cpp b/src/core/hle/service/hid/hidbus/hidbus_base.cpp
index dfd23ec04..ee522c36e 100644
--- a/src/core/hle/service/hid/hidbus/hidbus_base.cpp
+++ b/src/core/hle/service/hid/hidbus/hidbus_base.cpp
@@ -59,7 +59,7 @@ void HidbusBase::DisablePollingMode() {
polling_mode_enabled = false;
}
-void HidbusBase::SetTransferMemoryAddress(VAddr t_mem) {
+void HidbusBase::SetTransferMemoryAddress(Common::ProcessAddress t_mem) {
transfer_memory = t_mem;
}
diff --git a/src/core/hle/service/hid/hidbus/hidbus_base.h b/src/core/hle/service/hid/hidbus/hidbus_base.h
index 26313264d..ec41684e1 100644
--- a/src/core/hle/service/hid/hidbus/hidbus_base.h
+++ b/src/core/hle/service/hid/hidbus/hidbus_base.h
@@ -5,7 +5,7 @@
#include <array>
#include <span>
-#include "common/common_types.h"
+#include "common/typed_address.h"
#include "core/hle/result.h"
namespace Core {
@@ -138,7 +138,7 @@ public:
void DisablePollingMode();
// Called on EnableJoyPollingReceiveMode
- void SetTransferMemoryAddress(VAddr t_mem);
+ void SetTransferMemoryAddress(Common::ProcessAddress t_mem);
Kernel::KReadableEvent& GetSendCommandAsycEvent() const;
@@ -174,7 +174,7 @@ protected:
JoyEnableSixAxisDataAccessor enable_sixaxis_data{};
ButtonOnlyPollingDataAccessor button_only_data{};
- VAddr transfer_memory{};
+ Common::ProcessAddress transfer_memory{};
Core::System& system;
Kernel::KEvent* send_command_async_event;
diff --git a/src/core/hle/service/hid/hidbus/ringcon.cpp b/src/core/hle/service/hid/hidbus/ringcon.cpp
index 65a2dd521..378108012 100644
--- a/src/core/hle/service/hid/hidbus/ringcon.cpp
+++ b/src/core/hle/service/hid/hidbus/ringcon.cpp
@@ -64,8 +64,8 @@ void RingController::OnUpdate() {
curr_entry.polling_data.out_size = sizeof(ringcon_value);
std::memcpy(curr_entry.polling_data.data.data(), &ringcon_value, sizeof(ringcon_value));
- system.Memory().WriteBlock(transfer_memory, &enable_sixaxis_data,
- sizeof(enable_sixaxis_data));
+ system.ApplicationMemory().WriteBlock(transfer_memory, &enable_sixaxis_data,
+ sizeof(enable_sixaxis_data));
break;
}
default:
diff --git a/src/core/hle/service/hid/irsensor/image_transfer_processor.cpp b/src/core/hle/service/hid/irsensor/image_transfer_processor.cpp
index a268750cd..803a6277c 100644
--- a/src/core/hle/service/hid/irsensor/image_transfer_processor.cpp
+++ b/src/core/hle/service/hid/irsensor/image_transfer_processor.cpp
@@ -58,16 +58,16 @@ void ImageTransferProcessor::OnControllerUpdate(Core::HID::ControllerTriggerType
if (camera_data.format != current_config.origin_format) {
LOG_WARNING(Service_IRS, "Wrong Input format {} expected {}", camera_data.format,
current_config.origin_format);
- system.Memory().ZeroBlock(*system.ApplicationProcess(), transfer_memory,
- GetDataSize(current_config.trimming_format));
+ system.ApplicationMemory().ZeroBlock(transfer_memory,
+ GetDataSize(current_config.trimming_format));
return;
}
if (current_config.origin_format > current_config.trimming_format) {
LOG_WARNING(Service_IRS, "Origin format {} is smaller than trimming format {}",
current_config.origin_format, current_config.trimming_format);
- system.Memory().ZeroBlock(*system.ApplicationProcess(), transfer_memory,
- GetDataSize(current_config.trimming_format));
+ system.ApplicationMemory().ZeroBlock(transfer_memory,
+ GetDataSize(current_config.trimming_format));
return;
}
@@ -84,8 +84,8 @@ void ImageTransferProcessor::OnControllerUpdate(Core::HID::ControllerTriggerType
"Trimming area ({}, {}, {}, {}) is outside of origin area ({}, {})",
current_config.trimming_start_x, current_config.trimming_start_y,
trimming_width, trimming_height, origin_width, origin_height);
- system.Memory().ZeroBlock(*system.ApplicationProcess(), transfer_memory,
- GetDataSize(current_config.trimming_format));
+ system.ApplicationMemory().ZeroBlock(transfer_memory,
+ GetDataSize(current_config.trimming_format));
return;
}
@@ -99,8 +99,8 @@ void ImageTransferProcessor::OnControllerUpdate(Core::HID::ControllerTriggerType
}
}
- system.Memory().WriteBlock(transfer_memory, window_data.data(),
- GetDataSize(current_config.trimming_format));
+ system.ApplicationMemory().WriteBlock(transfer_memory, window_data.data(),
+ GetDataSize(current_config.trimming_format));
if (!IsProcessorActive()) {
StartProcessor();
@@ -140,7 +140,7 @@ void ImageTransferProcessor::SetConfig(
npad_device->SetCameraFormat(current_config.origin_format);
}
-void ImageTransferProcessor::SetTransferMemoryAddress(VAddr t_mem) {
+void ImageTransferProcessor::SetTransferMemoryAddress(Common::ProcessAddress t_mem) {
transfer_memory = t_mem;
}
@@ -148,7 +148,7 @@ Core::IrSensor::ImageTransferProcessorState ImageTransferProcessor::GetState(
std::vector<u8>& data) const {
const auto size = GetDataSize(current_config.trimming_format);
data.resize(size);
- system.Memory().ReadBlock(transfer_memory, data.data(), size);
+ system.ApplicationMemory().ReadBlock(transfer_memory, data.data(), size);
return processor_state;
}
diff --git a/src/core/hle/service/hid/irsensor/image_transfer_processor.h b/src/core/hle/service/hid/irsensor/image_transfer_processor.h
index 7cfe04c8c..7f42d8453 100644
--- a/src/core/hle/service/hid/irsensor/image_transfer_processor.h
+++ b/src/core/hle/service/hid/irsensor/image_transfer_processor.h
@@ -3,7 +3,7 @@
#pragma once
-#include "common/common_types.h"
+#include "common/typed_address.h"
#include "core/hid/irs_types.h"
#include "core/hle/service/hid/irsensor/processor_base.h"
@@ -37,7 +37,7 @@ public:
void SetConfig(Core::IrSensor::PackedImageTransferProcessorExConfig config);
// Transfer memory where the image data will be stored
- void SetTransferMemoryAddress(VAddr t_mem);
+ void SetTransferMemoryAddress(Common::ProcessAddress t_mem);
Core::IrSensor::ImageTransferProcessorState GetState(std::vector<u8>& data) const;
@@ -72,6 +72,6 @@ private:
int callback_key{};
Core::System& system;
- VAddr transfer_memory{};
+ Common::ProcessAddress transfer_memory{};
};
} // namespace Service::IRS
diff --git a/src/core/hle/service/hle_ipc.cpp b/src/core/hle/service/hle_ipc.cpp
index cca697c64..2290df705 100644
--- a/src/core/hle/service/hle_ipc.cpp
+++ b/src/core/hle/service/hle_ipc.cpp
@@ -303,8 +303,7 @@ Result HLERequestContext::WriteToOutgoingCommandBuffer(Kernel::KThread& requesti
}
// Copy the translated command buffer back into the thread's command buffer area.
- memory.WriteBlock(owner_process, requesting_thread.GetTlsAddress(), cmd_buf.data(),
- write_size * sizeof(u32));
+ memory.WriteBlock(requesting_thread.GetTlsAddress(), cmd_buf.data(), write_size * sizeof(u32));
return ResultSuccess;
}
diff --git a/src/core/hle/service/jit/jit.cpp b/src/core/hle/service/jit/jit.cpp
index 46bcfd695..be996870f 100644
--- a/src/core/hle/service/jit/jit.cpp
+++ b/src/core/hle/service/jit/jit.cpp
@@ -24,8 +24,8 @@ class IJitEnvironment final : public ServiceFramework<IJitEnvironment> {
public:
explicit IJitEnvironment(Core::System& system_, Kernel::KProcess& process_, CodeRange user_rx,
CodeRange user_ro)
- : ServiceFramework{system_, "IJitEnvironment"}, process{&process_}, context{
- system_.Memory()} {
+ : ServiceFramework{system_, "IJitEnvironment"}, process{&process_},
+ context{system_.ApplicationMemory()} {
// clang-format off
static const FunctionInfo functions[] = {
{0, &IJitEnvironment::GenerateCode, "GenerateCode"},
@@ -195,7 +195,7 @@ public:
}
// Set up the configuration with the required TransferMemory address
- configuration.transfer_memory.offset = tmem->GetSourceAddress();
+ configuration.transfer_memory.offset = GetInteger(tmem->GetSourceAddress());
configuration.transfer_memory.size = tmem_size;
// Gather up all the callbacks from the loaded plugin
@@ -383,12 +383,12 @@ public:
}
const CodeRange user_rx{
- .offset = rx_mem->GetSourceAddress(),
+ .offset = GetInteger(rx_mem->GetSourceAddress()),
.size = parameters.rx_size,
};
const CodeRange user_ro{
- .offset = ro_mem->GetSourceAddress(),
+ .offset = GetInteger(ro_mem->GetSourceAddress()),
.size = parameters.ro_size,
};
diff --git a/src/core/hle/service/ldr/ldr.cpp b/src/core/hle/service/ldr/ldr.cpp
index 6de96ed5b..c42489ff9 100644
--- a/src/core/hle/service/ldr/ldr.cpp
+++ b/src/core/hle/service/ldr/ldr.cpp
@@ -225,7 +225,7 @@ public:
// Read NRR data from memory
std::vector<u8> nrr_data(nrr_size);
- system.Memory().ReadBlock(nrr_address, nrr_data.data(), nrr_size);
+ system.ApplicationMemory().ReadBlock(nrr_address, nrr_data.data(), nrr_size);
NRRHeader header;
std::memcpy(&header, nrr_data.data(), sizeof(NRRHeader));
@@ -314,7 +314,7 @@ public:
const auto is_region_available = [&](VAddr addr) {
const auto end_addr = addr + size;
while (addr < end_addr) {
- if (system.Memory().IsValidVirtualAddress(addr)) {
+ if (system.ApplicationMemory().IsValidVirtualAddress(addr)) {
return false;
}
@@ -337,7 +337,7 @@ public:
bool succeeded = false;
const auto map_region_end =
- page_table.GetAliasCodeRegionStart() + page_table.GetAliasCodeRegionSize();
+ GetInteger(page_table.GetAliasCodeRegionStart()) + page_table.GetAliasCodeRegionSize();
while (current_map_addr < map_region_end) {
if (is_region_available(current_map_addr)) {
succeeded = true;
@@ -427,8 +427,8 @@ public:
const VAddr bss_end_addr{
Common::AlignUp(bss_start + nro_header.bss_size, Kernel::PageSize)};
- const auto CopyCode = [this, process](VAddr src_addr, VAddr dst_addr, u64 size) {
- system.Memory().CopyBlock(*process, dst_addr, src_addr, size);
+ const auto CopyCode = [this](VAddr src_addr, VAddr dst_addr, u64 size) {
+ system.ApplicationMemory().CopyBlock(dst_addr, src_addr, size);
};
CopyCode(nro_addr + nro_header.segment_headers[TEXT_INDEX].memory_offset, text_start,
nro_header.segment_headers[TEXT_INDEX].memory_size);
@@ -506,7 +506,7 @@ public:
// Read NRO data from memory
std::vector<u8> nro_data(nro_size);
- system.Memory().ReadBlock(nro_address, nro_data.data(), nro_size);
+ system.ApplicationMemory().ReadBlock(nro_address, nro_data.data(), nro_size);
SHA256Hash hash{};
mbedtls_sha256_ret(nro_data.data(), nro_data.size(), hash.data(), 0);
@@ -642,7 +642,8 @@ public:
LOG_WARNING(Service_LDR, "(STUBBED) called");
initialized = true;
- current_map_addr = system.ApplicationProcess()->PageTable().GetAliasCodeRegionStart();
+ current_map_addr =
+ GetInteger(system.ApplicationProcess()->PageTable().GetAliasCodeRegionStart());
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
diff --git a/src/core/hle/service/mii/mii_manager.cpp b/src/core/hle/service/mii/mii_manager.cpp
index 3a2fe938f..c920650f5 100644
--- a/src/core/hle/service/mii/mii_manager.cpp
+++ b/src/core/hle/service/mii/mii_manager.cpp
@@ -510,7 +510,7 @@ CharInfo MiiManager::ConvertV3ToCharInfo(const Ver3StoreData& mii_v3) const {
return mii;
}
-Ver3StoreData MiiManager::ConvertCharInfoToV3(const CharInfo& mii) const {
+Ver3StoreData MiiManager::BuildFromStoreData(const CharInfo& mii) const {
Service::Mii::MiiManager manager;
Ver3StoreData mii_v3{};
@@ -534,16 +534,13 @@ Ver3StoreData MiiManager::ConvertCharInfoToV3(const CharInfo& mii) const {
mii_v3.region_information.character_set.Assign(mii.font_region);
mii_v3.appearance_bits1.face_shape.Assign(mii.faceline_type);
- mii_v3.appearance_bits1.skin_color.Assign(mii.faceline_color);
mii_v3.appearance_bits2.wrinkles.Assign(mii.faceline_wrinkle);
mii_v3.appearance_bits2.makeup.Assign(mii.faceline_make);
mii_v3.hair_style = mii.hair_type;
- mii_v3.appearance_bits3.hair_color.Assign(mii.hair_color);
mii_v3.appearance_bits3.flip_hair.Assign(mii.hair_flip);
mii_v3.appearance_bits4.eye_type.Assign(mii.eye_type);
- mii_v3.appearance_bits4.eye_color.Assign(mii.eye_color);
mii_v3.appearance_bits4.eye_scale.Assign(mii.eye_scale);
mii_v3.appearance_bits4.eye_vertical_stretch.Assign(mii.eye_aspect);
mii_v3.appearance_bits4.eye_rotation.Assign(mii.eye_rotate);
@@ -551,7 +548,6 @@ Ver3StoreData MiiManager::ConvertCharInfoToV3(const CharInfo& mii) const {
mii_v3.appearance_bits4.eye_y_position.Assign(mii.eye_y);
mii_v3.appearance_bits5.eyebrow_style.Assign(mii.eyebrow_type);
- mii_v3.appearance_bits5.eyebrow_color.Assign(mii.eyebrow_color);
mii_v3.appearance_bits5.eyebrow_scale.Assign(mii.eyebrow_scale);
mii_v3.appearance_bits5.eyebrow_yscale.Assign(mii.eyebrow_aspect);
mii_v3.appearance_bits5.eyebrow_rotation.Assign(mii.eyebrow_rotate);
@@ -563,7 +559,6 @@ Ver3StoreData MiiManager::ConvertCharInfoToV3(const CharInfo& mii) const {
mii_v3.appearance_bits6.nose_y_position.Assign(mii.nose_y);
mii_v3.appearance_bits7.mouth_type.Assign(mii.mouth_type);
- mii_v3.appearance_bits7.mouth_color.Assign(mii.mouth_color);
mii_v3.appearance_bits7.mouth_scale.Assign(mii.mouth_scale);
mii_v3.appearance_bits7.mouth_horizontal_stretch.Assign(mii.mouth_aspect);
mii_v3.appearance_bits8.mouth_y_position.Assign(mii.mouth_y);
@@ -573,10 +568,7 @@ Ver3StoreData MiiManager::ConvertCharInfoToV3(const CharInfo& mii) const {
mii_v3.appearance_bits9.mustache_y_position.Assign(mii.mustache_y);
mii_v3.appearance_bits9.bear_type.Assign(mii.beard_type);
- mii_v3.appearance_bits9.facial_hair_color.Assign(mii.beard_color);
- mii_v3.appearance_bits10.glasses_type.Assign(mii.glasses_type);
- mii_v3.appearance_bits10.glasses_color.Assign(mii.glasses_color);
mii_v3.appearance_bits10.glasses_scale.Assign(mii.glasses_scale);
mii_v3.appearance_bits10.glasses_y_position.Assign(mii.glasses_y);
@@ -585,11 +577,36 @@ Ver3StoreData MiiManager::ConvertCharInfoToV3(const CharInfo& mii) const {
mii_v3.appearance_bits11.mole_x_position.Assign(mii.mole_x);
mii_v3.appearance_bits11.mole_y_position.Assign(mii.mole_y);
+ // These types are converted to V3 from a table
+ mii_v3.appearance_bits1.skin_color.Assign(Ver3FacelineColorTable[mii.faceline_color]);
+ mii_v3.appearance_bits3.hair_color.Assign(Ver3HairColorTable[mii.hair_color]);
+ mii_v3.appearance_bits4.eye_color.Assign(Ver3EyeColorTable[mii.eye_color]);
+ mii_v3.appearance_bits5.eyebrow_color.Assign(Ver3HairColorTable[mii.eyebrow_color]);
+ mii_v3.appearance_bits7.mouth_color.Assign(Ver3MouthlineColorTable[mii.mouth_color]);
+ mii_v3.appearance_bits9.facial_hair_color.Assign(Ver3HairColorTable[mii.beard_color]);
+ mii_v3.appearance_bits10.glasses_color.Assign(Ver3GlassColorTable[mii.glasses_color]);
+ mii_v3.appearance_bits10.glasses_type.Assign(Ver3GlassTypeTable[mii.glasses_type]);
+
+ mii_v3.crc = GenerateCrc16(&mii_v3, sizeof(Ver3StoreData) - sizeof(u16));
+
// TODO: Validate mii_v3 data
return mii_v3;
}
+NfpStoreDataExtension MiiManager::SetFromStoreData(const CharInfo& mii) const {
+ return {
+ .faceline_color = static_cast<u8>(mii.faceline_color & 0xf),
+ .hair_color = static_cast<u8>(mii.hair_color & 0x7f),
+ .eye_color = static_cast<u8>(mii.eyebrow_color & 0x7f),
+ .eyebrow_color = static_cast<u8>(mii.eyebrow_color & 0x7f),
+ .mouth_color = static_cast<u8>(mii.mouth_color & 0x7f),
+ .beard_color = static_cast<u8>(mii.beard_color & 0x7f),
+ .glass_color = static_cast<u8>(mii.glasses_color & 0x7f),
+ .glass_type = static_cast<u8>(mii.glasses_type & 0x1f),
+ };
+}
+
bool MiiManager::ValidateV3Info(const Ver3StoreData& mii_v3) const {
bool is_valid = mii_v3.version == 0 || mii_v3.version == 3;
diff --git a/src/core/hle/service/mii/mii_manager.h b/src/core/hle/service/mii/mii_manager.h
index 83ad3d343..5525fcd1c 100644
--- a/src/core/hle/service/mii/mii_manager.h
+++ b/src/core/hle/service/mii/mii_manager.h
@@ -23,11 +23,16 @@ public:
CharInfo BuildRandom(Age age, Gender gender, Race race);
CharInfo BuildDefault(std::size_t index);
CharInfo ConvertV3ToCharInfo(const Ver3StoreData& mii_v3) const;
- Ver3StoreData ConvertCharInfoToV3(const CharInfo& mii) const;
bool ValidateV3Info(const Ver3StoreData& mii_v3) const;
ResultVal<std::vector<MiiInfoElement>> GetDefault(SourceFlag source_flag);
Result GetIndex(const CharInfo& info, u32& index);
+ // This is nn::mii::detail::Ver::StoreDataRaw::BuildFromStoreData
+ Ver3StoreData BuildFromStoreData(const CharInfo& mii) const;
+
+ // This is nn::mii::detail::NfpStoreDataExtentionRaw::SetFromStoreData
+ NfpStoreDataExtension SetFromStoreData(const CharInfo& mii) const;
+
private:
const Common::UUID user_id{};
u64 update_counter{};
diff --git a/src/core/hle/service/mii/types.h b/src/core/hle/service/mii/types.h
index 9e3247397..c48d08d79 100644
--- a/src/core/hle/service/mii/types.h
+++ b/src/core/hle/service/mii/types.h
@@ -365,10 +365,68 @@ struct Ver3StoreData {
} appearance_bits11;
std::array<u16_le, 0xA> author_name;
- INSERT_PADDING_BYTES(0x4);
+ INSERT_PADDING_BYTES(0x2);
+ u16_be crc;
};
static_assert(sizeof(Ver3StoreData) == 0x60, "Ver3StoreData is an invalid size");
+struct NfpStoreDataExtension {
+ u8 faceline_color;
+ u8 hair_color;
+ u8 eye_color;
+ u8 eyebrow_color;
+ u8 mouth_color;
+ u8 beard_color;
+ u8 glass_color;
+ u8 glass_type;
+};
+static_assert(sizeof(NfpStoreDataExtension) == 0x8, "NfpStoreDataExtension is an invalid size");
+
+constexpr std::array<u8, 0x10> Ver3FacelineColorTable{
+ 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x0, 0x1, 0x5, 0x5,
+};
+
+constexpr std::array<u8, 100> Ver3HairColorTable{
+ 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x0, 0x4, 0x3, 0x5, 0x4, 0x4, 0x6, 0x2, 0x0,
+ 0x6, 0x4, 0x3, 0x2, 0x2, 0x7, 0x3, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2,
+ 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x0, 0x0, 0x4,
+ 0x4, 0x4, 0x4, 0x4, 0x4, 0x0, 0x0, 0x0, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x5, 0x5, 0x5,
+ 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x5, 0x7, 0x5, 0x7, 0x7, 0x7, 0x7, 0x7, 0x6, 0x7,
+ 0x7, 0x7, 0x7, 0x7, 0x3, 0x7, 0x7, 0x7, 0x7, 0x7, 0x0, 0x4, 0x4, 0x4, 0x4,
+};
+
+constexpr std::array<u8, 100> Ver3EyeColorTable{
+ 0x0, 0x2, 0x2, 0x2, 0x1, 0x3, 0x2, 0x3, 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x2, 0x2, 0x4,
+ 0x2, 0x1, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2,
+ 0x2, 0x2, 0x2, 0x2, 0x0, 0x0, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x1, 0x0, 0x4, 0x4,
+ 0x4, 0x4, 0x4, 0x4, 0x4, 0x0, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5,
+ 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x2, 0x2,
+ 0x3, 0x3, 0x3, 0x3, 0x2, 0x2, 0x2, 0x2, 0x2, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,
+};
+
+constexpr std::array<u8, 100> Ver3MouthlineColorTable{
+ 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x3, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x1, 0x4,
+ 0x4, 0x4, 0x0, 0x1, 0x2, 0x3, 0x4, 0x4, 0x2, 0x3, 0x3, 0x4, 0x4, 0x4, 0x4, 0x1, 0x4,
+ 0x4, 0x2, 0x3, 0x3, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x3, 0x3, 0x3, 0x4, 0x4, 0x4,
+ 0x3, 0x3, 0x3, 0x3, 0x3, 0x4, 0x4, 0x4, 0x4, 0x4, 0x3, 0x3, 0x3, 0x3, 0x4, 0x4, 0x4,
+ 0x4, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x4, 0x4, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x4, 0x3,
+ 0x3, 0x3, 0x3, 0x3, 0x4, 0x0, 0x3, 0x3, 0x3, 0x3, 0x4, 0x3, 0x3, 0x3, 0x3,
+};
+
+constexpr std::array<u8, 100> Ver3GlassColorTable{
+ 0x0, 0x1, 0x1, 0x1, 0x5, 0x1, 0x1, 0x4, 0x0, 0x5, 0x1, 0x1, 0x3, 0x5, 0x1, 0x2, 0x3,
+ 0x4, 0x5, 0x4, 0x2, 0x2, 0x4, 0x4, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2,
+ 0x2, 0x2, 0x2, 0x2, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3,
+ 0x3, 0x3, 0x3, 0x3, 0x3, 0x0, 0x0, 0x0, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x0, 0x5, 0x5,
+ 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5, 0x1, 0x4,
+ 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x5, 0x5, 0x5, 0x5, 0x5, 0x5,
+};
+
+constexpr std::array<u8, 20> Ver3GlassTypeTable{
+ 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x1,
+ 0x2, 0x1, 0x3, 0x7, 0x7, 0x6, 0x7, 0x8, 0x7, 0x7,
+};
+
struct MiiStoreData {
using Name = std::array<char16_t, 10>;
diff --git a/src/core/hle/service/nfc/nfc_device.cpp b/src/core/hle/service/nfc/nfc_device.cpp
index 3f17d0c7a..c7db74d14 100644
--- a/src/core/hle/service/nfc/nfc_device.cpp
+++ b/src/core/hle/service/nfc/nfc_device.cpp
@@ -42,8 +42,18 @@ NfcDevice::~NfcDevice() {
};
void NfcDevice::NpadUpdate(Core::HID::ControllerTriggerType type) {
- if (type == Core::HID::ControllerTriggerType::Connected ||
- type == Core::HID::ControllerTriggerType::Disconnected) {
+ if (!is_initalized) {
+ return;
+ }
+
+ if (type == Core::HID::ControllerTriggerType::Connected) {
+ Initialize();
+ availability_change_event->Signal();
+ return;
+ }
+
+ if (type == Core::HID::ControllerTriggerType::Disconnected) {
+ device_state = NFP::DeviceState::Unavailable;
availability_change_event->Signal();
return;
}
@@ -113,6 +123,7 @@ void NfcDevice::Initialize() {
device_state =
npad_device->HasNfc() ? NFP::DeviceState::Initialized : NFP::DeviceState::Unavailable;
encrypted_tag_data = {};
+ is_initalized = true;
}
void NfcDevice::Finalize() {
@@ -121,6 +132,7 @@ void NfcDevice::Finalize() {
StopDetection();
}
device_state = NFP::DeviceState::Unavailable;
+ is_initalized = false;
}
Result NfcDevice::StartDetection(NFP::TagProtocol allowed_protocol) {
diff --git a/src/core/hle/service/nfc/nfc_device.h b/src/core/hle/service/nfc/nfc_device.h
index a6e114d36..ea63f0537 100644
--- a/src/core/hle/service/nfc/nfc_device.h
+++ b/src/core/hle/service/nfc/nfc_device.h
@@ -67,6 +67,7 @@ private:
Kernel::KEvent* deactivate_event = nullptr;
Kernel::KEvent* availability_change_event = nullptr;
+ bool is_initalized{};
NFP::TagProtocol allowed_protocols{};
NFP::DeviceState device_state{NFP::DeviceState::Unavailable};
diff --git a/src/core/hle/service/nfp/amiibo_crypto.cpp b/src/core/hle/service/nfp/amiibo_crypto.cpp
index ad73edbda..a3622e792 100644
--- a/src/core/hle/service/nfp/amiibo_crypto.cpp
+++ b/src/core/hle/service/nfp/amiibo_crypto.cpp
@@ -70,6 +70,10 @@ bool IsAmiiboValid(const EncryptedNTAG215File& ntag_file) {
return true;
}
+bool IsAmiiboValid(const NTAG215File& ntag_file) {
+ return IsAmiiboValid(EncodedDataToNfcData(ntag_file));
+}
+
NTAG215File NfcDataToEncodedData(const EncryptedNTAG215File& nfc_data) {
NTAG215File encoded_data{};
@@ -88,8 +92,9 @@ NTAG215File NfcDataToEncodedData(const EncryptedNTAG215File& nfc_data) {
encoded_data.application_area_id = nfc_data.user_memory.application_area_id;
encoded_data.application_id_byte = nfc_data.user_memory.application_id_byte;
encoded_data.unknown = nfc_data.user_memory.unknown;
+ encoded_data.mii_extension = nfc_data.user_memory.mii_extension;
encoded_data.unknown2 = nfc_data.user_memory.unknown2;
- encoded_data.application_area_crc = nfc_data.user_memory.application_area_crc;
+ encoded_data.register_info_crc = nfc_data.user_memory.register_info_crc;
encoded_data.application_area = nfc_data.user_memory.application_area;
encoded_data.hmac_tag = nfc_data.user_memory.hmac_tag;
encoded_data.lock_bytes = nfc_data.uuid.lock_bytes;
@@ -122,8 +127,9 @@ EncryptedNTAG215File EncodedDataToNfcData(const NTAG215File& encoded_data) {
nfc_data.user_memory.application_area_id = encoded_data.application_area_id;
nfc_data.user_memory.application_id_byte = encoded_data.application_id_byte;
nfc_data.user_memory.unknown = encoded_data.unknown;
+ nfc_data.user_memory.mii_extension = encoded_data.mii_extension;
nfc_data.user_memory.unknown2 = encoded_data.unknown2;
- nfc_data.user_memory.application_area_crc = encoded_data.application_area_crc;
+ nfc_data.user_memory.register_info_crc = encoded_data.register_info_crc;
nfc_data.user_memory.application_area = encoded_data.application_area;
nfc_data.user_memory.hmac_tag = encoded_data.hmac_tag;
nfc_data.user_memory.model_info = encoded_data.model_info;
diff --git a/src/core/hle/service/nfp/amiibo_crypto.h b/src/core/hle/service/nfp/amiibo_crypto.h
index c9fd67a39..f6208ee6b 100644
--- a/src/core/hle/service/nfp/amiibo_crypto.h
+++ b/src/core/hle/service/nfp/amiibo_crypto.h
@@ -60,6 +60,9 @@ static_assert(sizeof(DerivedKeys) == 0x30, "DerivedKeys is an invalid size");
/// Validates that the amiibo file is not corrupted
bool IsAmiiboValid(const EncryptedNTAG215File& ntag_file);
+/// Validates that the amiibo file is not corrupted
+bool IsAmiiboValid(const NTAG215File& ntag_file);
+
/// Converts from encrypted file format to encoded file format
NTAG215File NfcDataToEncodedData(const EncryptedNTAG215File& nfc_data);
diff --git a/src/core/hle/service/nfp/nfp_device.cpp b/src/core/hle/service/nfp/nfp_device.cpp
index ddff90d6a..607e70968 100644
--- a/src/core/hle/service/nfp/nfp_device.cpp
+++ b/src/core/hle/service/nfp/nfp_device.cpp
@@ -3,6 +3,17 @@
#include <array>
+#ifdef _MSC_VER
+#pragma warning(push)
+#pragma warning(disable : 4701) // Potentially uninitialized local variable 'result' used
+#endif
+
+#include <boost/crc.hpp>
+
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+
#include "common/input.h"
#include "common/logging/log.h"
#include "common/string_util.h"
@@ -55,8 +66,18 @@ NfpDevice::~NfpDevice() {
};
void NfpDevice::NpadUpdate(Core::HID::ControllerTriggerType type) {
- if (type == Core::HID::ControllerTriggerType::Connected ||
- type == Core::HID::ControllerTriggerType::Disconnected) {
+ if (!is_initalized) {
+ return;
+ }
+
+ if (type == Core::HID::ControllerTriggerType::Connected) {
+ Initialize();
+ availability_change_event->Signal();
+ return;
+ }
+
+ if (type == Core::HID::ControllerTriggerType::Disconnected) {
+ device_state = DeviceState::Unavailable;
availability_change_event->Signal();
return;
}
@@ -100,7 +121,16 @@ bool NfpDevice::LoadAmiibo(std::span<const u8> data) {
// TODO: Filter by allowed_protocols here
- memcpy(&encrypted_tag_data, data.data(), sizeof(EncryptedNTAG215File));
+ memcpy(&tag_data, data.data(), sizeof(EncryptedNTAG215File));
+ is_plain_amiibo = AmiiboCrypto::IsAmiiboValid(tag_data);
+
+ if (is_plain_amiibo) {
+ encrypted_tag_data = AmiiboCrypto::EncodedDataToNfcData(tag_data);
+ LOG_INFO(Service_NFP, "Using plain amiibo");
+ } else {
+ tag_data = {};
+ memcpy(&encrypted_tag_data, data.data(), sizeof(EncryptedNTAG215File));
+ }
device_state = DeviceState::TagFound;
deactivate_event->GetReadableEvent().Clear();
@@ -134,6 +164,7 @@ void NfpDevice::Initialize() {
device_state = npad_device->HasNfc() ? DeviceState::Initialized : DeviceState::Unavailable;
encrypted_tag_data = {};
tag_data = {};
+ is_initalized = true;
}
void NfpDevice::Finalize() {
@@ -144,6 +175,7 @@ void NfpDevice::Finalize() {
StopDetection();
}
device_state = DeviceState::Unavailable;
+ is_initalized = false;
}
Result NfpDevice::StartDetection(TagProtocol allowed_protocol) {
@@ -209,13 +241,17 @@ Result NfpDevice::Flush() {
tag_data.write_counter++;
- if (!AmiiboCrypto::EncodeAmiibo(tag_data, encrypted_tag_data)) {
- LOG_ERROR(Service_NFP, "Failed to encode data");
- return WriteAmiiboFailed;
- }
+ std::vector<u8> data(sizeof(EncryptedNTAG215File));
+ if (is_plain_amiibo) {
+ memcpy(data.data(), &tag_data, sizeof(tag_data));
+ } else {
+ if (!AmiiboCrypto::EncodeAmiibo(tag_data, encrypted_tag_data)) {
+ LOG_ERROR(Service_NFP, "Failed to encode data");
+ return WriteAmiiboFailed;
+ }
- std::vector<u8> data(sizeof(encrypted_tag_data));
- memcpy(data.data(), &encrypted_tag_data, sizeof(encrypted_tag_data));
+ memcpy(data.data(), &encrypted_tag_data, sizeof(encrypted_tag_data));
+ }
if (!npad_device->WriteNfc(data)) {
LOG_ERROR(Service_NFP, "Error writing to file");
@@ -233,6 +269,13 @@ Result NfpDevice::Mount(MountTarget mount_target_) {
return WrongDeviceState;
}
+ // The loaded amiibo is not encrypted
+ if (is_plain_amiibo) {
+ device_state = DeviceState::TagMounted;
+ mount_target = mount_target_;
+ return ResultSuccess;
+ }
+
if (!AmiiboCrypto::IsAmiiboValid(encrypted_tag_data)) {
LOG_ERROR(Service_NFP, "Not an amiibo");
return NotAnAmiibo;
@@ -448,7 +491,7 @@ Result NfpDevice::DeleteRegisterInfo() {
rng.GenerateRandomBytes(&tag_data.unknown, sizeof(u8));
rng.GenerateRandomBytes(&tag_data.unknown2[0], sizeof(u32));
rng.GenerateRandomBytes(&tag_data.unknown2[1], sizeof(u32));
- rng.GenerateRandomBytes(&tag_data.application_area_crc, sizeof(u32));
+ rng.GenerateRandomBytes(&tag_data.register_info_crc, sizeof(u32));
rng.GenerateRandomBytes(&tag_data.settings.init_date, sizeof(u32));
tag_data.settings.settings.font_region.Assign(0);
tag_data.settings.settings.amiibo_initialized.Assign(0);
@@ -471,6 +514,7 @@ Result NfpDevice::SetRegisterInfoPrivate(const AmiiboName& amiibo_name) {
}
Service::Mii::MiiManager manager;
+ const auto mii = manager.BuildDefault(0);
auto& settings = tag_data.settings;
if (tag_data.settings.settings.amiibo_initialized == 0) {
@@ -479,16 +523,15 @@ Result NfpDevice::SetRegisterInfoPrivate(const AmiiboName& amiibo_name) {
}
SetAmiiboName(settings, amiibo_name);
- tag_data.owner_mii = manager.ConvertCharInfoToV3(manager.BuildDefault(0));
+ tag_data.owner_mii = manager.BuildFromStoreData(mii);
+ tag_data.mii_extension = manager.SetFromStoreData(mii);
tag_data.unknown = 0;
- tag_data.unknown2[6] = 0;
+ tag_data.unknown2 = {};
settings.country_code_id = 0;
settings.settings.font_region.Assign(0);
settings.settings.amiibo_initialized.Assign(1);
- // TODO: this is a mix of tag.file input
- std::array<u8, 0x7e> unknown_input{};
- tag_data.application_area_crc = CalculateCrc(unknown_input);
+ UpdateRegisterInfoCrc();
return Flush();
}
@@ -685,6 +728,11 @@ Result NfpDevice::RecreateApplicationArea(u32 access_id, std::span<const u8> dat
return WrongDeviceState;
}
+ if (is_app_area_open) {
+ LOG_ERROR(Service_NFP, "Application area is open");
+ return WrongDeviceState;
+ }
+
if (mount_target == MountTarget::None || mount_target == MountTarget::Rom) {
LOG_ERROR(Service_NFP, "Amiibo is read only", device_state);
return WrongDeviceState;
@@ -715,10 +763,9 @@ Result NfpDevice::RecreateApplicationArea(u32 access_id, std::span<const u8> dat
tag_data.settings.settings.appdata_initialized.Assign(1);
tag_data.application_area_id = access_id;
tag_data.unknown = {};
+ tag_data.unknown2 = {};
- // TODO: this is a mix of tag_data input
- std::array<u8, 0x7e> unknown_input{};
- tag_data.application_area_crc = CalculateCrc(unknown_input);
+ UpdateRegisterInfoCrc();
return Flush();
}
@@ -752,6 +799,10 @@ Result NfpDevice::DeleteApplicationArea() {
rng.GenerateRandomBytes(&tag_data.application_id_byte, sizeof(u8));
tag_data.settings.settings.appdata_initialized.Assign(0);
tag_data.unknown = {};
+ tag_data.unknown2 = {};
+ is_app_area_open = false;
+
+ UpdateRegisterInfoCrc();
return Flush();
}
@@ -835,32 +886,34 @@ void NfpDevice::UpdateSettingsCrc() {
// TODO: this reads data from a global, find what it is
std::array<u8, 8> unknown_input{};
- settings.crc = CalculateCrc(unknown_input);
-}
-
-u32 NfpDevice::CalculateCrc(std::span<const u8> data) {
- constexpr u32 magic = 0xedb88320;
- u32 crc = 0xffffffff;
-
- if (data.size() == 0) {
- return 0;
- }
-
- for (u8 input : data) {
- u32 temp = (crc ^ input) >> 1;
- if (((crc ^ input) & 1) != 0) {
- temp = temp ^ magic;
- }
-
- for (std::size_t step = 0; step < 7; ++step) {
- crc = temp >> 1;
- if ((temp & 1) != 0) {
- crc = temp >> 1 ^ magic;
- }
- }
- }
+ boost::crc_32_type crc;
+ crc.process_bytes(&unknown_input, sizeof(unknown_input));
+ settings.crc = crc.checksum();
+}
+
+void NfpDevice::UpdateRegisterInfoCrc() {
+#pragma pack(push, 1)
+ struct CrcData {
+ Mii::Ver3StoreData mii;
+ u8 application_id_byte;
+ u8 unknown;
+ Mii::NfpStoreDataExtension mii_extension;
+ std::array<u32, 0x5> unknown2;
+ };
+ static_assert(sizeof(CrcData) == 0x7e, "CrcData is an invalid size");
+#pragma pack(pop)
+
+ const CrcData crc_data{
+ .mii = tag_data.owner_mii,
+ .application_id_byte = tag_data.application_id_byte,
+ .unknown = tag_data.unknown,
+ .mii_extension = tag_data.mii_extension,
+ .unknown2 = tag_data.unknown2,
+ };
- return ~crc;
+ boost::crc_32_type crc;
+ crc.process_bytes(&crc_data, sizeof(CrcData));
+ tag_data.register_info_crc = crc.checksum();
}
} // namespace Service::NFP
diff --git a/src/core/hle/service/nfp/nfp_device.h b/src/core/hle/service/nfp/nfp_device.h
index 06386401d..7f963730d 100644
--- a/src/core/hle/service/nfp/nfp_device.h
+++ b/src/core/hle/service/nfp/nfp_device.h
@@ -80,7 +80,7 @@ private:
AmiiboDate GetAmiiboDate(s64 posix_time) const;
u64 RemoveVersionByte(u64 application_id) const;
void UpdateSettingsCrc();
- u32 CalculateCrc(std::span<const u8>);
+ void UpdateRegisterInfoCrc();
bool is_controller_set{};
int callback_key;
@@ -92,8 +92,10 @@ private:
Kernel::KEvent* deactivate_event = nullptr;
Kernel::KEvent* availability_change_event = nullptr;
+ bool is_initalized{};
bool is_data_moddified{};
bool is_app_area_open{};
+ bool is_plain_amiibo{};
TagProtocol allowed_protocols{};
s64 current_posix_time{};
MountTarget mount_target{MountTarget::None};
diff --git a/src/core/hle/service/nfp/nfp_types.h b/src/core/hle/service/nfp/nfp_types.h
index 142343d6e..70c878552 100644
--- a/src/core/hle/service/nfp/nfp_types.h
+++ b/src/core/hle/service/nfp/nfp_types.h
@@ -259,8 +259,9 @@ struct EncryptedAmiiboFile {
u32_be application_area_id; // Encrypted Game id
u8 application_id_byte;
u8 unknown;
- std::array<u32, 0x7> unknown2;
- u32_be application_area_crc;
+ Service::Mii::NfpStoreDataExtension mii_extension;
+ std::array<u32, 0x5> unknown2;
+ u32_be register_info_crc;
ApplicationArea application_area; // Encrypted Game data
};
static_assert(sizeof(EncryptedAmiiboFile) == 0x1F8, "AmiiboFile is an invalid size");
@@ -280,8 +281,9 @@ struct NTAG215File {
u32_be application_area_id;
u8 application_id_byte;
u8 unknown;
- std::array<u32, 0x7> unknown2;
- u32_be application_area_crc;
+ Service::Mii::NfpStoreDataExtension mii_extension;
+ std::array<u32, 0x5> unknown2;
+ u32_be register_info_crc;
ApplicationArea application_area; // Encrypted Game data
HashData hmac_tag; // Hash
UniqueSerialNumber uid; // Unique serial number
@@ -307,7 +309,8 @@ struct EncryptedNTAG215File {
u32 CFG1; // Defines number of verification attempts
NTAG215Password password; // Password data
};
-static_assert(sizeof(EncryptedNTAG215File) == 0x21C, "EncryptedNTAG215File is an invalid size");
+static_assert(sizeof(EncryptedNTAG215File) == sizeof(NTAG215File),
+ "EncryptedNTAG215File is an invalid size");
static_assert(std::is_trivially_copyable_v<EncryptedNTAG215File>,
"EncryptedNTAG215File must be trivially copyable.");
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp b/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp
index d2308fffc..453a965dc 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp
@@ -304,8 +304,8 @@ NvResult nvhost_gpu::SubmitGPFIFOBase(std::span<const u8> input, std::vector<u8>
Tegra::CommandList entries(params.num_entries);
if (kickoff) {
- system.Memory().ReadBlock(params.address, entries.command_lists.data(),
- params.num_entries * sizeof(Tegra::CommandListHeader));
+ system.ApplicationMemory().ReadBlock(params.address, entries.command_lists.data(),
+ params.num_entries * sizeof(Tegra::CommandListHeader));
} else {
std::memcpy(entries.command_lists.data(), &input[sizeof(IoctlSubmitGpfifo)],
params.num_entries * sizeof(Tegra::CommandListHeader));
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp b/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp
index 7bcef105b..1ab51f10b 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp
@@ -105,8 +105,8 @@ NvResult nvhost_nvdec_common::Submit(DeviceFD fd, std::span<const u8> input,
const auto object = nvmap.GetHandle(cmd_buffer.memory_id);
ASSERT_OR_EXECUTE(object, return NvResult::InvalidState;);
Tegra::ChCommandHeaderList cmdlist(cmd_buffer.word_count);
- system.Memory().ReadBlock(object->address + cmd_buffer.offset, cmdlist.data(),
- cmdlist.size() * sizeof(u32));
+ system.ApplicationMemory().ReadBlock(object->address + cmd_buffer.offset, cmdlist.data(),
+ cmdlist.size() * sizeof(u32));
gpu.PushCommandBuffer(core.Host1xDeviceFile().fd_to_id[fd], cmdlist);
}
std::memcpy(output.data(), &params, sizeof(IoctlSubmit));