diff --git a/CMakeLists.txt b/CMakeLists.txt index 4bf55d664..11a459813 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -363,7 +363,11 @@ if(ENABLE_QT) set(YUZU_QT_NO_CMAKE_SYSTEM_PATH "NO_CMAKE_SYSTEM_PATH") endif() - find_package(Qt5 ${QT_VERSION} REQUIRED COMPONENTS Widgets ${QT_PREFIX_HINT} ${YUZU_QT_NO_CMAKE_SYSTEM_PATH}) + if ((${CMAKE_SYSTEM_NAME} STREQUAL "Linux") AND YUZU_USE_BUNDLED_QT) + find_package(Qt5 ${QT_VERSION} REQUIRED COMPONENTS Widgets DBus ${QT_PREFIX_HINT} ${YUZU_QT_NO_CMAKE_SYSTEM_PATH}) + else() + find_package(Qt5 ${QT_VERSION} REQUIRED COMPONENTS Widgets ${QT_PREFIX_HINT} ${YUZU_QT_NO_CMAKE_SYSTEM_PATH}) + endif() if (YUZU_USE_QT_WEB_ENGINE) find_package(Qt5 COMPONENTS WebEngineCore WebEngineWidgets) endif() diff --git a/README.md b/README.md index a0d601ac3..29237c876 100755 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ yuzu emulator early access ============= -This is the source code for early-access 2550. +This is the source code for early-access 2551. ## Legal Notice diff --git a/src/common/intrusive_red_black_tree.h b/src/common/intrusive_red_black_tree.h index e379a5fce..b296b639e 100755 --- a/src/common/intrusive_red_black_tree.h +++ b/src/common/intrusive_red_black_tree.h @@ -85,9 +85,8 @@ public: using difference_type = typename IntrusiveRedBlackTreeImpl::difference_type; using pointer = std::conditional_t; - using reference = - typename std::conditional::type; + using reference = std::conditional_t; private: pointer m_node; @@ -262,8 +261,7 @@ namespace impl { } // namespace impl template -using RedBlackKeyType = - typename std::remove_pointer_t())>; +using RedBlackKeyType = std::remove_pointer_t())>; template class IntrusiveRedBlackTree { diff --git a/src/common/tree.h b/src/common/tree.h index a30aa80dc..28370e343 100755 --- a/src/common/tree.h +++ b/src/common/tree.h @@ -29,8 +29,6 @@ #pragma once -#include "common/assert.h" - /* * This file defines data structures for red-black trees. * diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index ea1910844..b19abe524 100755 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -122,6 +122,8 @@ add_library(core STATIC frontend/applets/error.h frontend/applets/general_frontend.cpp frontend/applets/general_frontend.h + frontend/applets/mii.cpp + frontend/applets/mii.h frontend/applets/profile_select.cpp frontend/applets/profile_select.h frontend/applets/software_keyboard.cpp @@ -303,6 +305,8 @@ add_library(core STATIC hle/service/am/applets/applet_error.h hle/service/am/applets/applet_general_backend.cpp hle/service/am/applets/applet_general_backend.h + hle/service/am/applets/applet_mii.cpp + hle/service/am/applets/applet_mii.h hle/service/am/applets/applet_profile_select.cpp hle/service/am/applets/applet_profile_select.h hle/service/am/applets/applet_software_keyboard.cpp diff --git a/src/core/frontend/applets/mii.cpp b/src/core/frontend/applets/mii.cpp new file mode 100755 index 000000000..1c05ff412 --- /dev/null +++ b/src/core/frontend/applets/mii.cpp @@ -0,0 +1,19 @@ +// Copyright 2022 yuzu Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include "common/logging/log.h" +#include "core/frontend/applets/mii.h" + +namespace Core::Frontend { + +MiiApplet::~MiiApplet() = default; + +void DefaultMiiApplet::ShowMii( + const MiiParameters& parameters, + const std::function callback) const { + LOG_INFO(Service_HID, "(STUBBED) called"); + callback(parameters); +} + +} // namespace Core::Frontend diff --git a/src/core/frontend/applets/mii.h b/src/core/frontend/applets/mii.h new file mode 100755 index 000000000..1fc40a9c6 --- /dev/null +++ b/src/core/frontend/applets/mii.h @@ -0,0 +1,35 @@ +// Copyright 2022 yuzu Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +#include + +#include "core/hle/result.h" +#include "core/hle/service/mii/mii_manager.h" + +namespace Core::Frontend { + +struct MiiParameters { + bool is_editable; + Service::Mii::MiiInfo mii_data{}; +}; + +class MiiApplet { +public: + virtual ~MiiApplet(); + + virtual void ShowMii(const MiiParameters& parameters, + const std::function + callback) const = 0; +}; + +class DefaultMiiApplet final : public MiiApplet { +public: + void ShowMii(const MiiParameters& parameters, + const std::function + callback) const override; +}; + +} // namespace Core::Frontend diff --git a/src/core/hle/kernel/init/init_slab_setup.cpp b/src/core/hle/kernel/init/init_slab_setup.cpp index e75ffd912..b0f773ee0 100755 --- a/src/core/hle/kernel/init/init_slab_setup.cpp +++ b/src/core/hle/kernel/init/init_slab_setup.cpp @@ -206,17 +206,17 @@ void InitializeSlabHeaps(Core::System& system, KMemoryLayout& memory_layout) { // Create an array to represent the gaps between the slabs. const size_t total_gap_size = CalculateSlabHeapGapSize(); - size_t slab_gaps[slab_types.size()]; - for (size_t i = 0; i < slab_types.size(); i++) { + std::array slab_gaps; + for (auto& slab_gap : slab_gaps) { // Note: This is an off-by-one error from Nintendo's intention, because GenerateRandomRange // is inclusive. However, Nintendo also has the off-by-one error, and it's "harmless", so we // will include it ourselves. - slab_gaps[i] = KSystemControl::GenerateRandomRange(0, total_gap_size); + slab_gap = KSystemControl::GenerateRandomRange(0, total_gap_size); } // Sort the array, so that we can treat differences between values as offsets to the starts of // slabs. - for (size_t i = 1; i < slab_types.size(); i++) { + for (size_t i = 1; i < slab_gaps.size(); i++) { for (size_t j = i; j > 0 && slab_gaps[j - 1] > slab_gaps[j]; j--) { std::swap(slab_gaps[j], slab_gaps[j - 1]); } @@ -226,7 +226,7 @@ void InitializeSlabHeaps(Core::System& system, KMemoryLayout& memory_layout) { VAddr gap_start = address; size_t gap_size = 0; - for (size_t i = 0; i < slab_types.size(); i++) { + for (size_t i = 0; i < slab_gaps.size(); i++) { // Add the random gap to the address. const auto cur_gap = (i == 0) ? slab_gaps[0] : slab_gaps[i] - slab_gaps[i - 1]; address += cur_gap; diff --git a/src/core/hle/kernel/k_page_table.cpp b/src/core/hle/kernel/k_page_table.cpp index 0344127e7..02d93b12e 100755 --- a/src/core/hle/kernel/k_page_table.cpp +++ b/src/core/hle/kernel/k_page_table.cpp @@ -445,18 +445,18 @@ VAddr KPageTable::FindFreeArea(VAddr region_start, std::size_t region_num_pages, if (info.state != KMemoryState::Free) { continue; } - if (!(region_start <= candidate)) { + if (region_start > candidate) { continue; } - if (!(info.GetAddress() + guard_pages * PageSize <= candidate)) { + if (info.GetAddress() + guard_pages * PageSize > candidate) { continue; } - if (!(candidate + (num_pages + guard_pages) * PageSize - 1 <= - info.GetLastAddress())) { + + const VAddr candidate_end = candidate + (num_pages + guard_pages) * PageSize - 1; + if (candidate_end > info.GetLastAddress()) { continue; } - if (!(candidate + (num_pages + guard_pages) * PageSize - 1 <= - region_start + region_num_pages * PageSize - 1)) { + if (candidate_end > region_start + region_num_pages * PageSize - 1) { continue; } diff --git a/src/core/hle/kernel/k_port.cpp b/src/core/hle/kernel/k_port.cpp index 496700195..ceb98709f 100755 --- a/src/core/hle/kernel/k_port.cpp +++ b/src/core/hle/kernel/k_port.cpp @@ -58,7 +58,7 @@ ResultCode KPort::EnqueueSession(KServerSession* session) { server.EnqueueSession(session); - if (auto session_ptr = server.GetSessionRequestHandler().lock(); session_ptr) { + if (auto session_ptr = server.GetSessionRequestHandler().lock()) { session_ptr->ClientConnected(server.AcceptSession()); } else { UNREACHABLE(); diff --git a/src/core/hle/kernel/k_server_port.h b/src/core/hle/kernel/k_server_port.h index d72f3bf48..2185736be 100755 --- a/src/core/hle/kernel/k_server_port.h +++ b/src/core/hle/kernel/k_server_port.h @@ -30,7 +30,7 @@ public: /// Whether or not this server port has an HLE handler available. bool HasSessionRequestHandler() const { - return session_handler.lock() != nullptr; + return !session_handler.expired(); } /// Gets the HLE handler for this port. diff --git a/src/core/hle/kernel/k_thread_local_page.h b/src/core/hle/kernel/k_thread_local_page.h index 1e2a7770e..658c67e94 100755 --- a/src/core/hle/kernel/k_thread_local_page.h +++ b/src/core/hle/kernel/k_thread_local_page.h @@ -28,7 +28,7 @@ public: static_assert(RegionsPerPage > 0); public: - explicit KThreadLocalPage(VAddr addr = {}) : m_virt_addr(addr) { + constexpr explicit KThreadLocalPage(VAddr addr = {}) : m_virt_addr(addr) { m_is_region_free.fill(true); } @@ -88,15 +88,15 @@ public: } private: - constexpr VAddr GetRegionAddress(size_t i) { + constexpr VAddr GetRegionAddress(size_t i) const { return this->GetAddress() + i * Svc::ThreadLocalRegionSize; } - constexpr bool Contains(VAddr addr) { + constexpr bool Contains(VAddr addr) const { return this->GetAddress() <= addr && addr < this->GetAddress() + PageSize; } - constexpr size_t GetRegionIndex(VAddr addr) { + constexpr size_t GetRegionIndex(VAddr addr) const { ASSERT(Common::IsAligned(addr, Svc::ThreadLocalRegionSize)); ASSERT(this->Contains(addr)); return (addr - this->GetAddress()) / Svc::ThreadLocalRegionSize; diff --git a/src/core/hle/service/am/applets/applet_mii.cpp b/src/core/hle/service/am/applets/applet_mii.cpp new file mode 100755 index 000000000..8c4173737 --- /dev/null +++ b/src/core/hle/service/am/applets/applet_mii.cpp @@ -0,0 +1,101 @@ +// Copyright 2022 yuzu Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include "common/assert.h" +#include "common/logging/log.h" +#include "core/core.h" +#include "core/frontend/applets/mii.h" +#include "core/hle/service/am/am.h" +#include "core/hle/service/am/applets/applet_mii.h" +#include "core/reporter.h" + +namespace Service::AM::Applets { + +Mii::Mii(Core::System& system_, LibraryAppletMode applet_mode_, + const Core::Frontend::MiiApplet& frontend_) + : Applet{system_, applet_mode_}, frontend{frontend_}, system{system_} {} + +Mii::~Mii() = default; + +void Mii::Initialize() { + is_complete = false; + + const auto storage = broker.PopNormalDataToApplet(); + ASSERT(storage != nullptr); + + const auto data = storage->GetData(); + ASSERT(data.size() == sizeof(MiiAppletInput)); + + std::memcpy(&input_data, data.data(), sizeof(MiiAppletInput)); +} + +bool Mii::TransactionComplete() const { + return is_complete; +} + +ResultCode Mii::GetStatus() const { + return ResultSuccess; +} + +void Mii::ExecuteInteractive() { + UNREACHABLE_MSG("Unexpected interactive applet data!"); +} + +void Mii::Execute() { + if (is_complete) { + return; + } + + const auto callback = [this](const Core::Frontend::MiiParameters& parameters) { + DisplayCompleted(parameters); + }; + + switch (input_data.applet_mode) { + case MiiAppletMode::ShowMiiEdit: { + Service::Mii::MiiManager manager; + Core::Frontend::MiiParameters params{ + .is_editable = false, + .mii_data = input_data.mii_char_info.mii_data, + }; + frontend.ShowMii(params, callback); + break; + } + case MiiAppletMode::EditMii: { + Service::Mii::MiiManager manager; + Core::Frontend::MiiParameters params{ + .is_editable = true, + .mii_data = input_data.mii_char_info.mii_data, + }; + frontend.ShowMii(params, callback); + break; + } + case MiiAppletMode::CreateMii: { + Service::Mii::MiiManager manager; + Core::Frontend::MiiParameters params{ + .is_editable = true, + .mii_data = manager.BuildDefault(0), + }; + frontend.ShowMii(params, callback); + break; + } + default: + UNIMPLEMENTED_MSG("Unimplemented LibAppletMiiEdit mode={:02X}!", input_data.applet_mode); + } +} + +void Mii::DisplayCompleted(const Core::Frontend::MiiParameters& parameters) { + is_complete = true; + + std::vector reply(sizeof(AppletOutputForCharInfoEditing)); + output_data = { + .result = ResultSuccess, + .mii_data = parameters.mii_data, + }; + + std::memcpy(reply.data(), &output_data, sizeof(AppletOutputForCharInfoEditing)); + broker.PushNormalDataFromApplet(std::make_shared(system, std::move(reply))); + broker.SignalStateChanged(); +} + +} // namespace Service::AM::Applets diff --git a/src/core/hle/service/am/applets/applet_mii.h b/src/core/hle/service/am/applets/applet_mii.h new file mode 100755 index 000000000..42326bfc2 --- /dev/null +++ b/src/core/hle/service/am/applets/applet_mii.h @@ -0,0 +1,90 @@ +// Copyright 2022 yuzu Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +#include + +#include "core/hle/result.h" +#include "core/hle/service/am/applets/applets.h" +#include "core/hle/service/mii/mii_manager.h" + +namespace Core { +class System; +} + +namespace Service::AM::Applets { + +// This is nn::mii::AppletMode +enum class MiiAppletMode : u32 { + ShowMiiEdit = 0, + AppendMii = 1, + AppendMiiImage = 2, + UpdateMiiImage = 3, + CreateMii = 4, + EditMii = 5, +}; + +struct MiiCharInfo { + Service::Mii::MiiInfo mii_data{}; + INSERT_PADDING_BYTES(0x28); +}; +static_assert(sizeof(MiiCharInfo) == 0x80, "MiiCharInfo has incorrect size."); + +// This is nn::mii::AppletInput +struct MiiAppletInput { + s32 version{}; + MiiAppletMode applet_mode{}; + u32 special_mii_key_code{}; + union { + std::array valid_uuid; + MiiCharInfo mii_char_info; + }; + Common::UUID used_uuid; + INSERT_PADDING_BYTES(0x64); +}; +static_assert(sizeof(MiiAppletInput) == 0x100, "MiiAppletInput has incorrect size."); + +// This is nn::mii::AppletOutput +struct MiiAppletOutput { + ResultCode result{ResultSuccess}; + s32 index{}; + INSERT_PADDING_BYTES(0x18); +}; +static_assert(sizeof(MiiAppletOutput) == 0x20, "MiiAppletOutput has incorrect size."); + +// This is nn::mii::AppletOutputForCharInfoEditing +struct AppletOutputForCharInfoEditing { + ResultCode result{ResultSuccess}; + Service::Mii::MiiInfo mii_data{}; + INSERT_PADDING_BYTES(0x24); +}; +static_assert(sizeof(AppletOutputForCharInfoEditing) == 0x80, + "AppletOutputForCharInfoEditing has incorrect size."); + +class Mii final : public Applet { +public: + explicit Mii(Core::System& system_, LibraryAppletMode applet_mode_, + const Core::Frontend::MiiApplet& frontend_); + ~Mii() override; + + void Initialize() override; + + bool TransactionComplete() const override; + ResultCode GetStatus() const override; + void ExecuteInteractive() override; + void Execute() override; + + void DisplayCompleted(const Core::Frontend::MiiParameters& parameters); + +private: + const Core::Frontend::MiiApplet& frontend; + MiiAppletInput input_data{}; + AppletOutputForCharInfoEditing output_data{}; + + bool is_complete = false; + Core::System& system; +}; + +} // 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 134ac1ee2..79e62679d 100755 --- a/src/core/hle/service/am/applets/applets.cpp +++ b/src/core/hle/service/am/applets/applets.cpp @@ -9,6 +9,7 @@ #include "core/frontend/applets/controller.h" #include "core/frontend/applets/error.h" #include "core/frontend/applets/general_frontend.h" +#include "core/frontend/applets/mii.h" #include "core/frontend/applets/profile_select.h" #include "core/frontend/applets/software_keyboard.h" #include "core/frontend/applets/web_browser.h" @@ -19,6 +20,7 @@ #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" +#include "core/hle/service/am/applets/applet_mii.h" #include "core/hle/service/am/applets/applet_profile_select.h" #include "core/hle/service/am/applets/applet_software_keyboard.h" #include "core/hle/service/am/applets/applet_web_browser.h" @@ -172,10 +174,11 @@ AppletFrontendSet::AppletFrontendSet() = default; AppletFrontendSet::AppletFrontendSet(ControllerApplet controller_applet, ErrorApplet error_applet, ParentalControlsApplet parental_controls_applet, - PhotoViewer photo_viewer_, ProfileSelect profile_select_, + MiiApplet mii_applet, PhotoViewer photo_viewer_, + ProfileSelect profile_select_, SoftwareKeyboard software_keyboard_, WebBrowser web_browser_) : controller{std::move(controller_applet)}, error{std::move(error_applet)}, - parental_controls{std::move(parental_controls_applet)}, + parental_controls{std::move(parental_controls_applet)}, mii{std::move(mii_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_)} {} @@ -206,6 +209,10 @@ void AppletManager::SetAppletFrontendSet(AppletFrontendSet set) { frontend.parental_controls = std::move(set.parental_controls); } + if (set.mii != nullptr) { + frontend.mii = std::move(set.mii); + } + if (set.photo_viewer != nullptr) { frontend.photo_viewer = std::move(set.photo_viewer); } @@ -243,6 +250,10 @@ void AppletManager::SetDefaultAppletsIfMissing() { std::make_unique(); } + if (frontend.mii == nullptr) { + frontend.mii = std::make_unique(); + } + if (frontend.photo_viewer == nullptr) { frontend.photo_viewer = std::make_unique(); } @@ -277,6 +288,8 @@ std::shared_ptr AppletManager::GetApplet(AppletId id, LibraryAppletMode return std::make_shared(system, mode, *frontend.profile_select); case AppletId::SoftwareKeyboard: return std::make_shared(system, mode, *frontend.software_keyboard); + case AppletId::MiiEdit: + return std::make_shared(system, mode, *frontend.mii); case AppletId::Web: case AppletId::Shop: case AppletId::OfflineWeb: diff --git a/src/core/hle/service/am/applets/applets.h b/src/core/hle/service/am/applets/applets.h index 15eeb4ee1..0c44aec79 100755 --- a/src/core/hle/service/am/applets/applets.h +++ b/src/core/hle/service/am/applets/applets.h @@ -21,6 +21,7 @@ class ControllerApplet; class ECommerceApplet; class ErrorApplet; class ParentalControlsApplet; +class MiiApplet; class PhotoViewerApplet; class ProfileSelectApplet; class SoftwareKeyboardApplet; @@ -179,6 +180,7 @@ struct AppletFrontendSet { using ControllerApplet = std::unique_ptr; using ErrorApplet = std::unique_ptr; using ParentalControlsApplet = std::unique_ptr; + using MiiApplet = std::unique_ptr; using PhotoViewer = std::unique_ptr; using ProfileSelect = std::unique_ptr; using SoftwareKeyboard = std::unique_ptr; @@ -186,9 +188,9 @@ struct AppletFrontendSet { AppletFrontendSet(); AppletFrontendSet(ControllerApplet controller_applet, ErrorApplet error_applet, - ParentalControlsApplet parental_controls_applet, PhotoViewer photo_viewer_, - ProfileSelect profile_select_, SoftwareKeyboard software_keyboard_, - WebBrowser web_browser_); + ParentalControlsApplet parental_controls_applet, MiiApplet mii_applet, + PhotoViewer photo_viewer_, ProfileSelect profile_select_, + SoftwareKeyboard software_keyboard_, WebBrowser web_browser_); ~AppletFrontendSet(); AppletFrontendSet(const AppletFrontendSet&) = delete; @@ -200,6 +202,7 @@ struct AppletFrontendSet { ControllerApplet controller; ErrorApplet error; ParentalControlsApplet parental_controls; + MiiApplet mii; PhotoViewer photo_viewer; ProfileSelect profile_select; SoftwareKeyboard software_keyboard; diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index 1d459bdb3..06774768d 100755 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp @@ -25,6 +25,7 @@ #include "core/file_sys/vfs_real.h" #include "core/frontend/applets/controller.h" #include "core/frontend/applets/general_frontend.h" +#include "core/frontend/applets/mii.h" #include "core/frontend/applets/software_keyboard.h" #include "core/hid/emulated_controller.h" #include "core/hid/hid_core.h" @@ -1285,6 +1286,7 @@ bool GMainWindow::LoadROM(const QString& filename, u64 program_id, std::size_t p std::make_unique(*this), // Controller Selector std::make_unique(*this), // Error Display nullptr, // Parental Controls + nullptr, // Mii editor nullptr, // Photo Viewer std::make_unique(*this), // Profile Selector std::make_unique(*this), // Software Keyboard