forked from eden-emu/eden
		
	service: am: Implement cabinet applet backend
This commit is contained in:
		
							parent
							
								
									b193d40d22
								
							
						
					
					
						commit
						fb57cd26a1
					
				
					 9 changed files with 362 additions and 7 deletions
				
			
		|  | @ -120,6 +120,8 @@ add_library(core STATIC | |||
|     file_sys/vfs_vector.h | ||||
|     file_sys/xts_archive.cpp | ||||
|     file_sys/xts_archive.h | ||||
|     frontend/applets/cabinet.cpp | ||||
|     frontend/applets/cabinet.h | ||||
|     frontend/applets/controller.cpp | ||||
|     frontend/applets/controller.h | ||||
|     frontend/applets/error.cpp | ||||
|  | @ -312,6 +314,8 @@ add_library(core STATIC | |||
|     hle/service/am/applet_ae.h | ||||
|     hle/service/am/applet_oe.cpp | ||||
|     hle/service/am/applet_oe.h | ||||
|     hle/service/am/applets/applet_cabinet.cpp | ||||
|     hle/service/am/applets/applet_cabinet.h | ||||
|     hle/service/am/applets/applet_controller.cpp | ||||
|     hle/service/am/applets/applet_controller.h | ||||
|     hle/service/am/applets/applet_error.cpp | ||||
|  |  | |||
							
								
								
									
										20
									
								
								src/core/frontend/applets/cabinet.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								src/core/frontend/applets/cabinet.cpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,20 @@ | |||
| // SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
 | ||||
| // SPDX-License-Identifier: GPL-2.0-or-later
 | ||||
| 
 | ||||
| #include "common/logging/log.h" | ||||
| #include "core/frontend/applets/cabinet.h" | ||||
| 
 | ||||
| #include <thread> | ||||
| 
 | ||||
| namespace Core::Frontend { | ||||
| 
 | ||||
| CabinetApplet::~CabinetApplet() = default; | ||||
| 
 | ||||
| void DefaultCabinetApplet::ShowCabinetApplet( | ||||
|     std::function<void(bool, const std::string&)> callback, const CabinetParameters& parameters, | ||||
|     std::shared_ptr<Service::NFP::NfpDevice> nfp_device) const { | ||||
|     LOG_WARNING(Service_AM, "(STUBBED) called"); | ||||
|     callback(false, {}); | ||||
| } | ||||
| 
 | ||||
| } // namespace Core::Frontend
 | ||||
							
								
								
									
										36
									
								
								src/core/frontend/applets/cabinet.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								src/core/frontend/applets/cabinet.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,36 @@ | |||
| // SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
 | ||||
| // SPDX-License-Identifier: GPL-2.0-or-later
 | ||||
| 
 | ||||
| #pragma once | ||||
| 
 | ||||
| #include <functional> | ||||
| #include "core/hle/service/nfp/nfp_types.h" | ||||
| 
 | ||||
| namespace Service::NFP { | ||||
| class NfpDevice; | ||||
| } // namespace Service::NFP
 | ||||
| 
 | ||||
| namespace Core::Frontend { | ||||
| 
 | ||||
| struct CabinetParameters { | ||||
|     Service::NFP::TagInfo tag_info; | ||||
|     Service::NFP::RegisterInfo register_info; | ||||
|     Service::NFP::CabinetMode mode; | ||||
| }; | ||||
| 
 | ||||
| class CabinetApplet { | ||||
| public: | ||||
|     virtual ~CabinetApplet(); | ||||
|     virtual void ShowCabinetApplet(std::function<void(bool, const std::string&)> callback, | ||||
|                                    const CabinetParameters& parameters, | ||||
|                                    std::shared_ptr<Service::NFP::NfpDevice> nfp_device) const = 0; | ||||
| }; | ||||
| 
 | ||||
| class DefaultCabinetApplet final : public CabinetApplet { | ||||
| public: | ||||
|     void ShowCabinetApplet(std::function<void(bool, const std::string&)> callback, | ||||
|                            const CabinetParameters& parameters, | ||||
|                            std::shared_ptr<Service::NFP::NfpDevice> nfp_device) const override; | ||||
| }; | ||||
| 
 | ||||
| } // namespace Core::Frontend
 | ||||
							
								
								
									
										169
									
								
								src/core/hle/service/am/applets/applet_cabinet.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										169
									
								
								src/core/hle/service/am/applets/applet_cabinet.cpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,169 @@ | |||
| // SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
 | ||||
| // SPDX-License-Identifier: GPL-2.0-or-later
 | ||||
| 
 | ||||
| #include "common/assert.h" | ||||
| #include "common/logging/log.h" | ||||
| #include "core/core.h" | ||||
| #include "core/frontend/applets/cabinet.h" | ||||
| #include "core/hid/hid_core.h" | ||||
| #include "core/hle/kernel/k_event.h" | ||||
| #include "core/hle/kernel/k_readable_event.h" | ||||
| #include "core/hle/service/am/am.h" | ||||
| #include "core/hle/service/am/applets/applet_cabinet.h" | ||||
| #include "core/hle/service/mii/mii_manager.h" | ||||
| #include "core/hle/service/nfp/nfp_device.h" | ||||
| 
 | ||||
| namespace Service::AM::Applets { | ||||
| 
 | ||||
| Cabinet::Cabinet(Core::System& system_, LibraryAppletMode applet_mode_, | ||||
|                  const Core::Frontend::CabinetApplet& frontend_) | ||||
|     : Applet{system_, applet_mode_}, frontend{frontend_}, system{system_}, service_context{ | ||||
|                                                                                system_, | ||||
|                                                                                "CabinetApplet"} { | ||||
| 
 | ||||
|     availability_change_event = | ||||
|         service_context.CreateEvent("CabinetApplet:AvailabilityChangeEvent"); | ||||
| } | ||||
| 
 | ||||
| Cabinet::~Cabinet() = default; | ||||
| 
 | ||||
| void Cabinet::Initialize() { | ||||
|     Applet::Initialize(); | ||||
| 
 | ||||
|     LOG_INFO(Service_HID, "Initializing Cabinet Applet."); | ||||
| 
 | ||||
|     LOG_ERROR(Service_HID, | ||||
|               "Initializing Applet with common_args: arg_version={}, lib_version={}, " | ||||
|               "play_startup_sound={}, size={}, system_tick={}, theme_color={}", | ||||
|               common_args.arguments_version, common_args.library_version, | ||||
|               common_args.play_startup_sound, common_args.size, common_args.system_tick, | ||||
|               common_args.theme_color); | ||||
| 
 | ||||
|     const auto storage = broker.PopNormalDataToApplet(); | ||||
|     ASSERT(storage != nullptr); | ||||
| 
 | ||||
|     const auto applet_input_data = storage->GetData(); | ||||
|     ASSERT(applet_input_data.size() >= sizeof(StartParamForAmiiboSettings)); | ||||
| 
 | ||||
|     std::memcpy(&applet_input_common, applet_input_data.data(), | ||||
|                 sizeof(StartParamForAmiiboSettings)); | ||||
| } | ||||
| 
 | ||||
| bool Cabinet::TransactionComplete() const { | ||||
|     return is_complete; | ||||
| } | ||||
| 
 | ||||
| Result Cabinet::GetStatus() const { | ||||
|     return ResultSuccess; | ||||
| } | ||||
| 
 | ||||
| void Cabinet::ExecuteInteractive() { | ||||
|     ASSERT_MSG(false, "Attempted to call interactive execution on non-interactive applet."); | ||||
| } | ||||
| 
 | ||||
| void Cabinet::Execute() { | ||||
|     if (is_complete) { | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     const auto callback = [this](bool apply_changes, const std::string& amiibo_name) { | ||||
|         DisplayCompleted(apply_changes, amiibo_name); | ||||
|     }; | ||||
| 
 | ||||
|     // TODO: listen on all controllers
 | ||||
|     if (nfp_device == nullptr) { | ||||
|         nfp_device = std::make_shared<Service::NFP::NfpDevice>( | ||||
|             system.HIDCore().GetFirstNpadId(), system, service_context, availability_change_event); | ||||
|         nfp_device->Initialize(); | ||||
|         nfp_device->StartDetection(Service::NFP::TagProtocol::All); | ||||
|     } | ||||
| 
 | ||||
|     const Core::Frontend::CabinetParameters parameters{ | ||||
|         .tag_info = applet_input_common.tag_info, | ||||
|         .register_info = applet_input_common.register_info, | ||||
|         .mode = applet_input_common.applet_mode, | ||||
|     }; | ||||
| 
 | ||||
|     switch (applet_input_common.applet_mode) { | ||||
|     case Service::NFP::CabinetMode::StartNicknameAndOwnerSettings: | ||||
|     case Service::NFP::CabinetMode::StartGameDataEraser: | ||||
|     case Service::NFP::CabinetMode::StartRestorer: | ||||
|     case Service::NFP::CabinetMode::StartFormatter: | ||||
|         frontend.ShowCabinetApplet(callback, parameters, nfp_device); | ||||
|         break; | ||||
|     default: | ||||
|         UNIMPLEMENTED_MSG("Unknown CabinetMode={}", applet_input_common.applet_mode); | ||||
|         DisplayCompleted(false, {}); | ||||
|         break; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void Cabinet::DisplayCompleted(bool apply_changes, const std::string& amiibo_name) { | ||||
|     Service::Mii::MiiManager manager; | ||||
|     ReturnValueForAmiiboSettings applet_output{}; | ||||
| 
 | ||||
|     if (!apply_changes) { | ||||
|         Cancel(); | ||||
|     } | ||||
| 
 | ||||
|     if (nfp_device->GetCurrentState() != Service::NFP::DeviceState::TagFound && | ||||
|         nfp_device->GetCurrentState() != Service::NFP::DeviceState::TagMounted) { | ||||
|         Cancel(); | ||||
|     } | ||||
| 
 | ||||
|     if (nfp_device->GetCurrentState() != Service::NFP::DeviceState::TagFound) { | ||||
|         nfp_device->Mount(Service::NFP::MountTarget::All); | ||||
|     } | ||||
| 
 | ||||
|     switch (applet_input_common.applet_mode) { | ||||
|     case Service::NFP::CabinetMode::StartNicknameAndOwnerSettings: { | ||||
|         Service::NFP::AmiiboName name{}; | ||||
|         memccpy(name.data(), amiibo_name.data(), 0, name.size()); | ||||
|         nfp_device->SetNicknameAndOwner(name); | ||||
|         break; | ||||
|     } | ||||
|     case Service::NFP::CabinetMode::StartGameDataEraser: | ||||
|         nfp_device->DeleteApplicationArea(); | ||||
|         break; | ||||
|     case Service::NFP::CabinetMode::StartRestorer: | ||||
|         nfp_device->RestoreAmiibo(); | ||||
|         break; | ||||
|     case Service::NFP::CabinetMode::StartFormatter: | ||||
|         nfp_device->DeleteAllData(); | ||||
|         break; | ||||
|     default: | ||||
|         UNIMPLEMENTED_MSG("Unknown CabinetMode={}", applet_input_common.applet_mode); | ||||
|         break; | ||||
|     } | ||||
| 
 | ||||
|     applet_output.device_handle = applet_input_common.device_handle; | ||||
|     applet_output.result = CabinetResult::Success; | ||||
|     nfp_device->GetRegisterInfo(applet_output.register_info); | ||||
|     nfp_device->GetTagInfo(applet_output.tag_info); | ||||
|     nfp_device->Finalize(); | ||||
| 
 | ||||
|     std::vector<u8> out_data(sizeof(ReturnValueForAmiiboSettings)); | ||||
|     std::memcpy(out_data.data(), &applet_output, sizeof(ReturnValueForAmiiboSettings)); | ||||
| 
 | ||||
|     is_complete = true; | ||||
| 
 | ||||
|     broker.PushNormalDataFromApplet(std::make_shared<IStorage>(system, std::move(out_data))); | ||||
|     broker.SignalStateChanged(); | ||||
| } | ||||
| 
 | ||||
| void Cabinet::Cancel() { | ||||
|     ReturnValueForAmiiboSettings applet_output{}; | ||||
|     applet_output.device_handle = applet_input_common.device_handle; | ||||
|     applet_output.result = CabinetResult::Cancel; | ||||
|     nfp_device->Finalize(); | ||||
| 
 | ||||
|     std::vector<u8> out_data(sizeof(ReturnValueForAmiiboSettings)); | ||||
|     std::memcpy(out_data.data(), &applet_output, sizeof(ReturnValueForAmiiboSettings)); | ||||
| 
 | ||||
|     is_complete = true; | ||||
| 
 | ||||
|     broker.PushNormalDataFromApplet(std::make_shared<IStorage>(system, std::move(out_data))); | ||||
|     broker.SignalStateChanged(); | ||||
| } | ||||
| 
 | ||||
| } // namespace Service::AM::Applets
 | ||||
							
								
								
									
										99
									
								
								src/core/hle/service/am/applets/applet_cabinet.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										99
									
								
								src/core/hle/service/am/applets/applet_cabinet.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,99 @@ | |||
| // SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
 | ||||
| // SPDX-License-Identifier: GPL-2.0-or-later
 | ||||
| 
 | ||||
| #pragma once | ||||
| 
 | ||||
| #include <array> | ||||
| 
 | ||||
| #include "core/hle/result.h" | ||||
| #include "core/hle/service/am/applets/applets.h" | ||||
| #include "core/hle/service/kernel_helpers.h" | ||||
| #include "core/hle/service/nfp/nfp_types.h" | ||||
| 
 | ||||
| namespace Kernel { | ||||
| class KEvent; | ||||
| class KReadableEvent; | ||||
| } // namespace Kernel
 | ||||
| 
 | ||||
| namespace Core { | ||||
| class System; | ||||
| } // namespace Core
 | ||||
| 
 | ||||
| namespace Service::NFP { | ||||
| class NfpDevice; | ||||
| } | ||||
| 
 | ||||
| namespace Service::AM::Applets { | ||||
| 
 | ||||
| enum class CabinetAppletVersion : s32 { | ||||
|     Version1 = 0x1, | ||||
| }; | ||||
| 
 | ||||
| enum class CabinetResult : u8 { | ||||
|     Cancel, | ||||
|     Success, | ||||
| }; | ||||
| 
 | ||||
| // This is nn::nfp::AmiiboSettingsStartParam
 | ||||
| struct AmiiboSettingsStartParam { | ||||
|     u64 device_handle; | ||||
|     std::array<u8, 0x20> param_1; | ||||
|     std::array<u8, 0x1> param_2; | ||||
| }; | ||||
| static_assert(sizeof(AmiiboSettingsStartParam) == 0x30, | ||||
|               "AmiiboSettingsStartParam is an invalid size"); | ||||
| 
 | ||||
| // This is nn::nfp::StartParamForAmiiboSettings
 | ||||
| struct StartParamForAmiiboSettings { | ||||
|     u8 param_1; | ||||
|     Service::NFP::CabinetMode applet_mode; | ||||
|     u8 flags; | ||||
|     u8 amiibo_settings_1; | ||||
|     u64 device_handle; | ||||
|     Service::NFP::TagInfo tag_info; | ||||
|     Service::NFP::RegisterInfo register_info; | ||||
|     std::array<u8, 0x20> amiibo_settings_3; | ||||
|     INSERT_PADDING_BYTES(0x20); | ||||
| }; | ||||
| static_assert(sizeof(StartParamForAmiiboSettings) == 0x1A8, | ||||
|               "StartParamForAmiiboSettings is an invalid size"); | ||||
| 
 | ||||
| // This is nn::nfp::ReturnValueForAmiiboSettings
 | ||||
| struct ReturnValueForAmiiboSettings { | ||||
|     CabinetResult result; | ||||
|     INSERT_PADDING_BYTES(0x3); | ||||
|     u64 device_handle; | ||||
|     Service::NFP::TagInfo tag_info; | ||||
|     Service::NFP::RegisterInfo register_info; | ||||
|     INSERT_PADDING_BYTES(0x24); | ||||
| }; | ||||
| static_assert(sizeof(ReturnValueForAmiiboSettings) == 0x190, | ||||
|               "ReturnValueForAmiiboSettings is an invalid size"); | ||||
| 
 | ||||
| class Cabinet final : public Applet { | ||||
| public: | ||||
|     explicit Cabinet(Core::System& system_, LibraryAppletMode applet_mode_, | ||||
|                      const Core::Frontend::CabinetApplet& frontend_); | ||||
|     ~Cabinet() override; | ||||
| 
 | ||||
|     void Initialize() override; | ||||
| 
 | ||||
|     bool TransactionComplete() const override; | ||||
|     Result GetStatus() const override; | ||||
|     void ExecuteInteractive() override; | ||||
|     void Execute() override; | ||||
|     void DisplayCompleted(bool apply_changes, const std::string& amiibo_name); | ||||
|     void Cancel(); | ||||
| 
 | ||||
| private: | ||||
|     const Core::Frontend::CabinetApplet& frontend; | ||||
|     Core::System& system; | ||||
| 
 | ||||
|     bool is_complete{false}; | ||||
|     std::shared_ptr<Service::NFP::NfpDevice> nfp_device; | ||||
|     Kernel::KEvent* availability_change_event; | ||||
|     KernelHelpers::ServiceContext service_context; | ||||
|     StartParamForAmiiboSettings applet_input_common{}; | ||||
| }; | ||||
| 
 | ||||
| } // namespace Service::AM::Applets
 | ||||
|  | @ -5,6 +5,7 @@ | |||
| 
 | ||||
| #include "common/assert.h" | ||||
| #include "core/core.h" | ||||
| #include "core/frontend/applets/cabinet.h" | ||||
| #include "core/frontend/applets/controller.h" | ||||
| #include "core/frontend/applets/error.h" | ||||
| #include "core/frontend/applets/general_frontend.h" | ||||
|  | @ -16,6 +17,7 @@ | |||
| #include "core/hle/service/am/am.h" | ||||
| #include "core/hle/service/am/applet_ae.h" | ||||
| #include "core/hle/service/am/applet_oe.h" | ||||
| #include "core/hle/service/am/applets/applet_cabinet.h" | ||||
| #include "core/hle/service/am/applets/applet_controller.h" | ||||
| #include "core/hle/service/am/applets/applet_error.h" | ||||
| #include "core/hle/service/am/applets/applet_general_backend.h" | ||||
|  | @ -171,13 +173,15 @@ void Applet::Initialize() { | |||
| 
 | ||||
| AppletFrontendSet::AppletFrontendSet() = default; | ||||
| 
 | ||||
| AppletFrontendSet::AppletFrontendSet(ControllerApplet controller_applet, ErrorApplet error_applet, | ||||
| AppletFrontendSet::AppletFrontendSet(CabinetApplet cabinet_applet, | ||||
|                                      ControllerApplet controller_applet, ErrorApplet error_applet, | ||||
|                                      MiiEdit mii_edit_, | ||||
|                                      ParentalControlsApplet parental_controls_applet, | ||||
|                                      PhotoViewer photo_viewer_, ProfileSelect profile_select_, | ||||
|                                      SoftwareKeyboard software_keyboard_, WebBrowser web_browser_) | ||||
|     : controller{std::move(controller_applet)}, error{std::move(error_applet)}, | ||||
|       mii_edit{std::move(mii_edit_)}, parental_controls{std::move(parental_controls_applet)}, | ||||
|     : cabinet{std::move(cabinet_applet)}, controller{std::move(controller_applet)}, | ||||
|       error{std::move(error_applet)}, mii_edit{std::move(mii_edit_)}, | ||||
|       parental_controls{std::move(parental_controls_applet)}, | ||||
|       photo_viewer{std::move(photo_viewer_)}, profile_select{std::move(profile_select_)}, | ||||
|       software_keyboard{std::move(software_keyboard_)}, web_browser{std::move(web_browser_)} {} | ||||
| 
 | ||||
|  | @ -196,6 +200,10 @@ const AppletFrontendSet& AppletManager::GetAppletFrontendSet() const { | |||
| } | ||||
| 
 | ||||
| void AppletManager::SetAppletFrontendSet(AppletFrontendSet set) { | ||||
|     if (set.cabinet != nullptr) { | ||||
|         frontend.cabinet = std::move(set.cabinet); | ||||
|     } | ||||
| 
 | ||||
|     if (set.controller != nullptr) { | ||||
|         frontend.controller = std::move(set.controller); | ||||
|     } | ||||
|  | @ -235,6 +243,10 @@ void AppletManager::SetDefaultAppletFrontendSet() { | |||
| } | ||||
| 
 | ||||
| void AppletManager::SetDefaultAppletsIfMissing() { | ||||
|     if (frontend.cabinet == nullptr) { | ||||
|         frontend.cabinet = std::make_unique<Core::Frontend::DefaultCabinetApplet>(); | ||||
|     } | ||||
| 
 | ||||
|     if (frontend.controller == nullptr) { | ||||
|         frontend.controller = | ||||
|             std::make_unique<Core::Frontend::DefaultControllerApplet>(system.HIDCore()); | ||||
|  | @ -279,6 +291,8 @@ std::shared_ptr<Applet> AppletManager::GetApplet(AppletId id, LibraryAppletMode | |||
|     switch (id) { | ||||
|     case AppletId::Auth: | ||||
|         return std::make_shared<Auth>(system, mode, *frontend.parental_controls); | ||||
|     case AppletId::Cabinet: | ||||
|         return std::make_shared<Cabinet>(system, mode, *frontend.cabinet); | ||||
|     case AppletId::Controller: | ||||
|         return std::make_shared<Controller>(system, mode, *frontend.controller); | ||||
|     case AppletId::Error: | ||||
|  |  | |||
|  | @ -16,6 +16,7 @@ class System; | |||
| } | ||||
| 
 | ||||
| namespace Core::Frontend { | ||||
| class CabinetApplet; | ||||
| class ControllerApplet; | ||||
| class ECommerceApplet; | ||||
| class ErrorApplet; | ||||
|  | @ -176,6 +177,7 @@ protected: | |||
| }; | ||||
| 
 | ||||
| struct AppletFrontendSet { | ||||
|     using CabinetApplet = std::unique_ptr<Core::Frontend::CabinetApplet>; | ||||
|     using ControllerApplet = std::unique_ptr<Core::Frontend::ControllerApplet>; | ||||
|     using ErrorApplet = std::unique_ptr<Core::Frontend::ErrorApplet>; | ||||
|     using MiiEdit = std::unique_ptr<Core::Frontend::MiiEditApplet>; | ||||
|  | @ -186,10 +188,11 @@ struct AppletFrontendSet { | |||
|     using WebBrowser = std::unique_ptr<Core::Frontend::WebBrowserApplet>; | ||||
| 
 | ||||
|     AppletFrontendSet(); | ||||
|     AppletFrontendSet(ControllerApplet controller_applet, ErrorApplet error_applet, | ||||
|                       MiiEdit mii_edit_, ParentalControlsApplet parental_controls_applet, | ||||
|                       PhotoViewer photo_viewer_, ProfileSelect profile_select_, | ||||
|                       SoftwareKeyboard software_keyboard_, WebBrowser web_browser_); | ||||
|     AppletFrontendSet(CabinetApplet cabinet_applet, ControllerApplet controller_applet, | ||||
|                       ErrorApplet error_applet, MiiEdit mii_edit_, | ||||
|                       ParentalControlsApplet parental_controls_applet, PhotoViewer photo_viewer_, | ||||
|                       ProfileSelect profile_select_, SoftwareKeyboard software_keyboard_, | ||||
|                       WebBrowser web_browser_); | ||||
|     ~AppletFrontendSet(); | ||||
| 
 | ||||
|     AppletFrontendSet(const AppletFrontendSet&) = delete; | ||||
|  | @ -198,6 +201,7 @@ struct AppletFrontendSet { | |||
|     AppletFrontendSet(AppletFrontendSet&&) noexcept; | ||||
|     AppletFrontendSet& operator=(AppletFrontendSet&&) noexcept; | ||||
| 
 | ||||
|     CabinetApplet cabinet; | ||||
|     ControllerApplet controller; | ||||
|     ErrorApplet error; | ||||
|     MiiEdit mii_edit; | ||||
|  |  | |||
|  | @ -99,6 +99,13 @@ enum class TagProtocol : u32 { | |||
|     All = 0xFFFFFFFFU, | ||||
| }; | ||||
| 
 | ||||
| enum class CabinetMode : u8 { | ||||
|     StartNicknameAndOwnerSettings, | ||||
|     StartGameDataEraser, | ||||
|     StartRestorer, | ||||
|     StartFormatter, | ||||
| }; | ||||
| 
 | ||||
| using UniqueSerialNumber = std::array<u8, 7>; | ||||
| using LockBytes = std::array<u8, 2>; | ||||
| using HashData = std::array<u8, 0x20>; | ||||
|  |  | |||
|  | @ -26,6 +26,7 @@ | |||
| #include "configuration/configure_tas.h" | ||||
| #include "core/file_sys/vfs.h" | ||||
| #include "core/file_sys/vfs_real.h" | ||||
| #include "core/frontend/applets/cabinet.h" | ||||
| #include "core/frontend/applets/controller.h" | ||||
| #include "core/frontend/applets/general_frontend.h" | ||||
| #include "core/frontend/applets/mii_edit.h" | ||||
|  | @ -1547,6 +1548,7 @@ bool GMainWindow::LoadROM(const QString& filename, u64 program_id, std::size_t p | |||
|     system->SetFilesystem(vfs); | ||||
| 
 | ||||
|     system->SetAppletFrontendSet({ | ||||
|         nullptr,                                       // Amiibo Manager
 | ||||
|         std::make_unique<QtControllerSelector>(*this), // Controller Selector
 | ||||
|         std::make_unique<QtErrorDisplay>(*this),       // Error Display
 | ||||
|         nullptr,                                       // Mii Editor
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 german77
						german77