summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar german772022-11-13 11:07:48 -0600
committerGravatar german772022-11-13 11:07:48 -0600
commitfb57cd26a1219a5c91d2cb4dec402528f8ba308e (patch)
treeb9120fd3ea1a5572687025aa70e6e6ff4bccdacb /src
parentinput_common: Add amiibo applet functions (diff)
downloadyuzu-fb57cd26a1219a5c91d2cb4dec402528f8ba308e.tar.gz
yuzu-fb57cd26a1219a5c91d2cb4dec402528f8ba308e.tar.xz
yuzu-fb57cd26a1219a5c91d2cb4dec402528f8ba308e.zip
service: am: Implement cabinet applet backend
Diffstat (limited to 'src')
-rw-r--r--src/core/CMakeLists.txt4
-rw-r--r--src/core/frontend/applets/cabinet.cpp20
-rw-r--r--src/core/frontend/applets/cabinet.h36
-rw-r--r--src/core/hle/service/am/applets/applet_cabinet.cpp169
-rw-r--r--src/core/hle/service/am/applets/applet_cabinet.h99
-rw-r--r--src/core/hle/service/am/applets/applets.cpp20
-rw-r--r--src/core/hle/service/am/applets/applets.h12
-rw-r--r--src/core/hle/service/nfp/nfp_types.h7
-rw-r--r--src/yuzu/main.cpp2
9 files changed, 362 insertions, 7 deletions
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index f67f1ce92..740c5b0fd 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -120,6 +120,8 @@ add_library(core STATIC
120 file_sys/vfs_vector.h 120 file_sys/vfs_vector.h
121 file_sys/xts_archive.cpp 121 file_sys/xts_archive.cpp
122 file_sys/xts_archive.h 122 file_sys/xts_archive.h
123 frontend/applets/cabinet.cpp
124 frontend/applets/cabinet.h
123 frontend/applets/controller.cpp 125 frontend/applets/controller.cpp
124 frontend/applets/controller.h 126 frontend/applets/controller.h
125 frontend/applets/error.cpp 127 frontend/applets/error.cpp
@@ -312,6 +314,8 @@ add_library(core STATIC
312 hle/service/am/applet_ae.h 314 hle/service/am/applet_ae.h
313 hle/service/am/applet_oe.cpp 315 hle/service/am/applet_oe.cpp
314 hle/service/am/applet_oe.h 316 hle/service/am/applet_oe.h
317 hle/service/am/applets/applet_cabinet.cpp
318 hle/service/am/applets/applet_cabinet.h
315 hle/service/am/applets/applet_controller.cpp 319 hle/service/am/applets/applet_controller.cpp
316 hle/service/am/applets/applet_controller.h 320 hle/service/am/applets/applet_controller.h
317 hle/service/am/applets/applet_error.cpp 321 hle/service/am/applets/applet_error.cpp
diff --git a/src/core/frontend/applets/cabinet.cpp b/src/core/frontend/applets/cabinet.cpp
new file mode 100644
index 000000000..5ade75de0
--- /dev/null
+++ b/src/core/frontend/applets/cabinet.cpp
@@ -0,0 +1,20 @@
1// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#include "common/logging/log.h"
5#include "core/frontend/applets/cabinet.h"
6
7#include <thread>
8
9namespace Core::Frontend {
10
11CabinetApplet::~CabinetApplet() = default;
12
13void DefaultCabinetApplet::ShowCabinetApplet(
14 std::function<void(bool, const std::string&)> callback, const CabinetParameters& parameters,
15 std::shared_ptr<Service::NFP::NfpDevice> nfp_device) const {
16 LOG_WARNING(Service_AM, "(STUBBED) called");
17 callback(false, {});
18}
19
20} // namespace Core::Frontend
diff --git a/src/core/frontend/applets/cabinet.h b/src/core/frontend/applets/cabinet.h
new file mode 100644
index 000000000..1c68bf57d
--- /dev/null
+++ b/src/core/frontend/applets/cabinet.h
@@ -0,0 +1,36 @@
1// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#pragma once
5
6#include <functional>
7#include "core/hle/service/nfp/nfp_types.h"
8
9namespace Service::NFP {
10class NfpDevice;
11} // namespace Service::NFP
12
13namespace Core::Frontend {
14
15struct CabinetParameters {
16 Service::NFP::TagInfo tag_info;
17 Service::NFP::RegisterInfo register_info;
18 Service::NFP::CabinetMode mode;
19};
20
21class CabinetApplet {
22public:
23 virtual ~CabinetApplet();
24 virtual void ShowCabinetApplet(std::function<void(bool, const std::string&)> callback,
25 const CabinetParameters& parameters,
26 std::shared_ptr<Service::NFP::NfpDevice> nfp_device) const = 0;
27};
28
29class DefaultCabinetApplet final : public CabinetApplet {
30public:
31 void ShowCabinetApplet(std::function<void(bool, const std::string&)> callback,
32 const CabinetParameters& parameters,
33 std::shared_ptr<Service::NFP::NfpDevice> nfp_device) const override;
34};
35
36} // namespace Core::Frontend
diff --git a/src/core/hle/service/am/applets/applet_cabinet.cpp b/src/core/hle/service/am/applets/applet_cabinet.cpp
new file mode 100644
index 000000000..1eb5a9f22
--- /dev/null
+++ b/src/core/hle/service/am/applets/applet_cabinet.cpp
@@ -0,0 +1,169 @@
1// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#include "common/assert.h"
5#include "common/logging/log.h"
6#include "core/core.h"
7#include "core/frontend/applets/cabinet.h"
8#include "core/hid/hid_core.h"
9#include "core/hle/kernel/k_event.h"
10#include "core/hle/kernel/k_readable_event.h"
11#include "core/hle/service/am/am.h"
12#include "core/hle/service/am/applets/applet_cabinet.h"
13#include "core/hle/service/mii/mii_manager.h"
14#include "core/hle/service/nfp/nfp_device.h"
15
16namespace Service::AM::Applets {
17
18Cabinet::Cabinet(Core::System& system_, LibraryAppletMode applet_mode_,
19 const Core::Frontend::CabinetApplet& frontend_)
20 : Applet{system_, applet_mode_}, frontend{frontend_}, system{system_}, service_context{
21 system_,
22 "CabinetApplet"} {
23
24 availability_change_event =
25 service_context.CreateEvent("CabinetApplet:AvailabilityChangeEvent");
26}
27
28Cabinet::~Cabinet() = default;
29
30void Cabinet::Initialize() {
31 Applet::Initialize();
32
33 LOG_INFO(Service_HID, "Initializing Cabinet Applet.");
34
35 LOG_ERROR(Service_HID,
36 "Initializing Applet with common_args: arg_version={}, lib_version={}, "
37 "play_startup_sound={}, size={}, system_tick={}, theme_color={}",
38 common_args.arguments_version, common_args.library_version,
39 common_args.play_startup_sound, common_args.size, common_args.system_tick,
40 common_args.theme_color);
41
42 const auto storage = broker.PopNormalDataToApplet();
43 ASSERT(storage != nullptr);
44
45 const auto applet_input_data = storage->GetData();
46 ASSERT(applet_input_data.size() >= sizeof(StartParamForAmiiboSettings));
47
48 std::memcpy(&applet_input_common, applet_input_data.data(),
49 sizeof(StartParamForAmiiboSettings));
50}
51
52bool Cabinet::TransactionComplete() const {
53 return is_complete;
54}
55
56Result Cabinet::GetStatus() const {
57 return ResultSuccess;
58}
59
60void Cabinet::ExecuteInteractive() {
61 ASSERT_MSG(false, "Attempted to call interactive execution on non-interactive applet.");
62}
63
64void Cabinet::Execute() {
65 if (is_complete) {
66 return;
67 }
68
69 const auto callback = [this](bool apply_changes, const std::string& amiibo_name) {
70 DisplayCompleted(apply_changes, amiibo_name);
71 };
72
73 // TODO: listen on all controllers
74 if (nfp_device == nullptr) {
75 nfp_device = std::make_shared<Service::NFP::NfpDevice>(
76 system.HIDCore().GetFirstNpadId(), system, service_context, availability_change_event);
77 nfp_device->Initialize();
78 nfp_device->StartDetection(Service::NFP::TagProtocol::All);
79 }
80
81 const Core::Frontend::CabinetParameters parameters{
82 .tag_info = applet_input_common.tag_info,
83 .register_info = applet_input_common.register_info,
84 .mode = applet_input_common.applet_mode,
85 };
86
87 switch (applet_input_common.applet_mode) {
88 case Service::NFP::CabinetMode::StartNicknameAndOwnerSettings:
89 case Service::NFP::CabinetMode::StartGameDataEraser:
90 case Service::NFP::CabinetMode::StartRestorer:
91 case Service::NFP::CabinetMode::StartFormatter:
92 frontend.ShowCabinetApplet(callback, parameters, nfp_device);
93 break;
94 default:
95 UNIMPLEMENTED_MSG("Unknown CabinetMode={}", applet_input_common.applet_mode);
96 DisplayCompleted(false, {});
97 break;
98 }
99}
100
101void Cabinet::DisplayCompleted(bool apply_changes, const std::string& amiibo_name) {
102 Service::Mii::MiiManager manager;
103 ReturnValueForAmiiboSettings applet_output{};
104
105 if (!apply_changes) {
106 Cancel();
107 }
108
109 if (nfp_device->GetCurrentState() != Service::NFP::DeviceState::TagFound &&
110 nfp_device->GetCurrentState() != Service::NFP::DeviceState::TagMounted) {
111 Cancel();
112 }
113
114 if (nfp_device->GetCurrentState() != Service::NFP::DeviceState::TagFound) {
115 nfp_device->Mount(Service::NFP::MountTarget::All);
116 }
117
118 switch (applet_input_common.applet_mode) {
119 case Service::NFP::CabinetMode::StartNicknameAndOwnerSettings: {
120 Service::NFP::AmiiboName name{};
121 memccpy(name.data(), amiibo_name.data(), 0, name.size());
122 nfp_device->SetNicknameAndOwner(name);
123 break;
124 }
125 case Service::NFP::CabinetMode::StartGameDataEraser:
126 nfp_device->DeleteApplicationArea();
127 break;
128 case Service::NFP::CabinetMode::StartRestorer:
129 nfp_device->RestoreAmiibo();
130 break;
131 case Service::NFP::CabinetMode::StartFormatter:
132 nfp_device->DeleteAllData();
133 break;
134 default:
135 UNIMPLEMENTED_MSG("Unknown CabinetMode={}", applet_input_common.applet_mode);
136 break;
137 }
138
139 applet_output.device_handle = applet_input_common.device_handle;
140 applet_output.result = CabinetResult::Success;
141 nfp_device->GetRegisterInfo(applet_output.register_info);
142 nfp_device->GetTagInfo(applet_output.tag_info);
143 nfp_device->Finalize();
144
145 std::vector<u8> out_data(sizeof(ReturnValueForAmiiboSettings));
146 std::memcpy(out_data.data(), &applet_output, sizeof(ReturnValueForAmiiboSettings));
147
148 is_complete = true;
149
150 broker.PushNormalDataFromApplet(std::make_shared<IStorage>(system, std::move(out_data)));
151 broker.SignalStateChanged();
152}
153
154void Cabinet::Cancel() {
155 ReturnValueForAmiiboSettings applet_output{};
156 applet_output.device_handle = applet_input_common.device_handle;
157 applet_output.result = CabinetResult::Cancel;
158 nfp_device->Finalize();
159
160 std::vector<u8> out_data(sizeof(ReturnValueForAmiiboSettings));
161 std::memcpy(out_data.data(), &applet_output, sizeof(ReturnValueForAmiiboSettings));
162
163 is_complete = true;
164
165 broker.PushNormalDataFromApplet(std::make_shared<IStorage>(system, std::move(out_data)));
166 broker.SignalStateChanged();
167}
168
169} // 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
new file mode 100644
index 000000000..2d3f22434
--- /dev/null
+++ b/src/core/hle/service/am/applets/applet_cabinet.h
@@ -0,0 +1,99 @@
1// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#pragma once
5
6#include <array>
7
8#include "core/hle/result.h"
9#include "core/hle/service/am/applets/applets.h"
10#include "core/hle/service/kernel_helpers.h"
11#include "core/hle/service/nfp/nfp_types.h"
12
13namespace Kernel {
14class KEvent;
15class KReadableEvent;
16} // namespace Kernel
17
18namespace Core {
19class System;
20} // namespace Core
21
22namespace Service::NFP {
23class NfpDevice;
24}
25
26namespace Service::AM::Applets {
27
28enum class CabinetAppletVersion : s32 {
29 Version1 = 0x1,
30};
31
32enum class CabinetResult : u8 {
33 Cancel,
34 Success,
35};
36
37// This is nn::nfp::AmiiboSettingsStartParam
38struct AmiiboSettingsStartParam {
39 u64 device_handle;
40 std::array<u8, 0x20> param_1;
41 std::array<u8, 0x1> param_2;
42};
43static_assert(sizeof(AmiiboSettingsStartParam) == 0x30,
44 "AmiiboSettingsStartParam is an invalid size");
45
46// This is nn::nfp::StartParamForAmiiboSettings
47struct StartParamForAmiiboSettings {
48 u8 param_1;
49 Service::NFP::CabinetMode applet_mode;
50 u8 flags;
51 u8 amiibo_settings_1;
52 u64 device_handle;
53 Service::NFP::TagInfo tag_info;
54 Service::NFP::RegisterInfo register_info;
55 std::array<u8, 0x20> amiibo_settings_3;
56 INSERT_PADDING_BYTES(0x20);
57};
58static_assert(sizeof(StartParamForAmiiboSettings) == 0x1A8,
59 "StartParamForAmiiboSettings is an invalid size");
60
61// This is nn::nfp::ReturnValueForAmiiboSettings
62struct ReturnValueForAmiiboSettings {
63 CabinetResult result;
64 INSERT_PADDING_BYTES(0x3);
65 u64 device_handle;
66 Service::NFP::TagInfo tag_info;
67 Service::NFP::RegisterInfo register_info;
68 INSERT_PADDING_BYTES(0x24);
69};
70static_assert(sizeof(ReturnValueForAmiiboSettings) == 0x190,
71 "ReturnValueForAmiiboSettings is an invalid size");
72
73class Cabinet final : public Applet {
74public:
75 explicit Cabinet(Core::System& system_, LibraryAppletMode applet_mode_,
76 const Core::Frontend::CabinetApplet& frontend_);
77 ~Cabinet() override;
78
79 void Initialize() override;
80
81 bool TransactionComplete() const override;
82 Result GetStatus() const override;
83 void ExecuteInteractive() override;
84 void Execute() override;
85 void DisplayCompleted(bool apply_changes, const std::string& amiibo_name);
86 void Cancel();
87
88private:
89 const Core::Frontend::CabinetApplet& frontend;
90 Core::System& system;
91
92 bool is_complete{false};
93 std::shared_ptr<Service::NFP::NfpDevice> nfp_device;
94 Kernel::KEvent* availability_change_event;
95 KernelHelpers::ServiceContext service_context;
96 StartParamForAmiiboSettings applet_input_common{};
97};
98
99} // namespace Service::AM::Applets
diff --git a/src/core/hle/service/am/applets/applets.cpp b/src/core/hle/service/am/applets/applets.cpp
index 7062df21c..10afbc2da 100644
--- a/src/core/hle/service/am/applets/applets.cpp
+++ b/src/core/hle/service/am/applets/applets.cpp
@@ -5,6 +5,7 @@
5 5
6#include "common/assert.h" 6#include "common/assert.h"
7#include "core/core.h" 7#include "core/core.h"
8#include "core/frontend/applets/cabinet.h"
8#include "core/frontend/applets/controller.h" 9#include "core/frontend/applets/controller.h"
9#include "core/frontend/applets/error.h" 10#include "core/frontend/applets/error.h"
10#include "core/frontend/applets/general_frontend.h" 11#include "core/frontend/applets/general_frontend.h"
@@ -16,6 +17,7 @@
16#include "core/hle/service/am/am.h" 17#include "core/hle/service/am/am.h"
17#include "core/hle/service/am/applet_ae.h" 18#include "core/hle/service/am/applet_ae.h"
18#include "core/hle/service/am/applet_oe.h" 19#include "core/hle/service/am/applet_oe.h"
20#include "core/hle/service/am/applets/applet_cabinet.h"
19#include "core/hle/service/am/applets/applet_controller.h" 21#include "core/hle/service/am/applets/applet_controller.h"
20#include "core/hle/service/am/applets/applet_error.h" 22#include "core/hle/service/am/applets/applet_error.h"
21#include "core/hle/service/am/applets/applet_general_backend.h" 23#include "core/hle/service/am/applets/applet_general_backend.h"
@@ -171,13 +173,15 @@ void Applet::Initialize() {
171 173
172AppletFrontendSet::AppletFrontendSet() = default; 174AppletFrontendSet::AppletFrontendSet() = default;
173 175
174AppletFrontendSet::AppletFrontendSet(ControllerApplet controller_applet, ErrorApplet error_applet, 176AppletFrontendSet::AppletFrontendSet(CabinetApplet cabinet_applet,
177 ControllerApplet controller_applet, ErrorApplet error_applet,
175 MiiEdit mii_edit_, 178 MiiEdit mii_edit_,
176 ParentalControlsApplet parental_controls_applet, 179 ParentalControlsApplet parental_controls_applet,
177 PhotoViewer photo_viewer_, ProfileSelect profile_select_, 180 PhotoViewer photo_viewer_, ProfileSelect profile_select_,
178 SoftwareKeyboard software_keyboard_, WebBrowser web_browser_) 181 SoftwareKeyboard software_keyboard_, WebBrowser web_browser_)
179 : controller{std::move(controller_applet)}, error{std::move(error_applet)}, 182 : cabinet{std::move(cabinet_applet)}, controller{std::move(controller_applet)},
180 mii_edit{std::move(mii_edit_)}, parental_controls{std::move(parental_controls_applet)}, 183 error{std::move(error_applet)}, mii_edit{std::move(mii_edit_)},
184 parental_controls{std::move(parental_controls_applet)},
181 photo_viewer{std::move(photo_viewer_)}, profile_select{std::move(profile_select_)}, 185 photo_viewer{std::move(photo_viewer_)}, profile_select{std::move(profile_select_)},
182 software_keyboard{std::move(software_keyboard_)}, web_browser{std::move(web_browser_)} {} 186 software_keyboard{std::move(software_keyboard_)}, web_browser{std::move(web_browser_)} {}
183 187
@@ -196,6 +200,10 @@ const AppletFrontendSet& AppletManager::GetAppletFrontendSet() const {
196} 200}
197 201
198void AppletManager::SetAppletFrontendSet(AppletFrontendSet set) { 202void AppletManager::SetAppletFrontendSet(AppletFrontendSet set) {
203 if (set.cabinet != nullptr) {
204 frontend.cabinet = std::move(set.cabinet);
205 }
206
199 if (set.controller != nullptr) { 207 if (set.controller != nullptr) {
200 frontend.controller = std::move(set.controller); 208 frontend.controller = std::move(set.controller);
201 } 209 }
@@ -235,6 +243,10 @@ void AppletManager::SetDefaultAppletFrontendSet() {
235} 243}
236 244
237void AppletManager::SetDefaultAppletsIfMissing() { 245void AppletManager::SetDefaultAppletsIfMissing() {
246 if (frontend.cabinet == nullptr) {
247 frontend.cabinet = std::make_unique<Core::Frontend::DefaultCabinetApplet>();
248 }
249
238 if (frontend.controller == nullptr) { 250 if (frontend.controller == nullptr) {
239 frontend.controller = 251 frontend.controller =
240 std::make_unique<Core::Frontend::DefaultControllerApplet>(system.HIDCore()); 252 std::make_unique<Core::Frontend::DefaultControllerApplet>(system.HIDCore());
@@ -279,6 +291,8 @@ std::shared_ptr<Applet> AppletManager::GetApplet(AppletId id, LibraryAppletMode
279 switch (id) { 291 switch (id) {
280 case AppletId::Auth: 292 case AppletId::Auth:
281 return std::make_shared<Auth>(system, mode, *frontend.parental_controls); 293 return std::make_shared<Auth>(system, mode, *frontend.parental_controls);
294 case AppletId::Cabinet:
295 return std::make_shared<Cabinet>(system, mode, *frontend.cabinet);
282 case AppletId::Controller: 296 case AppletId::Controller:
283 return std::make_shared<Controller>(system, mode, *frontend.controller); 297 return std::make_shared<Controller>(system, mode, *frontend.controller);
284 case AppletId::Error: 298 case AppletId::Error:
diff --git a/src/core/hle/service/am/applets/applets.h b/src/core/hle/service/am/applets/applets.h
index 12c6a5b1a..a22eb62a8 100644
--- a/src/core/hle/service/am/applets/applets.h
+++ b/src/core/hle/service/am/applets/applets.h
@@ -16,6 +16,7 @@ class System;
16} 16}
17 17
18namespace Core::Frontend { 18namespace Core::Frontend {
19class CabinetApplet;
19class ControllerApplet; 20class ControllerApplet;
20class ECommerceApplet; 21class ECommerceApplet;
21class ErrorApplet; 22class ErrorApplet;
@@ -176,6 +177,7 @@ protected:
176}; 177};
177 178
178struct AppletFrontendSet { 179struct AppletFrontendSet {
180 using CabinetApplet = std::unique_ptr<Core::Frontend::CabinetApplet>;
179 using ControllerApplet = std::unique_ptr<Core::Frontend::ControllerApplet>; 181 using ControllerApplet = std::unique_ptr<Core::Frontend::ControllerApplet>;
180 using ErrorApplet = std::unique_ptr<Core::Frontend::ErrorApplet>; 182 using ErrorApplet = std::unique_ptr<Core::Frontend::ErrorApplet>;
181 using MiiEdit = std::unique_ptr<Core::Frontend::MiiEditApplet>; 183 using MiiEdit = std::unique_ptr<Core::Frontend::MiiEditApplet>;
@@ -186,10 +188,11 @@ struct AppletFrontendSet {
186 using WebBrowser = std::unique_ptr<Core::Frontend::WebBrowserApplet>; 188 using WebBrowser = std::unique_ptr<Core::Frontend::WebBrowserApplet>;
187 189
188 AppletFrontendSet(); 190 AppletFrontendSet();
189 AppletFrontendSet(ControllerApplet controller_applet, ErrorApplet error_applet, 191 AppletFrontendSet(CabinetApplet cabinet_applet, ControllerApplet controller_applet,
190 MiiEdit mii_edit_, ParentalControlsApplet parental_controls_applet, 192 ErrorApplet error_applet, MiiEdit mii_edit_,
191 PhotoViewer photo_viewer_, ProfileSelect profile_select_, 193 ParentalControlsApplet parental_controls_applet, PhotoViewer photo_viewer_,
192 SoftwareKeyboard software_keyboard_, WebBrowser web_browser_); 194 ProfileSelect profile_select_, SoftwareKeyboard software_keyboard_,
195 WebBrowser web_browser_);
193 ~AppletFrontendSet(); 196 ~AppletFrontendSet();
194 197
195 AppletFrontendSet(const AppletFrontendSet&) = delete; 198 AppletFrontendSet(const AppletFrontendSet&) = delete;
@@ -198,6 +201,7 @@ struct AppletFrontendSet {
198 AppletFrontendSet(AppletFrontendSet&&) noexcept; 201 AppletFrontendSet(AppletFrontendSet&&) noexcept;
199 AppletFrontendSet& operator=(AppletFrontendSet&&) noexcept; 202 AppletFrontendSet& operator=(AppletFrontendSet&&) noexcept;
200 203
204 CabinetApplet cabinet;
201 ControllerApplet controller; 205 ControllerApplet controller;
202 ErrorApplet error; 206 ErrorApplet error;
203 MiiEdit mii_edit; 207 MiiEdit mii_edit;
diff --git a/src/core/hle/service/nfp/nfp_types.h b/src/core/hle/service/nfp/nfp_types.h
index 866aefe20..69858096a 100644
--- a/src/core/hle/service/nfp/nfp_types.h
+++ b/src/core/hle/service/nfp/nfp_types.h
@@ -99,6 +99,13 @@ enum class TagProtocol : u32 {
99 All = 0xFFFFFFFFU, 99 All = 0xFFFFFFFFU,
100}; 100};
101 101
102enum class CabinetMode : u8 {
103 StartNicknameAndOwnerSettings,
104 StartGameDataEraser,
105 StartRestorer,
106 StartFormatter,
107};
108
102using UniqueSerialNumber = std::array<u8, 7>; 109using UniqueSerialNumber = std::array<u8, 7>;
103using LockBytes = std::array<u8, 2>; 110using LockBytes = std::array<u8, 2>;
104using HashData = std::array<u8, 0x20>; 111using HashData = std::array<u8, 0x20>;
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp
index 032ff1cbc..27c9e1f32 100644
--- a/src/yuzu/main.cpp
+++ b/src/yuzu/main.cpp
@@ -26,6 +26,7 @@
26#include "configuration/configure_tas.h" 26#include "configuration/configure_tas.h"
27#include "core/file_sys/vfs.h" 27#include "core/file_sys/vfs.h"
28#include "core/file_sys/vfs_real.h" 28#include "core/file_sys/vfs_real.h"
29#include "core/frontend/applets/cabinet.h"
29#include "core/frontend/applets/controller.h" 30#include "core/frontend/applets/controller.h"
30#include "core/frontend/applets/general_frontend.h" 31#include "core/frontend/applets/general_frontend.h"
31#include "core/frontend/applets/mii_edit.h" 32#include "core/frontend/applets/mii_edit.h"
@@ -1547,6 +1548,7 @@ bool GMainWindow::LoadROM(const QString& filename, u64 program_id, std::size_t p
1547 system->SetFilesystem(vfs); 1548 system->SetFilesystem(vfs);
1548 1549
1549 system->SetAppletFrontendSet({ 1550 system->SetAppletFrontendSet({
1551 nullptr, // Amiibo Manager
1550 std::make_unique<QtControllerSelector>(*this), // Controller Selector 1552 std::make_unique<QtControllerSelector>(*this), // Controller Selector
1551 std::make_unique<QtErrorDisplay>(*this), // Error Display 1553 std::make_unique<QtErrorDisplay>(*this), // Error Display
1552 nullptr, // Mii Editor 1554 nullptr, // Mii Editor