early-access version 2551

main
pineappleEA 2022-03-15 03:53:56 +01:00
parent 23843c27a8
commit b92ba8ba26
17 changed files with 298 additions and 31 deletions

View File

@ -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()

View File

@ -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

View File

@ -85,9 +85,8 @@ public:
using difference_type = typename IntrusiveRedBlackTreeImpl::difference_type;
using pointer = std::conditional_t<Const, IntrusiveRedBlackTreeImpl::const_pointer,
IntrusiveRedBlackTreeImpl::pointer>;
using reference =
typename std::conditional<Const, IntrusiveRedBlackTreeImpl::const_reference,
IntrusiveRedBlackTreeImpl::reference>::type;
using reference = std::conditional_t<Const, IntrusiveRedBlackTreeImpl::const_reference,
IntrusiveRedBlackTreeImpl::reference>;
private:
pointer m_node;
@ -262,8 +261,7 @@ namespace impl {
} // namespace impl
template <typename T, typename Default>
using RedBlackKeyType =
typename std::remove_pointer_t<decltype(impl::GetRedBlackKeyType<T, Default>())>;
using RedBlackKeyType = std::remove_pointer_t<decltype(impl::GetRedBlackKeyType<T, Default>())>;
template <class T, class Traits, class Comparator>
class IntrusiveRedBlackTree {

View File

@ -29,8 +29,6 @@
#pragma once
#include "common/assert.h"
/*
* This file defines data structures for red-black trees.
*

View File

@ -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

View File

@ -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<void(const Core::Frontend::MiiParameters& parameters)> callback) const {
LOG_INFO(Service_HID, "(STUBBED) called");
callback(parameters);
}
} // namespace Core::Frontend

35
src/core/frontend/applets/mii.h Executable file
View File

@ -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 <functional>
#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<void(const Core::Frontend::MiiParameters& parameters)>
callback) const = 0;
};
class DefaultMiiApplet final : public MiiApplet {
public:
void ShowMii(const MiiParameters& parameters,
const std::function<void(const Core::Frontend::MiiParameters& parameters)>
callback) const override;
};
} // namespace Core::Frontend

View File

@ -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<size_t, slab_types.size()> 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;

View File

@ -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;
}

View File

@ -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();

View File

@ -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.

View File

@ -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;

View File

@ -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<u8> 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<IStorage>(system, std::move(reply)));
broker.SignalStateChanged();
}
} // namespace Service::AM::Applets

View File

@ -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 <array>
#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<Common::UUID, 8> 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

View File

@ -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<Core::Frontend::DefaultParentalControlsApplet>();
}
if (frontend.mii == nullptr) {
frontend.mii = std::make_unique<Core::Frontend::DefaultMiiApplet>();
}
if (frontend.photo_viewer == nullptr) {
frontend.photo_viewer = std::make_unique<Core::Frontend::DefaultPhotoViewerApplet>();
}
@ -277,6 +288,8 @@ std::shared_ptr<Applet> AppletManager::GetApplet(AppletId id, LibraryAppletMode
return std::make_shared<ProfileSelect>(system, mode, *frontend.profile_select);
case AppletId::SoftwareKeyboard:
return std::make_shared<SoftwareKeyboard>(system, mode, *frontend.software_keyboard);
case AppletId::MiiEdit:
return std::make_shared<Mii>(system, mode, *frontend.mii);
case AppletId::Web:
case AppletId::Shop:
case AppletId::OfflineWeb:

View File

@ -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<Core::Frontend::ControllerApplet>;
using ErrorApplet = std::unique_ptr<Core::Frontend::ErrorApplet>;
using ParentalControlsApplet = std::unique_ptr<Core::Frontend::ParentalControlsApplet>;
using MiiApplet = std::unique_ptr<Core::Frontend::MiiApplet>;
using PhotoViewer = std::unique_ptr<Core::Frontend::PhotoViewerApplet>;
using ProfileSelect = std::unique_ptr<Core::Frontend::ProfileSelectApplet>;
using SoftwareKeyboard = std::unique_ptr<Core::Frontend::SoftwareKeyboardApplet>;
@ -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;

View File

@ -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<QtControllerSelector>(*this), // Controller Selector
std::make_unique<QtErrorDisplay>(*this), // Error Display
nullptr, // Parental Controls
nullptr, // Mii editor
nullptr, // Photo Viewer
std::make_unique<QtProfileSelector>(*this), // Profile Selector
std::make_unique<QtSoftwareKeyboard>(*this), // Software Keyboard