From 18123ff958b0a4d877dab45a54637245c3b296ba Mon Sep 17 00:00:00 2001 From: Liam Date: Thu, 10 Nov 2022 19:17:54 -0500 Subject: gdbstub: add ams monitor commands --- src/core/hle/kernel/k_page_table.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/core/hle') diff --git a/src/core/hle/kernel/k_page_table.h b/src/core/hle/kernel/k_page_table.h index 950850291..f1ca785d7 100644 --- a/src/core/hle/kernel/k_page_table.h +++ b/src/core/hle/kernel/k_page_table.h @@ -320,6 +320,9 @@ public: constexpr VAddr GetAliasCodeRegionStart() const { return m_alias_code_region_start; } + constexpr VAddr GetAliasCodeRegionEnd() const { + return m_alias_code_region_end; + } constexpr VAddr GetAliasCodeRegionSize() const { return m_alias_code_region_end - m_alias_code_region_start; } -- cgit v1.2.3 From 651f6598ac8a980700c330f382d711f7429571a8 Mon Sep 17 00:00:00 2001 From: Liam Date: Sat, 12 Nov 2022 11:02:07 -0500 Subject: kernel: implement FlushProcessDataCache --- src/core/hle/kernel/svc.cpp | 26 +++++++++++------ src/core/hle/kernel/svc_wrap.h | 8 ++++++ src/core/memory.cpp | 65 ++++++++++++++++++++++++++++++++++++++++++ src/core/memory.h | 34 ++++++++++++++++++++++ 4 files changed, 125 insertions(+), 8 deletions(-) (limited to 'src/core/hle') diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index 9962ad171..e520cab47 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp @@ -2701,14 +2701,24 @@ static Result GetThreadList(Core::System& system, u32* out_num_threads, VAddr ou return ResultSuccess; } -static Result FlushProcessDataCache32([[maybe_unused]] Core::System& system, - [[maybe_unused]] Handle handle, [[maybe_unused]] u32 address, - [[maybe_unused]] u32 size) { - // Note(Blinkhawk): For emulation purposes of the data cache this is mostly a no-op, - // as all emulation is done in the same cache level in host architecture, thus data cache - // does not need flushing. - LOG_DEBUG(Kernel_SVC, "called"); - return ResultSuccess; +static Result FlushProcessDataCache32(Core::System& system, Handle process_handle, u64 address, + u64 size) { + // Validate address/size. + R_UNLESS(size > 0, ResultInvalidSize); + R_UNLESS(address == static_cast(address), ResultInvalidCurrentMemory); + R_UNLESS(size == static_cast(size), ResultInvalidCurrentMemory); + + // Get the process from its handle. + KScopedAutoObject process = + system.Kernel().CurrentProcess()->GetHandleTable().GetObject(process_handle); + R_UNLESS(process.IsNotNull(), ResultInvalidHandle); + + // Verify the region is within range. + auto& page_table = process->PageTable(); + R_UNLESS(page_table.Contains(address, size), ResultInvalidCurrentMemory); + + // Perform the operation. + R_RETURN(system.Memory().FlushDataCache(*process, address, size)); } namespace { diff --git a/src/core/hle/kernel/svc_wrap.h b/src/core/hle/kernel/svc_wrap.h index 272c54cf7..3730937fe 100644 --- a/src/core/hle/kernel/svc_wrap.h +++ b/src/core/hle/kernel/svc_wrap.h @@ -722,4 +722,12 @@ void SvcWrap32(Core::System& system) { FuncReturn(system, retval); } +// Used by Invalidate/Store/FlushProcessDataCache32 +template +void SvcWrap32(Core::System& system) { + const u64 address = (Param(system, 3) << 32) | Param(system, 2); + const u64 size = (Param(system, 4) << 32) | Param(system, 1); + FuncReturn32(system, func(system, Param32(system, 0), address, size).raw); +} + } // namespace Kernel diff --git a/src/core/memory.cpp b/src/core/memory.cpp index 3ca80c8ff..3141122f1 100644 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp @@ -6,6 +6,7 @@ #include "common/assert.h" #include "common/atomic_ops.h" +#include "common/cache_management.h" #include "common/common_types.h" #include "common/logging/log.h" #include "common/page_table.h" @@ -329,6 +330,55 @@ struct Memory::Impl { }); } + template + Result PerformCacheOperation(const Kernel::KProcess& process, VAddr dest_addr, std::size_t size, + Callback&& cb) { + class InvalidMemoryException : public std::exception {}; + + try { + WalkBlock( + process, dest_addr, size, + [&](const std::size_t block_size, const VAddr current_vaddr) { + LOG_ERROR(HW_Memory, "Unmapped cache maintenance @ {:#018X}", current_vaddr); + throw InvalidMemoryException(); + }, + [&](const std::size_t block_size, u8* const host_ptr) { cb(block_size, host_ptr); }, + [&](const VAddr current_vaddr, const std::size_t block_size, u8* const host_ptr) { + system.GPU().FlushRegion(current_vaddr, block_size); + cb(block_size, host_ptr); + }, + [](const std::size_t block_size) {}); + } catch (InvalidMemoryException&) { + return Kernel::ResultInvalidCurrentMemory; + } + + return ResultSuccess; + } + + Result InvalidateDataCache(const Kernel::KProcess& process, VAddr dest_addr, std::size_t size) { + auto perform = [&](const std::size_t block_size, u8* const host_ptr) { + // Do nothing; this operation (dc ivac) cannot be supported + // from EL0 + }; + return PerformCacheOperation(process, dest_addr, size, perform); + } + + Result StoreDataCache(const Kernel::KProcess& process, VAddr dest_addr, std::size_t size) { + auto perform = [&](const std::size_t block_size, u8* const host_ptr) { + // dc cvac: Store to point of coherency + Common::DataCacheLineCleanByVAToPoC(host_ptr, block_size); + }; + return PerformCacheOperation(process, dest_addr, size, perform); + } + + Result FlushDataCache(const Kernel::KProcess& process, VAddr dest_addr, std::size_t size) { + auto perform = [&](const std::size_t block_size, u8* const host_ptr) { + // dc civac: Store to point of coherency, and invalidate from cache + Common::DataCacheLineCleanAndInvalidateByVAToPoC(host_ptr, block_size); + }; + return PerformCacheOperation(process, dest_addr, size, perform); + } + void MarkRegionDebug(VAddr vaddr, u64 size, bool debug) { if (vaddr == 0) { return; @@ -786,6 +836,21 @@ void Memory::ZeroBlock(const Kernel::KProcess& process, VAddr dest_addr, const s impl->ZeroBlock(process, dest_addr, size); } +Result Memory::InvalidateDataCache(const Kernel::KProcess& process, VAddr dest_addr, + const std::size_t size) { + return impl->InvalidateDataCache(process, dest_addr, size); +} + +Result Memory::StoreDataCache(const Kernel::KProcess& process, VAddr dest_addr, + const std::size_t size) { + return impl->StoreDataCache(process, dest_addr, size); +} + +Result Memory::FlushDataCache(const Kernel::KProcess& process, VAddr dest_addr, + const std::size_t size) { + return impl->FlushDataCache(process, dest_addr, size); +} + void Memory::RasterizerMarkRegionCached(VAddr vaddr, u64 size, bool cached) { impl->RasterizerMarkRegionCached(vaddr, size, cached); } diff --git a/src/core/memory.h b/src/core/memory.h index 81eac448b..31fe699d8 100644 --- a/src/core/memory.h +++ b/src/core/memory.h @@ -7,6 +7,7 @@ #include #include #include "common/common_types.h" +#include "core/hle/result.h" namespace Common { struct PageTable; @@ -449,6 +450,39 @@ public: */ void ZeroBlock(const Kernel::KProcess& process, VAddr dest_addr, std::size_t size); + /** + * Invalidates a range of bytes within the current process' address space at the specified + * virtual address. + * + * @param process The process that will have data invalidated within its address space. + * @param dest_addr The destination virtual address to invalidate the data from. + * @param size The size of the range to invalidate, in bytes. + * + */ + Result InvalidateDataCache(const Kernel::KProcess& process, VAddr dest_addr, std::size_t size); + + /** + * Stores a range of bytes within the current process' address space at the specified + * virtual address. + * + * @param process The process that will have data stored within its address space. + * @param dest_addr The destination virtual address to store the data from. + * @param size The size of the range to store, in bytes. + * + */ + Result StoreDataCache(const Kernel::KProcess& process, VAddr dest_addr, std::size_t size); + + /** + * Flushes a range of bytes within the current process' address space at the specified + * virtual address. + * + * @param process The process that will have data flushed within its address space. + * @param dest_addr The destination virtual address to flush the data from. + * @param size The size of the range to flush, in bytes. + * + */ + Result FlushDataCache(const Kernel::KProcess& process, VAddr dest_addr, std::size_t size); + /** * Marks each page within the specified address range as cached or uncached. * -- cgit v1.2.3 From 6c045c9beb9c202fdea49274edd845fb2af491c3 Mon Sep 17 00:00:00 2001 From: german77 Date: Sun, 13 Nov 2022 10:52:48 -0600 Subject: service: nfc: fix tagprotocol and implement GetApplicationAreaId --- src/core/hle/service/nfp/nfp_device.cpp | 33 +++++++++++++++++++++++++++++++-- src/core/hle/service/nfp/nfp_device.h | 6 ++++-- src/core/hle/service/nfp/nfp_types.h | 10 +++++++--- src/core/hle/service/nfp/nfp_user.cpp | 2 +- 4 files changed, 43 insertions(+), 8 deletions(-) (limited to 'src/core/hle') diff --git a/src/core/hle/service/nfp/nfp_device.cpp b/src/core/hle/service/nfp/nfp_device.cpp index b19672560..2f9dfa9c2 100644 --- a/src/core/hle/service/nfp/nfp_device.cpp +++ b/src/core/hle/service/nfp/nfp_device.cpp @@ -77,6 +77,9 @@ void NfpDevice::NpadUpdate(Core::HID::ControllerTriggerType type) { LoadAmiibo(nfc_status.data); break; case Common::Input::NfcState::AmiiboRemoved: + if (device_state == DeviceState::Initialized || device_state == DeviceState::TagRemoved) { + break; + } if (device_state != DeviceState::SearchingForTag) { CloseAmiibo(); } @@ -97,6 +100,8 @@ bool NfpDevice::LoadAmiibo(std::span data) { return false; } + // TODO: Filter by allowed_protocols here + memcpy(&encrypted_tag_data, data.data(), sizeof(EncryptedNTAG215File)); device_state = DeviceState::TagFound; @@ -143,7 +148,7 @@ void NfpDevice::Finalize() { device_state = DeviceState::Unavailable; } -Result NfpDevice::StartDetection(s32 protocol_) { +Result NfpDevice::StartDetection([[maybe_unused]] TagProtocol allowed_protocol) { if (device_state != DeviceState::Initialized && device_state != DeviceState::TagRemoved) { LOG_ERROR(Service_NFP, "Wrong device state {}", device_state); return WrongDeviceState; @@ -155,7 +160,7 @@ Result NfpDevice::StartDetection(s32 protocol_) { } device_state = DeviceState::SearchingForTag; - protocol = protocol_; + allowed_protocols = allowed_protocol; return ResultSuccess; } @@ -469,6 +474,30 @@ Result NfpDevice::OpenApplicationArea(u32 access_id) { return ResultSuccess; } +Result NfpDevice::GetApplicationAreaId(u32& application_area_id) const { + if (device_state != DeviceState::TagMounted) { + LOG_ERROR(Service_NFP, "Wrong device state {}", device_state); + if (device_state == DeviceState::TagRemoved) { + return TagRemoved; + } + return WrongDeviceState; + } + + if (mount_target == MountTarget::None || mount_target == MountTarget::Rom) { + LOG_ERROR(Service_NFP, "Amiibo is read only", device_state); + return WrongDeviceState; + } + + if (tag_data.settings.settings.appdata_initialized.Value() == 0) { + LOG_WARNING(Service_NFP, "Application area is not initialized"); + return ApplicationAreaIsNotInitialized; + } + + application_area_id = tag_data.application_area_id; + + return ResultSuccess; +} + Result NfpDevice::GetApplicationArea(std::vector& data) const { if (device_state != DeviceState::TagMounted) { LOG_ERROR(Service_NFP, "Wrong device state {}", device_state); diff --git a/src/core/hle/service/nfp/nfp_device.h b/src/core/hle/service/nfp/nfp_device.h index 76d0e9ae4..3d1cb4609 100644 --- a/src/core/hle/service/nfp/nfp_device.h +++ b/src/core/hle/service/nfp/nfp_device.h @@ -4,6 +4,7 @@ #pragma once #include +#include #include #include "common/common_funcs.h" @@ -37,7 +38,7 @@ public: void Initialize(); void Finalize(); - Result StartDetection(s32 protocol_); + Result StartDetection(TagProtocol allowed_protocol); Result StopDetection(); Result Mount(MountTarget mount_target); Result Unmount(); @@ -53,6 +54,7 @@ public: Result DeleteAllData(); Result OpenApplicationArea(u32 access_id); + Result GetApplicationAreaId(u32& application_area_id) const; Result GetApplicationArea(std::vector& data) const; Result SetApplicationArea(std::span data); Result CreateApplicationArea(u32 access_id, std::span data); @@ -88,7 +90,7 @@ private: bool is_data_moddified{}; bool is_app_area_open{}; - s32 protocol{}; + TagProtocol allowed_protocols{}; s64 current_posix_time{}; MountTarget mount_target{MountTarget::None}; DeviceState device_state{DeviceState::Unavailable}; diff --git a/src/core/hle/service/nfp/nfp_types.h b/src/core/hle/service/nfp/nfp_types.h index 63d5917cb..866aefe20 100644 --- a/src/core/hle/service/nfp/nfp_types.h +++ b/src/core/hle/service/nfp/nfp_types.h @@ -88,11 +88,15 @@ enum class PackedTagType : u8 { Type5, // ISO15693 RW/RO 540 bytes 106kbit/s }; +// Verify this enum. It might be completely wrong default protocol is 0x48 enum class TagProtocol : u32 { None, - TypeA, // ISO14443A - TypeB, // ISO14443B - TypeF, // Sony Felica + TypeA = 1U << 0, // ISO14443A + TypeB = 1U << 1, // ISO14443B + TypeF = 1U << 2, // Sony Felica + Unknown1 = 1U << 3, + Unknown2 = 1U << 5, + All = 0xFFFFFFFFU, }; using UniqueSerialNumber = std::array; diff --git a/src/core/hle/service/nfp/nfp_user.cpp b/src/core/hle/service/nfp/nfp_user.cpp index 33e2ef518..ac492cc27 100644 --- a/src/core/hle/service/nfp/nfp_user.cpp +++ b/src/core/hle/service/nfp/nfp_user.cpp @@ -130,7 +130,7 @@ void IUser::ListDevices(Kernel::HLERequestContext& ctx) { void IUser::StartDetection(Kernel::HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; const auto device_handle{rp.Pop()}; - const auto nfp_protocol{rp.Pop()}; + const auto nfp_protocol{rp.PopEnum()}; LOG_INFO(Service_NFP, "called, device_handle={}, nfp_protocol={}", device_handle, nfp_protocol); if (state == State::NonInitialized) { -- cgit v1.2.3 From fb57cd26a1219a5c91d2cb4dec402528f8ba308e Mon Sep 17 00:00:00 2001 From: german77 Date: Sun, 13 Nov 2022 11:07:48 -0600 Subject: service: am: Implement cabinet applet backend --- src/core/CMakeLists.txt | 4 + src/core/frontend/applets/cabinet.cpp | 20 +++ src/core/frontend/applets/cabinet.h | 36 +++++ src/core/hle/service/am/applets/applet_cabinet.cpp | 169 +++++++++++++++++++++ src/core/hle/service/am/applets/applet_cabinet.h | 99 ++++++++++++ src/core/hle/service/am/applets/applets.cpp | 20 ++- src/core/hle/service/am/applets/applets.h | 12 +- src/core/hle/service/nfp/nfp_types.h | 7 + src/yuzu/main.cpp | 2 + 9 files changed, 362 insertions(+), 7 deletions(-) create mode 100644 src/core/frontend/applets/cabinet.cpp create mode 100644 src/core/frontend/applets/cabinet.h create mode 100644 src/core/hle/service/am/applets/applet_cabinet.cpp create mode 100644 src/core/hle/service/am/applets/applet_cabinet.h (limited to 'src/core/hle') 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 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 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 @@ +// 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 + +namespace Core::Frontend { + +CabinetApplet::~CabinetApplet() = default; + +void DefaultCabinetApplet::ShowCabinetApplet( + std::function callback, const CabinetParameters& parameters, + std::shared_ptr nfp_device) const { + LOG_WARNING(Service_AM, "(STUBBED) called"); + callback(false, {}); +} + +} // 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 @@ +// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include +#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 callback, + const CabinetParameters& parameters, + std::shared_ptr nfp_device) const = 0; +}; + +class DefaultCabinetApplet final : public CabinetApplet { +public: + void ShowCabinetApplet(std::function callback, + const CabinetParameters& parameters, + std::shared_ptr nfp_device) const override; +}; + +} // 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 @@ +// 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( + 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 out_data(sizeof(ReturnValueForAmiiboSettings)); + std::memcpy(out_data.data(), &applet_output, sizeof(ReturnValueForAmiiboSettings)); + + is_complete = true; + + broker.PushNormalDataFromApplet(std::make_shared(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 out_data(sizeof(ReturnValueForAmiiboSettings)); + std::memcpy(out_data.data(), &applet_output, sizeof(ReturnValueForAmiiboSettings)); + + is_complete = true; + + broker.PushNormalDataFromApplet(std::make_shared(system, std::move(out_data))); + broker.SignalStateChanged(); +} + +} // 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 @@ +// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include + +#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 param_1; + std::array 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 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 nfp_device; + Kernel::KEvent* availability_change_event; + KernelHelpers::ServiceContext service_context; + StartParamForAmiiboSettings applet_input_common{}; +}; + +} // 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 @@ #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(); + } + if (frontend.controller == nullptr) { frontend.controller = std::make_unique(system.HIDCore()); @@ -279,6 +291,8 @@ std::shared_ptr AppletManager::GetApplet(AppletId id, LibraryAppletMode switch (id) { case AppletId::Auth: return std::make_shared(system, mode, *frontend.parental_controls); + case AppletId::Cabinet: + return std::make_shared(system, mode, *frontend.cabinet); case AppletId::Controller: return std::make_shared(system, mode, *frontend.controller); 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; } namespace Core::Frontend { +class CabinetApplet; class ControllerApplet; class ECommerceApplet; class ErrorApplet; @@ -176,6 +177,7 @@ protected: }; struct AppletFrontendSet { + using CabinetApplet = std::unique_ptr; using ControllerApplet = std::unique_ptr; using ErrorApplet = std::unique_ptr; using MiiEdit = std::unique_ptr; @@ -186,10 +188,11 @@ struct AppletFrontendSet { using WebBrowser = std::unique_ptr; 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; 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 { All = 0xFFFFFFFFU, }; +enum class CabinetMode : u8 { + StartNicknameAndOwnerSettings, + StartGameDataEraser, + StartRestorer, + StartFormatter, +}; + using UniqueSerialNumber = std::array; using LockBytes = std::array; using HashData = std::array; 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 @@ #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(*this), // Controller Selector std::make_unique(*this), // Error Display nullptr, // Mii Editor -- cgit v1.2.3 From a253d1557d7d1fb1add6ae923ccb452d423d4547 Mon Sep 17 00:00:00 2001 From: german77 Date: Sun, 13 Nov 2022 13:59:00 -0600 Subject: service: am: Fix cabinet applet result --- src/core/hle/service/am/applets/applet_cabinet.cpp | 20 ++++++++++++++------ src/core/hle/service/am/applets/applet_cabinet.h | 12 ++++++++---- 2 files changed, 22 insertions(+), 10 deletions(-) (limited to 'src/core/hle') diff --git a/src/core/hle/service/am/applets/applet_cabinet.cpp b/src/core/hle/service/am/applets/applet_cabinet.cpp index 1eb5a9f22..01f577ab9 100644 --- a/src/core/hle/service/am/applets/applet_cabinet.cpp +++ b/src/core/hle/service/am/applets/applet_cabinet.cpp @@ -32,7 +32,7 @@ void Cabinet::Initialize() { LOG_INFO(Service_HID, "Initializing Cabinet Applet."); - LOG_ERROR(Service_HID, + LOG_DEBUG(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, @@ -111,14 +111,14 @@ void Cabinet::DisplayCompleted(bool apply_changes, const std::string& amiibo_nam Cancel(); } - if (nfp_device->GetCurrentState() != Service::NFP::DeviceState::TagFound) { + 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()); + memcpy(name.data(), amiibo_name.data(), std::min(amiibo_name.size(), name.size() - 1)); nfp_device->SetNicknameAndOwner(name); break; } @@ -137,11 +137,19 @@ void Cabinet::DisplayCompleted(bool apply_changes, const std::string& amiibo_nam } 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); + applet_output.result = CabinetResult::Cancel; + const auto reg_result = nfp_device->GetRegisterInfo(applet_output.register_info); + const auto tag_result = nfp_device->GetTagInfo(applet_output.tag_info); nfp_device->Finalize(); + if (reg_result.IsSuccess() && tag_result.IsSuccess()) { + applet_output.result = CabinetResult::All; + } else if (reg_result.IsSuccess()) { + applet_output.result = CabinetResult::RegisterInfo; + } else if (tag_result.IsSuccess()) { + applet_output.result = CabinetResult::TagInfo; + } + std::vector out_data(sizeof(ReturnValueForAmiiboSettings)); std::memcpy(out_data.data(), &applet_output, sizeof(ReturnValueForAmiiboSettings)); diff --git a/src/core/hle/service/am/applets/applet_cabinet.h b/src/core/hle/service/am/applets/applet_cabinet.h index 2d3f22434..8466d5997 100644 --- a/src/core/hle/service/am/applets/applet_cabinet.h +++ b/src/core/hle/service/am/applets/applet_cabinet.h @@ -31,18 +31,21 @@ enum class CabinetAppletVersion : s32 { enum class CabinetResult : u8 { Cancel, - Success, + TagInfo = 1 << 1, + RegisterInfo = 1 << 2, + All = TagInfo | RegisterInfo, }; // This is nn::nfp::AmiiboSettingsStartParam struct AmiiboSettingsStartParam { u64 device_handle; std::array param_1; - std::array param_2; + u8 param_2; }; static_assert(sizeof(AmiiboSettingsStartParam) == 0x30, "AmiiboSettingsStartParam is an invalid size"); +#pragma pack(1) // This is nn::nfp::StartParamForAmiiboSettings struct StartParamForAmiiboSettings { u8 param_1; @@ -53,7 +56,7 @@ struct StartParamForAmiiboSettings { Service::NFP::TagInfo tag_info; Service::NFP::RegisterInfo register_info; std::array amiibo_settings_3; - INSERT_PADDING_BYTES(0x20); + INSERT_PADDING_BYTES(0x24); }; static_assert(sizeof(StartParamForAmiiboSettings) == 0x1A8, "StartParamForAmiiboSettings is an invalid size"); @@ -67,8 +70,9 @@ struct ReturnValueForAmiiboSettings { Service::NFP::RegisterInfo register_info; INSERT_PADDING_BYTES(0x24); }; -static_assert(sizeof(ReturnValueForAmiiboSettings) == 0x190, +static_assert(sizeof(ReturnValueForAmiiboSettings) == 0x188, "ReturnValueForAmiiboSettings is an invalid size"); +#pragma pack() class Cabinet final : public Applet { public: -- cgit v1.2.3 From 75e6ec85e107d6e5422d882b97faaa813970d42e Mon Sep 17 00:00:00 2001 From: german77 Date: Sun, 13 Nov 2022 15:14:08 -0600 Subject: general: Address review comments --- src/core/frontend/applets/cabinet.cpp | 2 +- src/core/frontend/applets/cabinet.h | 7 +- src/core/hle/service/am/applets/applet_cabinet.cpp | 16 +- src/core/hle/service/am/applets/applet_cabinet.h | 11 +- src/core/hle/service/nfp/nfp_device.cpp | 4 +- src/input_common/drivers/virtual_amiibo.cpp | 2 +- src/input_common/drivers/virtual_amiibo.h | 2 +- src/yuzu/CMakeLists.txt | 6 +- src/yuzu/applets/qt_amiibo_manager.cpp | 247 ----------- src/yuzu/applets/qt_amiibo_manager.h | 93 ---- src/yuzu/applets/qt_amiibo_manager.ui | 491 -------------------- src/yuzu/applets/qt_amiibo_settings.cpp | 260 +++++++++++ src/yuzu/applets/qt_amiibo_settings.h | 83 ++++ src/yuzu/applets/qt_amiibo_settings.ui | 494 +++++++++++++++++++++ src/yuzu/main.cpp | 14 +- src/yuzu/main.h | 6 +- 16 files changed, 874 insertions(+), 864 deletions(-) delete mode 100644 src/yuzu/applets/qt_amiibo_manager.cpp delete mode 100644 src/yuzu/applets/qt_amiibo_manager.h delete mode 100644 src/yuzu/applets/qt_amiibo_manager.ui create mode 100644 src/yuzu/applets/qt_amiibo_settings.cpp create mode 100644 src/yuzu/applets/qt_amiibo_settings.h create mode 100644 src/yuzu/applets/qt_amiibo_settings.ui (limited to 'src/core/hle') diff --git a/src/core/frontend/applets/cabinet.cpp b/src/core/frontend/applets/cabinet.cpp index 5ade75de0..26c7fefe3 100644 --- a/src/core/frontend/applets/cabinet.cpp +++ b/src/core/frontend/applets/cabinet.cpp @@ -11,7 +11,7 @@ namespace Core::Frontend { CabinetApplet::~CabinetApplet() = default; void DefaultCabinetApplet::ShowCabinetApplet( - std::function callback, const CabinetParameters& parameters, + const CabinetCallback& callback, const CabinetParameters& parameters, std::shared_ptr nfp_device) const { LOG_WARNING(Service_AM, "(STUBBED) called"); callback(false, {}); diff --git a/src/core/frontend/applets/cabinet.h b/src/core/frontend/applets/cabinet.h index 1c68bf57d..c28a235c1 100644 --- a/src/core/frontend/applets/cabinet.h +++ b/src/core/frontend/applets/cabinet.h @@ -18,18 +18,19 @@ struct CabinetParameters { Service::NFP::CabinetMode mode; }; +using CabinetCallback = std::function; + class CabinetApplet { public: virtual ~CabinetApplet(); - virtual void ShowCabinetApplet(std::function callback, + virtual void ShowCabinetApplet(const CabinetCallback& callback, const CabinetParameters& parameters, std::shared_ptr nfp_device) const = 0; }; class DefaultCabinetApplet final : public CabinetApplet { public: - void ShowCabinetApplet(std::function callback, - const CabinetParameters& parameters, + void ShowCabinetApplet(const CabinetCallback& callback, const CabinetParameters& parameters, std::shared_ptr nfp_device) const override; }; diff --git a/src/core/hle/service/am/applets/applet_cabinet.cpp b/src/core/hle/service/am/applets/applet_cabinet.cpp index 01f577ab9..d0969b0f1 100644 --- a/src/core/hle/service/am/applets/applet_cabinet.cpp +++ b/src/core/hle/service/am/applets/applet_cabinet.cpp @@ -98,7 +98,7 @@ void Cabinet::Execute() { } } -void Cabinet::DisplayCompleted(bool apply_changes, const std::string& amiibo_name) { +void Cabinet::DisplayCompleted(bool apply_changes, std::string_view amiibo_name) { Service::Mii::MiiManager manager; ReturnValueForAmiiboSettings applet_output{}; @@ -118,7 +118,7 @@ void Cabinet::DisplayCompleted(bool apply_changes, const std::string& amiibo_nam switch (applet_input_common.applet_mode) { case Service::NFP::CabinetMode::StartNicknameAndOwnerSettings: { Service::NFP::AmiiboName name{}; - memcpy(name.data(), amiibo_name.data(), std::min(amiibo_name.size(), name.size() - 1)); + std::memcpy(name.data(), amiibo_name.data(), std::min(amiibo_name.size(), name.size() - 1)); nfp_device->SetNicknameAndOwner(name); break; } @@ -142,12 +142,12 @@ void Cabinet::DisplayCompleted(bool apply_changes, const std::string& amiibo_nam const auto tag_result = nfp_device->GetTagInfo(applet_output.tag_info); nfp_device->Finalize(); - if (reg_result.IsSuccess() && tag_result.IsSuccess()) { - applet_output.result = CabinetResult::All; - } else if (reg_result.IsSuccess()) { - applet_output.result = CabinetResult::RegisterInfo; - } else if (tag_result.IsSuccess()) { - applet_output.result = CabinetResult::TagInfo; + if (reg_result.IsSuccess()) { + applet_output.result |= CabinetResult::RegisterInfo; + } + + if (tag_result.IsSuccess()) { + applet_output.result |= CabinetResult::TagInfo; } std::vector out_data(sizeof(ReturnValueForAmiiboSettings)); diff --git a/src/core/hle/service/am/applets/applet_cabinet.h b/src/core/hle/service/am/applets/applet_cabinet.h index 8466d5997..84197a807 100644 --- a/src/core/hle/service/am/applets/applet_cabinet.h +++ b/src/core/hle/service/am/applets/applet_cabinet.h @@ -25,16 +25,17 @@ class NfpDevice; namespace Service::AM::Applets { -enum class CabinetAppletVersion : s32 { +enum class CabinetAppletVersion : u32 { Version1 = 0x1, }; enum class CabinetResult : u8 { - Cancel, + Cancel = 0, TagInfo = 1 << 1, RegisterInfo = 1 << 2, All = TagInfo | RegisterInfo, }; +DECLARE_ENUM_FLAG_OPERATORS(CabinetResult) // This is nn::nfp::AmiiboSettingsStartParam struct AmiiboSettingsStartParam { @@ -45,7 +46,7 @@ struct AmiiboSettingsStartParam { static_assert(sizeof(AmiiboSettingsStartParam) == 0x30, "AmiiboSettingsStartParam is an invalid size"); -#pragma pack(1) +#pragma pack(push, 1) // This is nn::nfp::StartParamForAmiiboSettings struct StartParamForAmiiboSettings { u8 param_1; @@ -72,7 +73,7 @@ struct ReturnValueForAmiiboSettings { }; static_assert(sizeof(ReturnValueForAmiiboSettings) == 0x188, "ReturnValueForAmiiboSettings is an invalid size"); -#pragma pack() +#pragma pack(pop) class Cabinet final : public Applet { public: @@ -86,7 +87,7 @@ public: Result GetStatus() const override; void ExecuteInteractive() override; void Execute() override; - void DisplayCompleted(bool apply_changes, const std::string& amiibo_name); + void DisplayCompleted(bool apply_changes, std::string_view amiibo_name); void Cancel(); private: diff --git a/src/core/hle/service/nfp/nfp_device.cpp b/src/core/hle/service/nfp/nfp_device.cpp index 2f9dfa9c2..e1bf90d7c 100644 --- a/src/core/hle/service/nfp/nfp_device.cpp +++ b/src/core/hle/service/nfp/nfp_device.cpp @@ -148,7 +148,7 @@ void NfpDevice::Finalize() { device_state = DeviceState::Unavailable; } -Result NfpDevice::StartDetection([[maybe_unused]] TagProtocol allowed_protocol) { +Result NfpDevice::StartDetection(TagProtocol allowed_protocol) { if (device_state != DeviceState::Initialized && device_state != DeviceState::TagRemoved) { LOG_ERROR(Service_NFP, "Wrong device state {}", device_state); return WrongDeviceState; @@ -475,6 +475,8 @@ Result NfpDevice::OpenApplicationArea(u32 access_id) { } Result NfpDevice::GetApplicationAreaId(u32& application_area_id) const { + application_area_id = {}; + if (device_state != DeviceState::TagMounted) { LOG_ERROR(Service_NFP, "Wrong device state {}", device_state); if (device_state == DeviceState::TagRemoved) { diff --git a/src/input_common/drivers/virtual_amiibo.cpp b/src/input_common/drivers/virtual_amiibo.cpp index 252c660d8..564a188e5 100644 --- a/src/input_common/drivers/virtual_amiibo.cpp +++ b/src/input_common/drivers/virtual_amiibo.cpp @@ -109,7 +109,7 @@ VirtualAmiibo::Info VirtualAmiibo::CloseAmiibo() { return Info::Success; } -std::string VirtualAmiibo::GetLastFilePath() { +std::string VirtualAmiibo::GetLastFilePath() const { return file_path; } diff --git a/src/input_common/drivers/virtual_amiibo.h b/src/input_common/drivers/virtual_amiibo.h index f2294b8b0..9baeb3997 100644 --- a/src/input_common/drivers/virtual_amiibo.h +++ b/src/input_common/drivers/virtual_amiibo.h @@ -50,7 +50,7 @@ public: Info ReloadAmiibo(); Info CloseAmiibo(); - std::string GetLastFilePath(); + std::string GetLastFilePath() const; private: static constexpr std::size_t amiibo_size = 0x21C; diff --git a/src/yuzu/CMakeLists.txt b/src/yuzu/CMakeLists.txt index 8571d9c7c..adad36221 100644 --- a/src/yuzu/CMakeLists.txt +++ b/src/yuzu/CMakeLists.txt @@ -18,9 +18,9 @@ add_executable(yuzu about_dialog.cpp about_dialog.h aboutdialog.ui - applets/qt_amiibo_manager.cpp - applets/qt_amiibo_manager.h - applets/qt_amiibo_manager.ui + applets/qt_amiibo_settings.cpp + applets/qt_amiibo_settings.h + applets/qt_amiibo_settings.ui applets/qt_controller.cpp applets/qt_controller.h applets/qt_controller.ui diff --git a/src/yuzu/applets/qt_amiibo_manager.cpp b/src/yuzu/applets/qt_amiibo_manager.cpp deleted file mode 100644 index 9c7b15d06..000000000 --- a/src/yuzu/applets/qt_amiibo_manager.cpp +++ /dev/null @@ -1,247 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#include -#include -#include -#include - -#include "common/assert.h" -#include "common/string_util.h" -#include "core/hle/service/nfp/nfp_device.h" -#include "core/hle/service/nfp/nfp_result.h" -#include "input_common/drivers/virtual_amiibo.h" -#include "input_common/main.h" -#include "ui_qt_amiibo_manager.h" -#include "web_service/web_backend.h" -#include "yuzu/applets/qt_amiibo_manager.h" -#include "yuzu/main.h" - -QtAmiiboManagerDialog::QtAmiiboManagerDialog(QWidget* parent, - Core::Frontend::CabinetParameters parameters_, - InputCommon::InputSubsystem* input_subsystem_, - std::shared_ptr nfp_device_) - : QDialog(parent), ui(std::make_unique()), - input_subsystem{input_subsystem_}, nfp_device{nfp_device_}, - parameters(std::move(parameters_)) { - ui->setupUi(this); - - LoadInfo(); - - resize(0, 0); -} - -QtAmiiboManagerDialog::~QtAmiiboManagerDialog() = default; - -int QtAmiiboManagerDialog::exec() { - if (!is_initalized) { - return QDialog::Rejected; - } - return QDialog::exec(); -} - -std::string QtAmiiboManagerDialog::GetName() { - return ui->amiiboCustomNameValue->text().toStdString(); -} - -void QtAmiiboManagerDialog::LoadInfo() { - if (input_subsystem->GetVirtualAmiibo()->ReloadAmiibo() != - InputCommon::VirtualAmiibo::Info::Success) { - return; - } - - if (nfp_device->GetCurrentState() != Service::NFP::DeviceState::TagFound && - nfp_device->GetCurrentState() != Service::NFP::DeviceState::TagMounted) { - return; - } - nfp_device->Mount(Service::NFP::MountTarget::All); - - Service::NFP::ModelInfo model_info{}; - const auto model_result = nfp_device->GetModelInfo(model_info); - - if (model_result.IsSuccess()) { - const auto amiibo_id = - fmt::format("{:04x}{:02x}{:02x}{:04x}{:02x}02", Common::swap16(model_info.character_id), - model_info.character_variant, model_info.amiibo_type, - model_info.model_number, model_info.series); - LOG_ERROR(Input, "{}", amiibo_id); - LoadAmiiboApiInfo(amiibo_id); - } - - LoadAmiiboData(); - LoadAmiiboGameInfo(); - - ui->amiiboDirectoryValue->setText( - QString::fromStdString(input_subsystem->GetVirtualAmiibo()->GetLastFilePath())); - - SetManagerDescription(); - is_initalized = true; -} - -void QtAmiiboManagerDialog::LoadAmiiboApiInfo(std::string amiibo_id) { - WebService::Client client{"https://amiiboapi.com", {}, {}}; - WebService::Client image_client{"https://raw.githubusercontent.com", {}, {}}; - const auto url_path = fmt::format("/api/amiibo/?id={}", amiibo_id); - - const auto amiibo_json = client.GetJson(url_path, true).returned_data; - if (amiibo_json.empty()) { - ui->amiiboImageLabel->setVisible(false); - ui->amiiboInfoGroup->setVisible(false); - return; - } - - std::string amiibo_series{}; - std::string amiibo_name{}; - std::string amiibo_image_url{}; - std::string amiibo_type{}; - - const auto parsed_amiibo_json_json = nlohmann::json::parse(amiibo_json).at("amiibo"); - parsed_amiibo_json_json.at("amiiboSeries").get_to(amiibo_series); - parsed_amiibo_json_json.at("name").get_to(amiibo_name); - parsed_amiibo_json_json.at("image").get_to(amiibo_image_url); - parsed_amiibo_json_json.at("type").get_to(amiibo_type); - - ui->amiiboSeriesValue->setText(QString::fromStdString(amiibo_series)); - ui->amiiboNameValue->setText(QString::fromStdString(amiibo_name)); - ui->amiiboTypeValue->setText(QString::fromStdString(amiibo_type)); - - if (amiibo_image_url.size() < 34) { - ui->amiiboImageLabel->setVisible(false); - } - - const auto image_url_path = amiibo_image_url.substr(34, amiibo_image_url.size() - 34); - const auto image_data = image_client.GetImage(image_url_path, true).returned_data; - - if (image_data.empty()) { - ui->amiiboImageLabel->setVisible(false); - } - - QPixmap pixmap; - pixmap.loadFromData(reinterpret_cast(image_data.data()), - static_cast(image_data.size())); - pixmap = pixmap.scaled(250, 350, Qt::AspectRatioMode::KeepAspectRatio, - Qt::TransformationMode::SmoothTransformation); - ui->amiiboImageLabel->setPixmap(pixmap); -} - -void QtAmiiboManagerDialog::LoadAmiiboData() { - Service::NFP::RegisterInfo register_info{}; - Service::NFP::CommonInfo common_info{}; - const auto register_result = nfp_device->GetRegisterInfo(register_info); - const auto common_result = nfp_device->GetCommonInfo(common_info); - - if (register_result.IsFailure()) { - ui->creationDateValue->setDisabled(true); - ui->modificationDateValue->setDisabled(true); - ui->amiiboCustomNameValue->setReadOnly(false); - ui->amiiboOwnerValue->setReadOnly(false); - return; - } - - if (parameters.mode == Service::NFP::CabinetMode::StartNicknameAndOwnerSettings) { - ui->creationDateValue->setDisabled(true); - ui->modificationDateValue->setDisabled(true); - } - - const auto amiibo_name = std::string(register_info.amiibo_name.data()); - const auto owner_name = Common::UTF16ToUTF8(register_info.mii_char_info.name.data()); - const auto creation_date = - QDate(register_info.creation_date.year, register_info.creation_date.month, - register_info.creation_date.day); - - ui->amiiboCustomNameValue->setText(QString::fromStdString(amiibo_name)); - ui->amiiboOwnerValue->setText(QString::fromStdString(owner_name)); - ui->amiiboCustomNameValue->setReadOnly(true); - ui->amiiboOwnerValue->setReadOnly(true); - ui->creationDateValue->setDate(creation_date); - - if (common_result.IsFailure()) { - ui->modificationDateValue->setDisabled(true); - return; - } - - const auto modification_date = - QDate(common_info.last_write_date.year, common_info.last_write_date.month, - common_info.last_write_date.day); - ui->modificationDateValue->setDate(modification_date); -} - -void QtAmiiboManagerDialog::LoadAmiiboGameInfo() { - u32 application_area_id{}; - const auto application_result = nfp_device->GetApplicationAreaId(application_area_id); - - if (application_result.IsFailure()) { - ui->gameIdValue->setVisible(false); - ui->gameIdLabel->setText(tr("No game data present")); - return; - } - - SetGameDataName(application_area_id); -} - -void QtAmiiboManagerDialog::SetGameDataName(u32 application_area_id) { - const std::array, 12> game_name_list = { - // 3ds, wii u - std::pair{0x10110E00, QStringLiteral("Super Smash Bros (3DS/WiiU)")}, - {0x00132600, QStringLiteral("Mario & Luigi: Paper Jam")}, - {0x0014F000, QStringLiteral("Animal Crossing: Happy Home Designer")}, - {0x00152600, QStringLiteral("Chibi-Robo!: Zip Lash")}, - {0x10161f00, QStringLiteral("Mario Party 10")}, - {0x1019C800, QStringLiteral("The Legend of Zelda: Twilight Princess HD")}, - // switch - {0x10162B00, QStringLiteral("Splatoon 2")}, - {0x1016e100, QStringLiteral("Shovel Knight: Treasure Trove")}, - {0x1019C800, QStringLiteral("The Legend of Zelda: Breath of the Wild")}, - {0x34F80200, QStringLiteral("Super Smash Bros. Ultimate")}, - {0x38600500, QStringLiteral("Splatoon 3")}, - {0x3B440400, QStringLiteral("The Legend of Zelda: Link's Awakening")}, - }; - - for (const auto& [game_id, game_name] : game_name_list) { - if (application_area_id == game_id) { - ui->gameIdValue->setText(game_name); - return; - } - } - - const auto application_area_string = fmt::format("{:016x}", application_area_id); - ui->gameIdValue->setText(QString::fromStdString(application_area_string)); -} - -void QtAmiiboManagerDialog::SetManagerDescription() { - switch (parameters.mode) { - case Service::NFP::CabinetMode::StartFormatter: - ui->cabinetActionDescriptionLabel->setText( - tr("The following amiibo data will be formated:")); - break; - case Service::NFP::CabinetMode::StartGameDataEraser: - ui->cabinetActionDescriptionLabel->setText(tr("The following game data will removed:")); - break; - case Service::NFP::CabinetMode::StartNicknameAndOwnerSettings: - ui->cabinetActionDescriptionLabel->setText(tr("Set nickname and owner:")); - break; - case Service::NFP::CabinetMode::StartRestorer: - ui->cabinetActionDescriptionLabel->setText(tr("Do you wish to restore this amiibo:")); - break; - } -} - -QtAmiiboManager::QtAmiiboManager(GMainWindow& parent) { - connect(this, &QtAmiiboManager::MainWindowShowAmiiboManager, &parent, - &GMainWindow::AmiiboManagerShowDialog, Qt::QueuedConnection); - connect(&parent, &GMainWindow::AmiiboManagerFinished, this, - &QtAmiiboManager::MainWindowFinished, Qt::QueuedConnection); -} - -QtAmiiboManager::~QtAmiiboManager() = default; - -void QtAmiiboManager::ShowCabinetApplet(std::function callback_, - const Core::Frontend::CabinetParameters& parameters, - std::shared_ptr nfp_device) const { - callback = std::move(callback_); - emit MainWindowShowAmiiboManager(parameters, nfp_device); -} - -void QtAmiiboManager::MainWindowFinished(bool is_success, std::string name) { - callback(is_success, name); -} diff --git a/src/yuzu/applets/qt_amiibo_manager.h b/src/yuzu/applets/qt_amiibo_manager.h deleted file mode 100644 index 3f5866ed7..000000000 --- a/src/yuzu/applets/qt_amiibo_manager.h +++ /dev/null @@ -1,93 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#pragma once - -#include -#include -#include -#include "core/frontend/applets/cabinet.h" - -class GMainWindow; -class QCheckBox; -class QComboBox; -class QDialogButtonBox; -class QGroupBox; -class QLabel; - -class InputProfiles; - -namespace InputCommon { -class InputSubsystem; -} - -namespace Ui { -class QtAmiiboManagerDialog; -} - -namespace Core { -class System; -} - -namespace Core::HID { -class HIDCore; -enum class NpadStyleIndex : u8; -} // namespace Core::HID - -namespace Service::NFP { -class NfpDevice; -} // namespace Service::NFP - -class QtAmiiboManagerDialog final : public QDialog { - Q_OBJECT - -public: - explicit QtAmiiboManagerDialog(QWidget* parent, Core::Frontend::CabinetParameters parameters_, - InputCommon::InputSubsystem* input_subsystem_, - std::shared_ptr nfp_device_); - ~QtAmiiboManagerDialog() override; - - int exec() override; - - std::string GetName(); - -private: - void LoadInfo(); - void LoadAmiiboApiInfo(std::string amiibo_id); - void LoadAmiiboData(); - void LoadAmiiboGameInfo(); - void SetGameDataName(u32 application_area_id); - void SetManagerDescription(); - - std::unique_ptr ui; - - InputCommon::InputSubsystem* input_subsystem; - std::shared_ptr nfp_device; - - // Parameters sent in from the backend HLE applet. - Core::Frontend::CabinetParameters parameters; - - // If false amiibo manager failed to load - bool is_initalized{}; -}; - -class QtAmiiboManager final : public QObject, public Core::Frontend::CabinetApplet { - Q_OBJECT - -public: - explicit QtAmiiboManager(GMainWindow& parent); - ~QtAmiiboManager() override; - - void ShowCabinetApplet(std::function callback_, - const Core::Frontend::CabinetParameters& parameters, - std::shared_ptr nfp_device) const override; - -signals: - void MainWindowShowAmiiboManager(const Core::Frontend::CabinetParameters& parameters, - std::shared_ptr nfp_device) const; - -private: - void MainWindowFinished(bool is_success, std::string name); - - mutable std::function callback; -}; diff --git a/src/yuzu/applets/qt_amiibo_manager.ui b/src/yuzu/applets/qt_amiibo_manager.ui deleted file mode 100644 index eb6eabe59..000000000 --- a/src/yuzu/applets/qt_amiibo_manager.ui +++ /dev/null @@ -1,491 +0,0 @@ - - - QtAmiiboManagerDialog - - - - 0 - 0 - 839 - 500 - - - - Amiibo Manager - - - - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 10 - - - 20 - - - 15 - - - 0 - - - 15 - - - - - - 12 - 75 - true - - - - - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - false - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - 20 - - - 15 - - - - - - 250 - 350 - - - - - 236 - 350 - - - - - - - Qt::AlignCenter - - - - - - - 20 - - - 8 - - - 15 - - - - - Amiibo Info - - - - - - - - Series - - - - - - - - 0 - 0 - - - - true - - - - - - - Type - - - - - - - - 0 - 0 - - - - true - - - - - - - Name - - - - - - - - 0 - 0 - - - - true - - - - - - - - - - - - Amiibo Data - - - - - - - - Custom Name - - - - - - - - 0 - 0 - - - - 10 - - - - - - - Owner - - - - - - - - 0 - 0 - - - - 10 - - - - - - - Creation Date - - - - - - - true - - - - 1970 - 1 - 1 - - - - dd/MM/yyyy - - - - - - - Modification Date - - - - - - - true - - - - 1970 - 1 - 1 - - - - dd/MM/yyyy - - - - - - - - - - - - - 500 - 0 - - - - Game Data - - - - - - Game Id - - - - - - - - 0 - 0 - - - - true - - - - - - - - - - - 500 - 0 - - - - Mount Amiibo - - - - - - ... - - - - - - - Qt::Horizontal - - - QSizePolicy::Maximum - - - - 60 - 20 - - - - - - - - File Path - - - - - - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - - - - - - - 15 - - - 15 - - - 8 - - - 20 - - - 8 - - - - - true - - - QDialogButtonBox::Cancel|QDialogButtonBox::Ok - - - - - - - - - - - - - - - buttonBox - accepted() - QtAmiiboManagerDialog - accept() - - - buttonBox - rejected() - QtAmiiboManagerDialog - reject() - - - diff --git a/src/yuzu/applets/qt_amiibo_settings.cpp b/src/yuzu/applets/qt_amiibo_settings.cpp new file mode 100644 index 000000000..efb7f6ecc --- /dev/null +++ b/src/yuzu/applets/qt_amiibo_settings.cpp @@ -0,0 +1,260 @@ +// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include +#include +#include +#include + +#include "common/assert.h" +#include "common/string_util.h" +#include "core/hle/service/nfp/nfp_device.h" +#include "core/hle/service/nfp/nfp_result.h" +#include "input_common/drivers/virtual_amiibo.h" +#include "input_common/main.h" +#include "ui_qt_amiibo_settings.h" +#include "web_service/web_backend.h" +#include "yuzu/applets/qt_amiibo_settings.h" +#include "yuzu/main.h" + +QtAmiiboSettingsDialog::QtAmiiboSettingsDialog(QWidget* parent, + Core::Frontend::CabinetParameters parameters_, + InputCommon::InputSubsystem* input_subsystem_, + std::shared_ptr nfp_device_) + : QDialog(parent), ui(std::make_unique()), + input_subsystem{input_subsystem_}, nfp_device{std::move(nfp_device_)}, + parameters(std::move(parameters_)) { + ui->setupUi(this); + + LoadInfo(); + + resize(0, 0); +} + +QtAmiiboSettingsDialog::~QtAmiiboSettingsDialog() = default; + +int QtAmiiboSettingsDialog::exec() { + if (!is_initalized) { + return QDialog::Rejected; + } + return QDialog::exec(); +} + +std::string QtAmiiboSettingsDialog::GetName() const { + return ui->amiiboCustomNameValue->text().toStdString(); +} + +void QtAmiiboSettingsDialog::LoadInfo() { + if (input_subsystem->GetVirtualAmiibo()->ReloadAmiibo() != + InputCommon::VirtualAmiibo::Info::Success) { + return; + } + + if (nfp_device->GetCurrentState() != Service::NFP::DeviceState::TagFound && + nfp_device->GetCurrentState() != Service::NFP::DeviceState::TagMounted) { + return; + } + nfp_device->Mount(Service::NFP::MountTarget::All); + + LoadAmiiboInfo(); + LoadAmiiboData(); + LoadAmiiboGameInfo(); + + ui->amiiboDirectoryValue->setText( + QString::fromStdString(input_subsystem->GetVirtualAmiibo()->GetLastFilePath())); + + SetSettingsDescription(); + is_initalized = true; +} + +void QtAmiiboSettingsDialog::LoadAmiiboInfo() { + Service::NFP::ModelInfo model_info{}; + const auto model_result = nfp_device->GetModelInfo(model_info); + + if (model_result.IsFailure()) { + ui->amiiboImageLabel->setVisible(false); + ui->amiiboInfoGroup->setVisible(false); + return; + } + + const auto amiibo_id = + fmt::format("{:04x}{:02x}{:02x}{:04x}{:02x}02", Common::swap16(model_info.character_id), + model_info.character_variant, model_info.amiibo_type, model_info.model_number, + model_info.series); + + LOG_DEBUG(Frontend, "Loading amiibo id {}", amiibo_id); + // Note: This function is not being used until we host the images on our server + // LoadAmiiboApiInfo(amiibo_id); + ui->amiiboImageLabel->setVisible(false); + ui->amiiboInfoGroup->setVisible(false); +} + +void QtAmiiboSettingsDialog::LoadAmiiboApiInfo(std::string_view amiibo_id) { + // TODO: Host this data on our website + WebService::Client client{"https://amiiboapi.com", {}, {}}; + WebService::Client image_client{"https://raw.githubusercontent.com", {}, {}}; + const auto url_path = fmt::format("/api/amiibo/?id={}", amiibo_id); + + const auto amiibo_json = client.GetJson(url_path, true).returned_data; + if (amiibo_json.empty()) { + ui->amiiboImageLabel->setVisible(false); + ui->amiiboInfoGroup->setVisible(false); + return; + } + + std::string amiibo_series{}; + std::string amiibo_name{}; + std::string amiibo_image_url{}; + std::string amiibo_type{}; + + const auto parsed_amiibo_json_json = nlohmann::json::parse(amiibo_json).at("amiibo"); + parsed_amiibo_json_json.at("amiiboSeries").get_to(amiibo_series); + parsed_amiibo_json_json.at("name").get_to(amiibo_name); + parsed_amiibo_json_json.at("image").get_to(amiibo_image_url); + parsed_amiibo_json_json.at("type").get_to(amiibo_type); + + ui->amiiboSeriesValue->setText(QString::fromStdString(amiibo_series)); + ui->amiiboNameValue->setText(QString::fromStdString(amiibo_name)); + ui->amiiboTypeValue->setText(QString::fromStdString(amiibo_type)); + + if (amiibo_image_url.size() < 34) { + ui->amiiboImageLabel->setVisible(false); + } + + const auto image_url_path = amiibo_image_url.substr(34, amiibo_image_url.size() - 34); + const auto image_data = image_client.GetImage(image_url_path, true).returned_data; + + if (image_data.empty()) { + ui->amiiboImageLabel->setVisible(false); + } + + QPixmap pixmap; + pixmap.loadFromData(reinterpret_cast(image_data.data()), + static_cast(image_data.size())); + pixmap = pixmap.scaled(250, 350, Qt::AspectRatioMode::KeepAspectRatio, + Qt::TransformationMode::SmoothTransformation); + ui->amiiboImageLabel->setPixmap(pixmap); +} + +void QtAmiiboSettingsDialog::LoadAmiiboData() { + Service::NFP::RegisterInfo register_info{}; + Service::NFP::CommonInfo common_info{}; + const auto register_result = nfp_device->GetRegisterInfo(register_info); + const auto common_result = nfp_device->GetCommonInfo(common_info); + + if (register_result.IsFailure()) { + ui->creationDateValue->setDisabled(true); + ui->modificationDateValue->setDisabled(true); + ui->amiiboCustomNameValue->setReadOnly(false); + ui->amiiboOwnerValue->setReadOnly(false); + return; + } + + if (parameters.mode == Service::NFP::CabinetMode::StartNicknameAndOwnerSettings) { + ui->creationDateValue->setDisabled(true); + ui->modificationDateValue->setDisabled(true); + } + + const auto amiibo_name = std::string(register_info.amiibo_name.data()); + const auto owner_name = Common::UTF16ToUTF8(register_info.mii_char_info.name.data()); + const auto creation_date = + QDate(register_info.creation_date.year, register_info.creation_date.month, + register_info.creation_date.day); + + ui->amiiboCustomNameValue->setText(QString::fromStdString(amiibo_name)); + ui->amiiboOwnerValue->setText(QString::fromStdString(owner_name)); + ui->amiiboCustomNameValue->setReadOnly(true); + ui->amiiboOwnerValue->setReadOnly(true); + ui->creationDateValue->setDate(creation_date); + + if (common_result.IsFailure()) { + ui->modificationDateValue->setDisabled(true); + return; + } + + const auto modification_date = + QDate(common_info.last_write_date.year, common_info.last_write_date.month, + common_info.last_write_date.day); + ui->modificationDateValue->setDate(modification_date); +} + +void QtAmiiboSettingsDialog::LoadAmiiboGameInfo() { + u32 application_area_id{}; + const auto application_result = nfp_device->GetApplicationAreaId(application_area_id); + + if (application_result.IsFailure()) { + ui->gameIdValue->setVisible(false); + ui->gameIdLabel->setText(tr("No game data present")); + return; + } + + SetGameDataName(application_area_id); +} + +void QtAmiiboSettingsDialog::SetGameDataName(u32 application_area_id) { + static constexpr std::array, 12> game_name_list = { + // 3ds, wii u + std::pair{0x10110E00, "Super Smash Bros (3DS/WiiU)"}, + {0x00132600, "Mario & Luigi: Paper Jam"}, + {0x0014F000, "Animal Crossing: Happy Home Designer"}, + {0x00152600, "Chibi-Robo!: Zip Lash"}, + {0x10161f00, "Mario Party 10"}, + {0x1019C800, "The Legend of Zelda: Twilight Princess HD"}, + // switch + {0x10162B00, "Splatoon 2"}, + {0x1016e100, "Shovel Knight: Treasure Trove"}, + {0x1019C800, "The Legend of Zelda: Breath of the Wild"}, + {0x34F80200, "Super Smash Bros. Ultimate"}, + {0x38600500, "Splatoon 3"}, + {0x3B440400, "The Legend of Zelda: Link's Awakening"}, + }; + + for (const auto& [game_id, game_name] : game_name_list) { + if (application_area_id == game_id) { + ui->gameIdValue->setText(QString::fromStdString(game_name)); + return; + } + } + + const auto application_area_string = fmt::format("{:016x}", application_area_id); + ui->gameIdValue->setText(QString::fromStdString(application_area_string)); +} + +void QtAmiiboSettingsDialog::SetSettingsDescription() { + switch (parameters.mode) { + case Service::NFP::CabinetMode::StartFormatter: + ui->cabinetActionDescriptionLabel->setText( + tr("The following amiibo data will be formatted:")); + break; + case Service::NFP::CabinetMode::StartGameDataEraser: + ui->cabinetActionDescriptionLabel->setText(tr("The following game data will removed:")); + break; + case Service::NFP::CabinetMode::StartNicknameAndOwnerSettings: + ui->cabinetActionDescriptionLabel->setText(tr("Set nickname and owner:")); + break; + case Service::NFP::CabinetMode::StartRestorer: + ui->cabinetActionDescriptionLabel->setText(tr("Do you wish to restore this amiibo?")); + break; + } +} + +QtAmiiboSettings::QtAmiiboSettings(GMainWindow& parent) { + connect(this, &QtAmiiboSettings::MainWindowShowAmiiboSettings, &parent, + &GMainWindow::AmiiboSettingsShowDialog, Qt::QueuedConnection); + connect(&parent, &GMainWindow::AmiiboSettingsFinished, this, + &QtAmiiboSettings::MainWindowFinished, Qt::QueuedConnection); +} + +QtAmiiboSettings::~QtAmiiboSettings() = default; + +void QtAmiiboSettings::ShowCabinetApplet( + const Core::Frontend::CabinetCallback& callback_, + const Core::Frontend::CabinetParameters& parameters, + std::shared_ptr nfp_device) const { + callback = std::move(callback_); + emit MainWindowShowAmiiboSettings(parameters, nfp_device); +} + +void QtAmiiboSettings::MainWindowFinished(bool is_success, const std::string& name) { + callback(is_success, name); +} diff --git a/src/yuzu/applets/qt_amiibo_settings.h b/src/yuzu/applets/qt_amiibo_settings.h new file mode 100644 index 000000000..930c96739 --- /dev/null +++ b/src/yuzu/applets/qt_amiibo_settings.h @@ -0,0 +1,83 @@ +// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include +#include +#include +#include "core/frontend/applets/cabinet.h" + +class GMainWindow; +class QCheckBox; +class QComboBox; +class QDialogButtonBox; +class QGroupBox; +class QLabel; + +namespace InputCommon { +class InputSubsystem; +} + +namespace Ui { +class QtAmiiboSettingsDialog; +} + +namespace Service::NFP { +class NfpDevice; +} // namespace Service::NFP + +class QtAmiiboSettingsDialog final : public QDialog { + Q_OBJECT + +public: + explicit QtAmiiboSettingsDialog(QWidget* parent, Core::Frontend::CabinetParameters parameters_, + InputCommon::InputSubsystem* input_subsystem_, + std::shared_ptr nfp_device_); + ~QtAmiiboSettingsDialog() override; + + int exec() override; + + std::string GetName() const; + +private: + void LoadInfo(); + void LoadAmiiboInfo(); + void LoadAmiiboApiInfo(std::string_view amiibo_id); + void LoadAmiiboData(); + void LoadAmiiboGameInfo(); + void SetGameDataName(u32 application_area_id); + void SetSettingsDescription(); + + std::unique_ptr ui; + + InputCommon::InputSubsystem* input_subsystem; + std::shared_ptr nfp_device; + + // Parameters sent in from the backend HLE applet. + Core::Frontend::CabinetParameters parameters; + + // If false amiibo settings failed to load + bool is_initalized{}; +}; + +class QtAmiiboSettings final : public QObject, public Core::Frontend::CabinetApplet { + Q_OBJECT + +public: + explicit QtAmiiboSettings(GMainWindow& parent); + ~QtAmiiboSettings() override; + + void ShowCabinetApplet(const Core::Frontend::CabinetCallback& callback_, + const Core::Frontend::CabinetParameters& parameters, + std::shared_ptr nfp_device) const override; + +signals: + void MainWindowShowAmiiboSettings(const Core::Frontend::CabinetParameters& parameters, + std::shared_ptr nfp_device) const; + +private: + void MainWindowFinished(bool is_success, const std::string& name); + + mutable Core::Frontend::CabinetCallback callback; +}; diff --git a/src/yuzu/applets/qt_amiibo_settings.ui b/src/yuzu/applets/qt_amiibo_settings.ui new file mode 100644 index 000000000..f377a6e61 --- /dev/null +++ b/src/yuzu/applets/qt_amiibo_settings.ui @@ -0,0 +1,494 @@ + + + QtAmiiboSettingsDialog + + + + 0 + 0 + 839 + 500 + + + + Amiibo Settings + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 10 + + + 20 + + + 15 + + + 0 + + + 15 + + + + + + 12 + 75 + true + + + + + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + false + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + 20 + + + 15 + + + 15 + + + + + + 250 + 350 + + + + + 236 + 350 + + + + + + + Qt::AlignCenter + + + + + + + 0 + + + 8 + + + 15 + + + + + Amiibo Info + + + + + + + + Series + + + + + + + + 0 + 0 + + + + true + + + + + + + Type + + + + + + + + 0 + 0 + + + + true + + + + + + + Name + + + + + + + + 0 + 0 + + + + true + + + + + + + + + + + + Amiibo Data + + + + + + + + Custom Name + + + + + + + + 0 + 0 + + + + 10 + + + + + + + Owner + + + + + + + + 0 + 0 + + + + 10 + + + + + + + Creation Date + + + + + + + true + + + + 1970 + 1 + 1 + + + + dd/MM/yyyy + + + + + + + Modification Date + + + + + + + true + + + + 1970 + 1 + 1 + + + + dd/MM/yyyy + + + + + + + + + + + + + 500 + 0 + + + + Game Data + + + + + + Game Id + + + + + + + + 0 + 0 + + + + true + + + + + + + + + + + 500 + 0 + + + + Mount Amiibo + + + + + + ... + + + + + + + Qt::Horizontal + + + QSizePolicy::Maximum + + + + 60 + 20 + + + + + + + + File Path + + + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + + + + + 15 + + + 15 + + + 8 + + + 20 + + + 8 + + + + + true + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + + + + + + + buttonBox + accepted() + QtAmiiboSettingsDialog + accept() + + + buttonBox + rejected() + QtAmiiboSettingsDialog + reject() + + + diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index 27266cae3..33f9237e2 100644 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp @@ -15,7 +15,7 @@ #endif // VFS includes must be before glad as they will conflict with Windows file api, which uses defines. -#include "applets/qt_amiibo_manager.h" +#include "applets/qt_amiibo_settings.h" #include "applets/qt_controller.h" #include "applets/qt_error.h" #include "applets/qt_profile_select.h" @@ -577,19 +577,19 @@ void GMainWindow::RegisterMetaTypes() { qRegisterMetaType("Core::SystemResultStatus"); } -void GMainWindow::AmiiboManagerShowDialog(const Core::Frontend::CabinetParameters& parameters, - std::shared_ptr nfp_device) { - QtAmiiboManagerDialog dialog(this, parameters, input_subsystem.get(), nfp_device); +void GMainWindow::AmiiboSettingsShowDialog(const Core::Frontend::CabinetParameters& parameters, + std::shared_ptr nfp_device) { + QtAmiiboSettingsDialog dialog(this, parameters, input_subsystem.get(), nfp_device); dialog.setWindowFlags(Qt::Dialog | Qt::CustomizeWindowHint | Qt::WindowStaysOnTopHint | Qt::WindowTitleHint | Qt::WindowSystemMenuHint); dialog.setWindowModality(Qt::WindowModal); if (dialog.exec() == QDialog::Rejected) { - emit AmiiboManagerFinished(false, {}); + emit AmiiboSettingsFinished(false, {}); return; } - emit AmiiboManagerFinished(true, dialog.GetName()); + emit AmiiboSettingsFinished(true, dialog.GetName()); } void GMainWindow::ControllerSelectorReconfigureControllers( @@ -1569,7 +1569,7 @@ bool GMainWindow::LoadROM(const QString& filename, u64 program_id, std::size_t p system->SetFilesystem(vfs); system->SetAppletFrontendSet({ - std::make_unique(*this), // Amiibo Manager + std::make_unique(*this), // Amiibo Settings std::make_unique(*this), // Controller Selector std::make_unique(*this), // Error Display nullptr, // Mii Editor diff --git a/src/yuzu/main.h b/src/yuzu/main.h index 2724ecd52..6a9992d05 100644 --- a/src/yuzu/main.h +++ b/src/yuzu/main.h @@ -154,7 +154,7 @@ signals: void UpdateInstallProgress(); - void AmiiboManagerFinished(bool is_success, std::string name); + void AmiiboSettingsFinished(bool is_success, const std::string& name); void ControllerSelectorReconfigureFinished(); @@ -177,8 +177,8 @@ public slots: void OnExecuteProgram(std::size_t program_index); void OnExit(); void OnSaveConfig(); - void AmiiboManagerShowDialog(const Core::Frontend::CabinetParameters& parameters, - std::shared_ptr nfp_device); + void AmiiboSettingsShowDialog(const Core::Frontend::CabinetParameters& parameters, + std::shared_ptr nfp_device); void ControllerSelectorReconfigureControllers( const Core::Frontend::ControllerParameters& parameters); void SoftwareKeyboardInitialize( -- cgit v1.2.3 From 6fa3faec658893c9fae19116232d24dac08babc7 Mon Sep 17 00:00:00 2001 From: Kyle Kienapfel Date: Fri, 11 Nov 2022 04:12:37 -0800 Subject: Add break for default cases Visual Studio has an option to search all files in a solution, so I did a search in there for "default:" looking for any missing break statements. I've left out default statements that return something, and that throw something, even if via ThrowInvalidType. UNREACHABLE leads towards throw R_THROW macro leads towards a return --- src/audio_core/renderer/performance/performance_manager.cpp | 1 + src/common/atomic_helpers.h | 1 + src/core/hle/kernel/init/init_slab_setup.cpp | 1 + src/core/hle/kernel/k_page_table.cpp | 3 +++ src/core/hle/kernel/k_process.cpp | 1 + src/core/hle/service/am/applets/applet_error.cpp | 1 + src/core/hle/service/am/applets/applet_general_backend.cpp | 2 ++ src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp | 5 ++--- src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp | 5 ++--- src/core/hle/service/service.cpp | 1 + src/core/hle/service/time/time_zone_manager.cpp | 1 + src/video_core/engines/maxwell_dma.cpp | 1 + src/video_core/engines/puller.cpp | 4 ++++ src/video_core/macro/macro_interpreter.cpp | 2 ++ src/video_core/macro/macro_jit_x64.cpp | 1 + src/video_core/renderer_opengl/gl_texture_cache.cpp | 2 ++ src/video_core/renderer_opengl/renderer_opengl.cpp | 1 + src/video_core/renderer_vulkan/vk_scheduler.cpp | 1 + src/video_core/renderer_vulkan/vk_texture_cache.cpp | 1 + src/video_core/textures/decoders.cpp | 3 +++ src/yuzu/compatdb.cpp | 1 + src/yuzu/main.cpp | 3 +++ src/yuzu_cmd/emu_window/emu_window_sdl2_vk.cpp | 1 + src/yuzu_cmd/yuzu.cpp | 1 + 24 files changed, 38 insertions(+), 6 deletions(-) (limited to 'src/core/hle') diff --git a/src/audio_core/renderer/performance/performance_manager.cpp b/src/audio_core/renderer/performance/performance_manager.cpp index fd5873e1e..8aa0f5ed0 100644 --- a/src/audio_core/renderer/performance/performance_manager.cpp +++ b/src/audio_core/renderer/performance/performance_manager.cpp @@ -26,6 +26,7 @@ void PerformanceManager::CreateImpl(const size_t version) { impl = std::make_unique< PerformanceManagerImpl>(); + break; } } diff --git a/src/common/atomic_helpers.h b/src/common/atomic_helpers.h index bef5015c1..aef3b66a4 100644 --- a/src/common/atomic_helpers.h +++ b/src/common/atomic_helpers.h @@ -156,6 +156,7 @@ AE_FORCEINLINE void compiler_fence(memory_order order) AE_NO_TSAN { break; default: assert(false); + break; } } diff --git a/src/core/hle/kernel/init/init_slab_setup.cpp b/src/core/hle/kernel/init/init_slab_setup.cpp index bda098511..7b363eb1e 100644 --- a/src/core/hle/kernel/init/init_slab_setup.cpp +++ b/src/core/hle/kernel/init/init_slab_setup.cpp @@ -243,6 +243,7 @@ void InitializeSlabHeaps(Core::System& system, KMemoryLayout& memory_layout) { // If we somehow get an invalid type, abort. default: ASSERT_MSG(false, "Unknown slab type: {}", slab_types[i]); + break; } // If we've hit the end of a gap, free it. diff --git a/src/core/hle/kernel/k_page_table.cpp b/src/core/hle/kernel/k_page_table.cpp index 5387bf5fe..612fc76fa 100644 --- a/src/core/hle/kernel/k_page_table.cpp +++ b/src/core/hle/kernel/k_page_table.cpp @@ -2301,6 +2301,7 @@ Result KPageTable::SetProcessMemoryPermission(VAddr addr, size_t size, break; default: ASSERT(false); + break; } } @@ -2803,6 +2804,7 @@ Result KPageTable::Operate(VAddr addr, size_t num_pages, const KPageGroup& page_ break; default: ASSERT(false); + break; } addr += size; @@ -2838,6 +2840,7 @@ Result KPageTable::Operate(VAddr addr, size_t num_pages, KMemoryPermission perm, break; default: ASSERT(false); + break; } R_SUCCEED(); } diff --git a/src/core/hle/kernel/k_process.cpp b/src/core/hle/kernel/k_process.cpp index 55a9c5fae..d1dc62401 100644 --- a/src/core/hle/kernel/k_process.cpp +++ b/src/core/hle/kernel/k_process.cpp @@ -395,6 +395,7 @@ Result KProcess::LoadFromMetadata(const FileSys::ProgramMetadata& metadata, std: default: ASSERT(false); + break; } // Create TLS region diff --git a/src/core/hle/service/am/applets/applet_error.cpp b/src/core/hle/service/am/applets/applet_error.cpp index fcf34bf7e..bae0d99a6 100644 --- a/src/core/hle/service/am/applets/applet_error.cpp +++ b/src/core/hle/service/am/applets/applet_error.cpp @@ -144,6 +144,7 @@ void Error::Initialize() { break; default: UNIMPLEMENTED_MSG("Unimplemented LibAppletError mode={:02X}!", mode); + break; } } 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 c34ef08b3..e50acdaf6 100644 --- a/src/core/hle/service/am/applets/applet_general_backend.cpp +++ b/src/core/hle/service/am/applets/applet_general_backend.cpp @@ -129,6 +129,7 @@ void Auth::Execute() { } default: unimplemented_log(); + break; } } @@ -192,6 +193,7 @@ void PhotoViewer::Execute() { break; default: UNIMPLEMENTED_MSG("Unimplemented PhotoViewer applet mode={:02X}!", mode); + break; } } diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp b/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp index ced57dfe6..b97813fbc 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp @@ -300,11 +300,10 @@ Kernel::KEvent* nvhost_ctrl_gpu::QueryEvent(u32 event_id) { return error_notifier_event; case 2: return unknown_event; - default: { + default: LOG_CRITICAL(Service_NVDRV, "Unknown Ctrl GPU Event {}", event_id); + return nullptr; } - } - return nullptr; } } // namespace Service::Nvidia::Devices diff --git a/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp b/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp index 45a759fa8..e123564c6 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp @@ -364,11 +364,10 @@ Kernel::KEvent* nvhost_gpu::QueryEvent(u32 event_id) { return sm_exception_breakpoint_pause_report_event; case 3: return error_notifier_event; - default: { + default: LOG_CRITICAL(Service_NVDRV, "Unknown Ctrl GPU Event {}", event_id); + return nullptr; } - } - return nullptr; } } // namespace Service::Nvidia::Devices diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp index 5ab41c0c4..0de67f1e1 100644 --- a/src/core/hle/service/service.cpp +++ b/src/core/hle/service/service.cpp @@ -228,6 +228,7 @@ Result ServiceFrameworkBase::HandleSyncRequest(Kernel::KServerSession& session, } UNIMPLEMENTED_MSG("command_type={}", ctx.GetCommandType()); + break; } // If emulation was shutdown, we are closing service threads, do not write the response back to diff --git a/src/core/hle/service/time/time_zone_manager.cpp b/src/core/hle/service/time/time_zone_manager.cpp index 2aa675df9..f9ada7c93 100644 --- a/src/core/hle/service/time/time_zone_manager.cpp +++ b/src/core/hle/service/time/time_zone_manager.cpp @@ -280,6 +280,7 @@ static constexpr int TransitionTime(int year, Rule rule, int offset) { } default: ASSERT(false); + break; } return value + rule.transition_time + offset; } diff --git a/src/video_core/engines/maxwell_dma.cpp b/src/video_core/engines/maxwell_dma.cpp index 4eb7a100d..27be4af87 100644 --- a/src/video_core/engines/maxwell_dma.cpp +++ b/src/video_core/engines/maxwell_dma.cpp @@ -311,6 +311,7 @@ void MaxwellDMA::ReleaseSemaphore() { } default: ASSERT_MSG(false, "Unknown semaphore type: {}", static_cast(type.Value())); + break; } } diff --git a/src/video_core/engines/puller.cpp b/src/video_core/engines/puller.cpp index 3977bb0fb..4d2278811 100644 --- a/src/video_core/engines/puller.cpp +++ b/src/video_core/engines/puller.cpp @@ -50,6 +50,7 @@ void Puller::ProcessBindMethod(const MethodCall& method_call) { break; default: UNIMPLEMENTED_MSG("Unimplemented engine {:04X}", engine_id); + break; } } @@ -65,6 +66,7 @@ void Puller::ProcessFenceActionMethod() { break; default: UNIMPLEMENTED_MSG("Unimplemented operation {}", regs.fence_action.op.Value()); + break; } } @@ -228,6 +230,7 @@ void Puller::CallEngineMethod(const MethodCall& method_call) { break; default: UNIMPLEMENTED_MSG("Unimplemented engine"); + break; } } @@ -254,6 +257,7 @@ void Puller::CallEngineMultiMethod(u32 method, u32 subchannel, const u32* base_s break; default: UNIMPLEMENTED_MSG("Unimplemented engine"); + break; } } diff --git a/src/video_core/macro/macro_interpreter.cpp b/src/video_core/macro/macro_interpreter.cpp index c0d32c112..0d63495a9 100644 --- a/src/video_core/macro/macro_interpreter.cpp +++ b/src/video_core/macro/macro_interpreter.cpp @@ -201,6 +201,7 @@ bool MacroInterpreterImpl::Step(bool is_delay_slot) { } default: UNIMPLEMENTED_MSG("Unimplemented macro operation {}", opcode.operation.Value()); + break; } // An instruction with the Exit flag will not actually @@ -297,6 +298,7 @@ void MacroInterpreterImpl::ProcessResult(Macro::ResultOperation operation, u32 r break; default: UNIMPLEMENTED_MSG("Unimplemented result operation {}", operation); + break; } } diff --git a/src/video_core/macro/macro_jit_x64.cpp b/src/video_core/macro/macro_jit_x64.cpp index 25c1ce798..7347cbd88 100644 --- a/src/video_core/macro/macro_jit_x64.cpp +++ b/src/video_core/macro/macro_jit_x64.cpp @@ -652,6 +652,7 @@ void MacroJITx64Impl::Compile_ProcessResult(Macro::ResultOperation operation, u3 break; default: UNIMPLEMENTED_MSG("Unimplemented macro operation {}", operation); + break; } } diff --git a/src/video_core/renderer_opengl/gl_texture_cache.cpp b/src/video_core/renderer_opengl/gl_texture_cache.cpp index 99cd11d1e..9f7ce7414 100644 --- a/src/video_core/renderer_opengl/gl_texture_cache.cpp +++ b/src/video_core/renderer_opengl/gl_texture_cache.cpp @@ -891,6 +891,7 @@ void Image::CopyBufferToImage(const VideoCommon::BufferImageCopy& copy, size_t b break; default: ASSERT(false); + break; } } @@ -927,6 +928,7 @@ void Image::CopyImageToBuffer(const VideoCommon::BufferImageCopy& copy, size_t b break; default: ASSERT(false); + break; } // Compressed formats don't have a pixel format or type const bool is_compressed = gl_format == GL_NONE; diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp index 8bd5eba7e..f29462f7c 100644 --- a/src/video_core/renderer_opengl/renderer_opengl.cpp +++ b/src/video_core/renderer_opengl/renderer_opengl.cpp @@ -340,6 +340,7 @@ void RendererOpenGL::ConfigureFramebufferTexture(TextureInfo& texture, texture.gl_type = GL_UNSIGNED_INT_8_8_8_8_REV; // UNIMPLEMENTED_MSG("Unknown framebuffer pixel format: {}", // static_cast(framebuffer.pixel_format)); + break; } texture.resource.Release(); diff --git a/src/video_core/renderer_vulkan/vk_scheduler.cpp b/src/video_core/renderer_vulkan/vk_scheduler.cpp index 7934f2a51..4a7b633b7 100644 --- a/src/video_core/renderer_vulkan/vk_scheduler.cpp +++ b/src/video_core/renderer_vulkan/vk_scheduler.cpp @@ -221,6 +221,7 @@ void Scheduler::SubmitExecution(VkSemaphore signal_semaphore, VkSemaphore wait_s [[fallthrough]]; default: vk::Check(result); + break; } }); chunk->MarkSubmit(); diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.cpp b/src/video_core/renderer_vulkan/vk_texture_cache.cpp index 853b80d8a..a65bbeb1c 100644 --- a/src/video_core/renderer_vulkan/vk_texture_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_texture_cache.cpp @@ -108,6 +108,7 @@ constexpr VkBorderColor ConvertBorderColor(const std::array& color) { break; default: ASSERT_MSG(false, "Invalid surface type"); + break; } } if (info.storage) { diff --git a/src/video_core/textures/decoders.cpp b/src/video_core/textures/decoders.cpp index fd1a4b987..59120cd09 100644 --- a/src/video_core/textures/decoders.cpp +++ b/src/video_core/textures/decoders.cpp @@ -170,6 +170,7 @@ void Swizzle(std::span output, std::span input, u32 bytes_per_pixe #undef BPP_CASE default: ASSERT_MSG(false, "Invalid bytes_per_pixel={}", bytes_per_pixel); + break; } } @@ -217,6 +218,7 @@ void SwizzleSubrect(std::span output, std::span input, u32 bytes_p #undef BPP_CASE default: ASSERT_MSG(false, "Invalid bytes_per_pixel={}", bytes_per_pixel); + break; } } @@ -240,6 +242,7 @@ void UnswizzleSubrect(std::span output, std::span input, u32 bytes #undef BPP_CASE default: ASSERT_MSG(false, "Invalid bytes_per_pixel={}", bytes_per_pixel); + break; } } diff --git a/src/yuzu/compatdb.cpp b/src/yuzu/compatdb.cpp index f46fff340..e5bc5c448 100644 --- a/src/yuzu/compatdb.cpp +++ b/src/yuzu/compatdb.cpp @@ -63,6 +63,7 @@ void CompatDB::Submit() { break; default: LOG_ERROR(Frontend, "Unexpected page: {}", currentId()); + break; } } diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index 01a002e4f..3c61899aa 100644 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp @@ -1953,6 +1953,7 @@ void GMainWindow::OnGameListOpenFolder(u64 program_id, GameListOpenTarget target } default: UNIMPLEMENTED(); + break; } const QString qpath = QString::fromStdString(Common::FS::PathToUTF8String(path)); @@ -3182,6 +3183,7 @@ void GMainWindow::OnToggleGpuAccuracy() { case Settings::GPUAccuracy::Extreme: default: { Settings::values.gpu_accuracy.SetValue(Settings::GPUAccuracy::High); + break; } } @@ -3514,6 +3516,7 @@ void GMainWindow::UpdateGPUAccuracyButton() { default: { gpu_accuracy_button->setText(tr("GPU ERROR")); gpu_accuracy_button->setChecked(true); + break; } } } diff --git a/src/yuzu_cmd/emu_window/emu_window_sdl2_vk.cpp b/src/yuzu_cmd/emu_window/emu_window_sdl2_vk.cpp index 65455c86e..25948328c 100644 --- a/src/yuzu_cmd/emu_window/emu_window_sdl2_vk.cpp +++ b/src/yuzu_cmd/emu_window/emu_window_sdl2_vk.cpp @@ -84,6 +84,7 @@ EmuWindow_SDL2_VK::EmuWindow_SDL2_VK(InputCommon::InputSubsystem* input_subsyste default: LOG_CRITICAL(Frontend, "Window manager subsystem not implemented"); std::exit(EXIT_FAILURE); + break; } OnResize(); diff --git a/src/yuzu_cmd/yuzu.cpp b/src/yuzu_cmd/yuzu.cpp index e16f79eb4..dfe5a30ea 100644 --- a/src/yuzu_cmd/yuzu.cpp +++ b/src/yuzu_cmd/yuzu.cpp @@ -351,6 +351,7 @@ int main(int argc, char** argv) { "additional help.\n\nError Code: {:04X}-{:04X}\nError Description: {}", loader_id, error_id, static_cast(error_id)); } + break; } system.TelemetrySession().AddField(Common::Telemetry::FieldType::App, "Frontend", "SDL"); -- cgit v1.2.3 From 18fcc03b3ce10997ab1559b4e4887d6267d8486c Mon Sep 17 00:00:00 2001 From: Narr the Reg Date: Mon, 14 Nov 2022 18:10:04 -0600 Subject: core: Update result module --- src/core/hle/result.h | 76 ++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 75 insertions(+), 1 deletion(-) (limited to 'src/core/hle') diff --git a/src/core/hle/result.h b/src/core/hle/result.h index 56c990728..240f06689 100644 --- a/src/core/hle/result.h +++ b/src/core/hle/result.h @@ -28,30 +28,49 @@ enum class ErrorModule : u32 { Loader = 9, CMIF = 10, HIPC = 11, + TMA = 12, + DMNT = 13, + GDS = 14, PM = 15, NS = 16, + BSDSockets = 17, HTC = 18, + TSC = 19, NCMContent = 20, SM = 21, RO = 22, + GC = 23, SDMMC = 24, OVLN = 25, SPL = 26, + Socket = 27, + HTCLOW = 29, + DDSF = 30, + HTCFS = 31, + Async = 32, + Util = 33, + TIPC = 35, + ANIF = 37, ETHC = 100, I2C = 101, GPIO = 102, UART = 103, + CPAD = 104, Settings = 105, + FTM = 106, WLAN = 107, XCD = 108, + TMP451 = 109, NIFM = 110, Hwopus = 111, + LSM6DS3 = 112, Bluetooth = 113, VI = 114, NFP = 115, Time = 116, FGM = 117, OE = 118, + BH1730FVC = 119, PCIe = 120, Friends = 121, BCAT = 122, @@ -65,7 +84,7 @@ enum class ErrorModule : u32 { AHID = 130, Qlaunch = 132, PCV = 133, - OMM = 134, + USBPD = 134, BPC = 135, PSM = 136, NIM = 137, @@ -75,18 +94,22 @@ enum class ErrorModule : u32 { NSD = 141, PCTL = 142, BTM = 143, + LA = 144, ETicket = 145, NGC = 146, ERPT = 147, APM = 148, + CEC = 149, Profiler = 150, ErrorUpload = 151, + LIDBE = 152, Audio = 153, NPNS = 154, NPNSHTTPSTREAM = 155, ARP = 157, SWKBD = 158, BOOT = 159, + NetDiag = 160, NFCMifare = 161, UserlandAssert = 162, Fatal = 163, @@ -94,17 +117,68 @@ enum class ErrorModule : u32 { SPSM = 165, BGTC = 167, UserlandCrash = 168, + SASBUS = 169, + PI = 170, + AudioCtrl = 172, + LBL = 173, + JIT = 175, + HDCP = 176, + OMM = 177, + PDM = 178, + OLSC = 179, SREPO = 180, Dauth = 181, + STDFU = 182, + DBG = 183, + DHCPS = 186, + SPI = 187, + AVM = 188, + PWM = 189, + RTC = 191, + Regulator = 192, + LED = 193, + SIO = 195, + PCM = 196, + CLKRST = 197, + POWCTL = 198, + AudioOld = 201, HID = 202, LDN = 203, + CS = 204, Irsensor = 205, Capture = 206, Manu = 208, ATK = 209, + WEB = 210, + LCS = 211, GRC = 212, + Repair = 213, + Album = 214, + RID = 215, Migration = 216, MigrationLdcServ = 217, + HIDBUS = 218, + ENS = 219, + WebSocket = 223, + DCDMTP = 227, + PGL = 228, + Notification = 229, + INS = 230, + LP2P = 231, + RCD = 232, + LCM40607 = 233, + PRC = 235, + TMAHTC = 237, + ECTX = 238, + MNPP = 239, + HSHL = 240, + CAPMTP = 242, + DP2HDMI = 244, + Cradle = 245, + SProfile = 246, + NDRM = 250, + TSPM = 499, + DevMenu = 500, GeneralWebApplet = 800, WifiWebAuthApplet = 809, WhitelistedApplet = 810, -- cgit v1.2.3 From cf202f371862ebe92dd88924a9f7b8cfbc7ad738 Mon Sep 17 00:00:00 2001 From: Liam Date: Mon, 14 Nov 2022 21:00:32 -0500 Subject: nvnflinger: fix lost wakeup --- src/core/hle/service/nvflinger/buffer_queue_core.cpp | 6 ++++-- src/core/hle/service/nvflinger/buffer_queue_core.h | 5 +++-- src/core/hle/service/nvflinger/buffer_queue_producer.cpp | 14 +++++++------- src/core/hle/service/nvflinger/buffer_queue_producer.h | 3 ++- 4 files changed, 16 insertions(+), 12 deletions(-) (limited to 'src/core/hle') diff --git a/src/core/hle/service/nvflinger/buffer_queue_core.cpp b/src/core/hle/service/nvflinger/buffer_queue_core.cpp index ea4a14ea4..3d1338e66 100644 --- a/src/core/hle/service/nvflinger/buffer_queue_core.cpp +++ b/src/core/hle/service/nvflinger/buffer_queue_core.cpp @@ -23,15 +23,17 @@ void BufferQueueCore::NotifyShutdown() { } void BufferQueueCore::SignalDequeueCondition() { + dequeue_possible.store(true); dequeue_condition.notify_all(); } -bool BufferQueueCore::WaitForDequeueCondition() { +bool BufferQueueCore::WaitForDequeueCondition(std::unique_lock& lk) { if (is_shutting_down) { return false; } - dequeue_condition.wait(mutex); + dequeue_condition.wait(lk, [&] { return dequeue_possible.load(); }); + dequeue_possible.store(false); return true; } diff --git a/src/core/hle/service/nvflinger/buffer_queue_core.h b/src/core/hle/service/nvflinger/buffer_queue_core.h index ca6baefaf..85b3bc4c1 100644 --- a/src/core/hle/service/nvflinger/buffer_queue_core.h +++ b/src/core/hle/service/nvflinger/buffer_queue_core.h @@ -38,7 +38,7 @@ public: private: void SignalDequeueCondition(); - bool WaitForDequeueCondition(); + bool WaitForDequeueCondition(std::unique_lock& lk); s32 GetMinUndequeuedBufferCountLocked(bool async) const; s32 GetMinMaxBufferCountLocked(bool async) const; @@ -60,7 +60,8 @@ private: BufferQueueDefs::SlotsType slots{}; std::vector queue; s32 override_max_buffer_count{}; - mutable std::condition_variable_any dequeue_condition; + std::condition_variable dequeue_condition; + std::atomic dequeue_possible{}; const bool use_async_buffer{}; // This is always disabled on HOS bool dequeue_buffer_cannot_block{}; PixelFormat default_buffer_format{PixelFormat::Rgba8888}; diff --git a/src/core/hle/service/nvflinger/buffer_queue_producer.cpp b/src/core/hle/service/nvflinger/buffer_queue_producer.cpp index 41ba44b21..e601b5da1 100644 --- a/src/core/hle/service/nvflinger/buffer_queue_producer.cpp +++ b/src/core/hle/service/nvflinger/buffer_queue_producer.cpp @@ -121,8 +121,8 @@ Status BufferQueueProducer::SetBufferCount(s32 buffer_count) { return Status::NoError; } -Status BufferQueueProducer::WaitForFreeSlotThenRelock(bool async, s32* found, - Status* return_flags) const { +Status BufferQueueProducer::WaitForFreeSlotThenRelock(bool async, s32* found, Status* return_flags, + std::unique_lock& lk) const { bool try_again = true; while (try_again) { @@ -214,7 +214,7 @@ Status BufferQueueProducer::WaitForFreeSlotThenRelock(bool async, s32* found, return Status::WouldBlock; } - if (!core->WaitForDequeueCondition()) { + if (!core->WaitForDequeueCondition(lk)) { // We are no longer running return Status::NoError; } @@ -237,7 +237,7 @@ Status BufferQueueProducer::DequeueBuffer(s32* out_slot, Fence* out_fence, bool Status return_flags = Status::NoError; bool attached_by_consumer = false; { - std::scoped_lock lock{core->mutex}; + std::unique_lock lock{core->mutex}; core->WaitWhileAllocatingLocked(); if (format == PixelFormat::NoFormat) { @@ -248,7 +248,7 @@ Status BufferQueueProducer::DequeueBuffer(s32* out_slot, Fence* out_fence, bool usage |= core->consumer_usage_bit; s32 found{}; - Status status = WaitForFreeSlotThenRelock(async, &found, &return_flags); + Status status = WaitForFreeSlotThenRelock(async, &found, &return_flags, lock); if (status != Status::NoError) { return status; } @@ -400,13 +400,13 @@ Status BufferQueueProducer::AttachBuffer(s32* out_slot, return Status::BadValue; } - std::scoped_lock lock{core->mutex}; + std::unique_lock lock{core->mutex}; core->WaitWhileAllocatingLocked(); Status return_flags = Status::NoError; s32 found{}; - const auto status = WaitForFreeSlotThenRelock(false, &found, &return_flags); + const auto status = WaitForFreeSlotThenRelock(false, &found, &return_flags, lock); if (status != Status::NoError) { return status; } diff --git a/src/core/hle/service/nvflinger/buffer_queue_producer.h b/src/core/hle/service/nvflinger/buffer_queue_producer.h index 7526bf8ec..1d380480f 100644 --- a/src/core/hle/service/nvflinger/buffer_queue_producer.h +++ b/src/core/hle/service/nvflinger/buffer_queue_producer.h @@ -70,7 +70,8 @@ public: private: BufferQueueProducer(const BufferQueueProducer&) = delete; - Status WaitForFreeSlotThenRelock(bool async, s32* found, Status* return_flags) const; + Status WaitForFreeSlotThenRelock(bool async, s32* found, Status* return_flags, + std::unique_lock& lk) const; Kernel::KEvent* buffer_wait_event{}; Service::KernelHelpers::ServiceContext& service_context; -- cgit v1.2.3 From aa075a0c08335b1d145b2885eb0ba2f395b74f90 Mon Sep 17 00:00:00 2001 From: german77 Date: Sat, 5 Nov 2022 11:40:19 -0600 Subject: service: hid: Only overclock npad controllers --- src/core/hle/service/hid/hid.cpp | 32 +++++++++++++++++++++++++++----- src/core/hle/service/hid/hid.h | 4 +++- 2 files changed, 30 insertions(+), 6 deletions(-) (limited to 'src/core/hle') diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp index 79375bd2f..bf28440c6 100644 --- a/src/core/hle/service/hid/hid.cpp +++ b/src/core/hle/service/hid/hid.cpp @@ -36,8 +36,9 @@ namespace Service::HID { // Updating period for each HID device. // Period time is obtained by measuring the number of samples in a second on HW using a homebrew -// Correct pad_update_ns is 4ms this is overclocked to lower input lag -constexpr auto pad_update_ns = std::chrono::nanoseconds{1 * 1000 * 1000}; // (1ms, 1000Hz) +// Correct npad_update_ns is 4ms this is overclocked to lower input lag +constexpr auto npad_update_ns = std::chrono::nanoseconds{1 * 1000 * 1000}; // (1ms, 1000Hz) +constexpr auto default_update_ns = std::chrono::nanoseconds{4 * 1000 * 1000}; // (4ms, 1000Hz) constexpr auto mouse_keyboard_update_ns = std::chrono::nanoseconds{8 * 1000 * 1000}; // (8ms, 125Hz) constexpr auto motion_update_ns = std::chrono::nanoseconds{5 * 1000 * 1000}; // (5ms, 200Hz) @@ -75,8 +76,16 @@ IAppletResource::IAppletResource(Core::System& system_, GetController(HidController::UniquePad).SetCommonHeaderOffset(0x5A00); // Register update callbacks - pad_update_event = Core::Timing::CreateEvent( + npad_update_event = Core::Timing::CreateEvent( "HID::UpdatePadCallback", + [this](std::uintptr_t user_data, s64 time, + std::chrono::nanoseconds ns_late) -> std::optional { + const auto guard = LockService(); + UpdateNpad(user_data, ns_late); + return std::nullopt; + }); + default_update_event = Core::Timing::CreateEvent( + "HID::UpdateDefaultCallback", [this](std::uintptr_t user_data, s64 time, std::chrono::nanoseconds ns_late) -> std::optional { const auto guard = LockService(); @@ -100,7 +109,9 @@ IAppletResource::IAppletResource(Core::System& system_, return std::nullopt; }); - system.CoreTiming().ScheduleLoopingEvent(pad_update_ns, pad_update_ns, pad_update_event); + system.CoreTiming().ScheduleLoopingEvent(npad_update_ns, npad_update_ns, npad_update_event); + system.CoreTiming().ScheduleLoopingEvent(default_update_ns, default_update_ns, + default_update_event); system.CoreTiming().ScheduleLoopingEvent(mouse_keyboard_update_ns, mouse_keyboard_update_ns, mouse_keyboard_update_event); system.CoreTiming().ScheduleLoopingEvent(motion_update_ns, motion_update_ns, @@ -118,7 +129,8 @@ void IAppletResource::DeactivateController(HidController controller) { } IAppletResource::~IAppletResource() { - system.CoreTiming().UnscheduleEvent(pad_update_event, 0); + system.CoreTiming().UnscheduleEvent(npad_update_event, 0); + system.CoreTiming().UnscheduleEvent(default_update_event, 0); system.CoreTiming().UnscheduleEvent(mouse_keyboard_update_event, 0); system.CoreTiming().UnscheduleEvent(motion_update_event, 0); } @@ -144,10 +156,20 @@ void IAppletResource::UpdateControllers(std::uintptr_t user_data, if (controller == controllers[static_cast(HidController::Mouse)]) { continue; } + // Npad has it's own update event + if (controller == controllers[static_cast(HidController::NPad)]) { + continue; + } controller->OnUpdate(core_timing); } } +void IAppletResource::UpdateNpad(std::uintptr_t user_data, std::chrono::nanoseconds ns_late) { + auto& core_timing = system.CoreTiming(); + + controllers[static_cast(HidController::NPad)]->OnUpdate(core_timing); +} + void IAppletResource::UpdateMouseKeyboard(std::uintptr_t user_data, std::chrono::nanoseconds ns_late) { auto& core_timing = system.CoreTiming(); diff --git a/src/core/hle/service/hid/hid.h b/src/core/hle/service/hid/hid.h index 340d26fdc..b7c2a23ef 100644 --- a/src/core/hle/service/hid/hid.h +++ b/src/core/hle/service/hid/hid.h @@ -71,12 +71,14 @@ private: void GetSharedMemoryHandle(Kernel::HLERequestContext& ctx); void UpdateControllers(std::uintptr_t user_data, std::chrono::nanoseconds ns_late); + void UpdateNpad(std::uintptr_t user_data, std::chrono::nanoseconds ns_late); void UpdateMouseKeyboard(std::uintptr_t user_data, std::chrono::nanoseconds ns_late); void UpdateMotion(std::uintptr_t user_data, std::chrono::nanoseconds ns_late); KernelHelpers::ServiceContext& service_context; - std::shared_ptr pad_update_event; + std::shared_ptr npad_update_event; + std::shared_ptr default_update_event; std::shared_ptr mouse_keyboard_update_event; std::shared_ptr motion_update_event; -- cgit v1.2.3