early-access version 1591

This commit is contained in:
pineappleEA
2021-04-13 00:32:26 +02:00
parent 2f619137d1
commit e839de5014
67 changed files with 777 additions and 5583 deletions

View File

@@ -273,7 +273,6 @@ add_library(core STATIC
hle/service/am/applets/profile_select.h
hle/service/am/applets/software_keyboard.cpp
hle/service/am/applets/software_keyboard.h
hle/service/am/applets/software_keyboard_types.h
hle/service/am/applets/web_browser.cpp
hle/service/am/applets/web_browser.h
hle/service/am/applets/web_types.h

View File

@@ -1,149 +1,29 @@
// Copyright 2021 yuzu Emulator Project
// Copyright 2018 yuzu emulator team
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#include <thread>
#include "common/logging/log.h"
#include "common/logging/backend.h"
#include "common/string_util.h"
#include "core/frontend/applets/software_keyboard.h"
namespace Core::Frontend {
SoftwareKeyboardApplet::~SoftwareKeyboardApplet() = default;
DefaultSoftwareKeyboardApplet::~DefaultSoftwareKeyboardApplet() = default;
void DefaultSoftwareKeyboardApplet::RequestText(
std::function<void(std::optional<std::u16string>)> out,
SoftwareKeyboardParameters parameters) const {
if (parameters.initial_text.empty())
out(u"yuzu");
void DefaultSoftwareKeyboardApplet::InitializeKeyboard(
bool is_inline, KeyboardInitializeParameters initialize_parameters,
std::function<void(Service::AM::Applets::SwkbdResult, std::u16string)> submit_normal_callback_,
std::function<void(Service::AM::Applets::SwkbdReplyType, std::u16string, s32)>
submit_inline_callback_) {
if (is_inline) {
LOG_WARNING(
Service_AM,
"(STUBBED) called, backend requested to initialize the inline software keyboard.");
submit_inline_callback = std::move(submit_inline_callback_);
} else {
LOG_WARNING(
Service_AM,
"(STUBBED) called, backend requested to initialize the normal software keyboard.");
submit_normal_callback = std::move(submit_normal_callback_);
}
parameters = std::move(initialize_parameters);
LOG_INFO(Service_AM,
"\nKeyboardInitializeParameters:"
"\nok_text={}"
"\nheader_text={}"
"\nsub_text={}"
"\nguide_text={}"
"\ninitial_text={}"
"\nmax_text_length={}"
"\nmin_text_length={}"
"\ninitial_cursor_position={}"
"\ntype={}"
"\npassword_mode={}"
"\ntext_draw_type={}"
"\nkey_disable_flags={}"
"\nuse_blur_background={}"
"\nenable_backspace_button={}"
"\nenable_return_button={}"
"\ndisable_cancel_button={}",
Common::UTF16ToUTF8(parameters.ok_text), Common::UTF16ToUTF8(parameters.header_text),
Common::UTF16ToUTF8(parameters.sub_text), Common::UTF16ToUTF8(parameters.guide_text),
Common::UTF16ToUTF8(parameters.initial_text), parameters.max_text_length,
parameters.min_text_length, parameters.initial_cursor_position, parameters.type,
parameters.password_mode, parameters.text_draw_type, parameters.key_disable_flags.raw,
parameters.use_blur_background, parameters.enable_backspace_button,
parameters.enable_return_button, parameters.disable_cancel_button);
out(parameters.initial_text);
}
void DefaultSoftwareKeyboardApplet::ShowNormalKeyboard() const {
void DefaultSoftwareKeyboardApplet::SendTextCheckDialog(
std::u16string error_message, std::function<void()> finished_check) const {
LOG_WARNING(Service_AM,
"(STUBBED) called, backend requested to show the normal software keyboard.");
SubmitNormalText(u"yuzu");
"(STUBBED) called - Default fallback software keyboard does not support text "
"check! (error_message={})",
Common::UTF16ToUTF8(error_message));
finished_check();
}
void DefaultSoftwareKeyboardApplet::ShowTextCheckDialog(
Service::AM::Applets::SwkbdTextCheckResult text_check_result,
std::u16string text_check_message) const {
LOG_WARNING(Service_AM, "(STUBBED) called, backend requested to show the text check dialog.");
}
void DefaultSoftwareKeyboardApplet::ShowInlineKeyboard(
InlineAppearParameters appear_parameters) const {
LOG_WARNING(Service_AM,
"(STUBBED) called, backend requested to show the inline software keyboard.");
LOG_INFO(Service_AM,
"\nInlineAppearParameters:"
"\nmax_text_length={}"
"\nmin_text_length={}"
"\nkey_top_scale_x={}"
"\nkey_top_scale_y={}"
"\nkey_top_translate_x={}"
"\nkey_top_translate_y={}"
"\ntype={}"
"\nkey_disable_flags={}"
"\nkey_top_as_floating={}"
"\nenable_backspace_button={}"
"\nenable_return_button={}"
"\ndisable_cancel_button={}",
appear_parameters.max_text_length, appear_parameters.min_text_length,
appear_parameters.key_top_scale_x, appear_parameters.key_top_scale_y,
appear_parameters.key_top_translate_x, appear_parameters.key_top_translate_y,
appear_parameters.type, appear_parameters.key_disable_flags.raw,
appear_parameters.key_top_as_floating, appear_parameters.enable_backspace_button,
appear_parameters.enable_return_button, appear_parameters.disable_cancel_button);
std::thread([this] { SubmitInlineText(u"yuzu"); }).detach();
}
void DefaultSoftwareKeyboardApplet::HideInlineKeyboard() const {
LOG_WARNING(Service_AM,
"(STUBBED) called, backend requested to hide the inline software keyboard.");
}
void DefaultSoftwareKeyboardApplet::InlineTextChanged(InlineTextParameters text_parameters) const {
LOG_WARNING(Service_AM,
"(STUBBED) called, backend requested to change the inline keyboard text.");
LOG_INFO(Service_AM,
"\nInlineTextParameters:"
"\ninput_text={}"
"\ncursor_position={}",
Common::UTF16ToUTF8(text_parameters.input_text), text_parameters.cursor_position);
submit_inline_callback(Service::AM::Applets::SwkbdReplyType::ChangedString,
text_parameters.input_text, text_parameters.cursor_position);
}
void DefaultSoftwareKeyboardApplet::ExitKeyboard() const {
LOG_WARNING(Service_AM, "(STUBBED) called, backend requested to exit the software keyboard.");
}
void DefaultSoftwareKeyboardApplet::SubmitNormalText(std::u16string text) const {
submit_normal_callback(Service::AM::Applets::SwkbdResult::Ok, text);
}
void DefaultSoftwareKeyboardApplet::SubmitInlineText(std::u16string_view text) const {
std::this_thread::sleep_for(std::chrono::milliseconds(500));
for (std::size_t index = 0; index < text.size(); ++index) {
submit_inline_callback(Service::AM::Applets::SwkbdReplyType::ChangedString,
std::u16string(text.data(), text.data() + index + 1),
static_cast<s32>(index) + 1);
std::this_thread::sleep_for(std::chrono::milliseconds(250));
}
submit_inline_callback(Service::AM::Applets::SwkbdReplyType::DecidedEnter, std::u16string(text),
static_cast<s32>(text.size()));
}
} // namespace Core::Frontend

View File

@@ -1,116 +1,54 @@
// Copyright 2021 yuzu Emulator Project
// Copyright 2018 yuzu emulator team
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#pragma once
#include <functional>
#include <thread>
#include <optional>
#include <string>
#include "common/bit_field.h"
#include "common/common_types.h"
#include "core/hle/service/am/applets/software_keyboard_types.h"
namespace Core::Frontend {
struct KeyboardInitializeParameters {
std::u16string ok_text;
struct SoftwareKeyboardParameters {
std::u16string submit_text;
std::u16string header_text;
std::u16string sub_text;
std::u16string guide_text;
std::u16string initial_text;
u32 max_text_length;
u32 min_text_length;
s32 initial_cursor_position;
Service::AM::Applets::SwkbdType type;
Service::AM::Applets::SwkbdPasswordMode password_mode;
Service::AM::Applets::SwkbdTextDrawType text_draw_type;
Service::AM::Applets::SwkbdKeyDisableFlags key_disable_flags;
bool use_blur_background;
bool enable_backspace_button;
bool enable_return_button;
bool disable_cancel_button;
};
std::size_t max_length;
bool password;
bool cursor_at_beginning;
struct InlineAppearParameters {
u32 max_text_length;
u32 min_text_length;
f32 key_top_scale_x;
f32 key_top_scale_y;
f32 key_top_translate_x;
f32 key_top_translate_y;
Service::AM::Applets::SwkbdType type;
Service::AM::Applets::SwkbdKeyDisableFlags key_disable_flags;
bool key_top_as_floating;
bool enable_backspace_button;
bool enable_return_button;
bool disable_cancel_button;
};
union {
u8 value;
struct InlineTextParameters {
std::u16string input_text;
s32 cursor_position;
BitField<1, 1, u8> disable_space;
BitField<2, 1, u8> disable_address;
BitField<3, 1, u8> disable_percent;
BitField<4, 1, u8> disable_slash;
BitField<6, 1, u8> disable_number;
BitField<7, 1, u8> disable_download_code;
};
};
class SoftwareKeyboardApplet {
public:
virtual ~SoftwareKeyboardApplet();
virtual void InitializeKeyboard(
bool is_inline, KeyboardInitializeParameters initialize_parameters,
std::function<void(Service::AM::Applets::SwkbdResult, std::u16string)>
submit_normal_callback_,
std::function<void(Service::AM::Applets::SwkbdReplyType, std::u16string, s32)>
submit_inline_callback_) = 0;
virtual void ShowNormalKeyboard() const = 0;
virtual void ShowTextCheckDialog(Service::AM::Applets::SwkbdTextCheckResult text_check_result,
std::u16string text_check_message) const = 0;
virtual void ShowInlineKeyboard(InlineAppearParameters appear_parameters) const = 0;
virtual void HideInlineKeyboard() const = 0;
virtual void InlineTextChanged(InlineTextParameters text_parameters) const = 0;
virtual void ExitKeyboard() const = 0;
virtual void RequestText(std::function<void(std::optional<std::u16string>)> out,
SoftwareKeyboardParameters parameters) const = 0;
virtual void SendTextCheckDialog(std::u16string error_message,
std::function<void()> finished_check) const = 0;
};
class DefaultSoftwareKeyboardApplet final : public SoftwareKeyboardApplet {
public:
~DefaultSoftwareKeyboardApplet() override;
void InitializeKeyboard(
bool is_inline, KeyboardInitializeParameters initialize_parameters,
std::function<void(Service::AM::Applets::SwkbdResult, std::u16string)>
submit_normal_callback_,
std::function<void(Service::AM::Applets::SwkbdReplyType, std::u16string, s32)>
submit_inline_callback_) override;
void ShowNormalKeyboard() const override;
void ShowTextCheckDialog(Service::AM::Applets::SwkbdTextCheckResult text_check_result,
std::u16string text_check_message) const override;
void ShowInlineKeyboard(InlineAppearParameters appear_parameters) const override;
void HideInlineKeyboard() const override;
void InlineTextChanged(InlineTextParameters text_parameters) const override;
void ExitKeyboard() const override;
private:
void SubmitNormalText(std::u16string text) const;
void SubmitInlineText(std::u16string_view text) const;
KeyboardInitializeParameters parameters;
mutable std::function<void(Service::AM::Applets::SwkbdResult, std::u16string)>
submit_normal_callback;
mutable std::function<void(Service::AM::Applets::SwkbdReplyType, std::u16string, s32)>
submit_inline_callback;
void RequestText(std::function<void(std::optional<std::u16string>)> out,
SoftwareKeyboardParameters parameters) const override;
void SendTextCheckDialog(std::u16string error_message,
std::function<void()> finished_check) const override;
};
} // namespace Core::Frontend

View File

@@ -12,9 +12,7 @@ InputInterpreter::InputInterpreter(Core::System& system)
: npad{system.ServiceManager()
.GetService<Service::HID::Hid>("hid")
->GetAppletResource()
->GetController<Service::HID::Controller_NPad>(Service::HID::HidController::NPad)} {
ResetButtonStates();
}
->GetController<Service::HID::Controller_NPad>(Service::HID::HidController::NPad)} {}
InputInterpreter::~InputInterpreter() = default;
@@ -27,17 +25,6 @@ void InputInterpreter::PollInput() {
button_states[current_index] = button_state;
}
void InputInterpreter::ResetButtonStates() {
previous_index = 0;
current_index = 0;
button_states[0] = 0xFFFFFFFF;
for (std::size_t i = 1; i < button_states.size(); ++i) {
button_states[i] = 0;
}
}
bool InputInterpreter::IsButtonPressed(HIDButton button) const {
return (button_states[current_index] & (1U << static_cast<u8>(button))) != 0;
}

View File

@@ -66,9 +66,6 @@ public:
/// Gets a button state from HID and inserts it into the array of button states.
void PollInput();
/// Resets all the button states to their defaults.
void ResetButtonStates();
/**
* Checks whether the button is pressed.
*

View File

@@ -75,14 +75,10 @@ void HLERequestContext::ParseCommandBuffer(const HandleTable& handle_table, u32_
if (incoming) {
// Populate the object lists with the data in the IPC request.
for (u32 handle = 0; handle < handle_descriptor_header->num_handles_to_copy; ++handle) {
const u32 copy_handle{rp.Pop<Handle>()};
copy_handles.push_back(copy_handle);
copy_objects.push_back(handle_table.GetGeneric(copy_handle));
copy_objects.push_back(handle_table.GetGeneric(rp.Pop<Handle>()));
}
for (u32 handle = 0; handle < handle_descriptor_header->num_handles_to_move; ++handle) {
const u32 move_handle{rp.Pop<Handle>()};
move_handles.push_back(move_handle);
move_objects.push_back(handle_table.GetGeneric(move_handle));
move_objects.push_back(handle_table.GetGeneric(rp.Pop<Handle>()));
}
} else {
// For responses we just ignore the handles, they're empty and will be populated when

View File

@@ -210,14 +210,6 @@ public:
/// Helper function to test whether the output buffer at buffer_index can be written
bool CanWriteBuffer(std::size_t buffer_index = 0) const;
Handle GetCopyHandle(std::size_t index) const {
return copy_handles.at(index);
}
Handle GetMoveHandle(std::size_t index) const {
return move_handles.at(index);
}
template <typename T>
std::shared_ptr<T> GetCopyObject(std::size_t index) {
return DynamicObjectCast<T>(copy_objects.at(index));
@@ -293,8 +285,6 @@ private:
std::shared_ptr<Kernel::ServerSession> server_session;
std::shared_ptr<KThread> thread;
// TODO(yuriks): Check common usage of this and optimize size accordingly
boost::container::small_vector<Handle, 8> move_handles;
boost::container::small_vector<Handle, 8> copy_handles;
boost::container::small_vector<std::shared_ptr<Object>, 8> move_objects;
boost::container::small_vector<std::shared_ptr<Object>, 8> copy_objects;
boost::container::small_vector<std::shared_ptr<SessionRequestHandler>, 8> domain_objects;

View File

@@ -402,7 +402,7 @@ public:
return wait_cancelled;
}
[[nodiscard]] void ClearWaitCancelled() {
void ClearWaitCancelled() {
wait_cancelled = false;
}

View File

@@ -67,13 +67,8 @@ struct KernelCore::Impl {
is_phantom_mode_for_singlecore = false;
InitializePhysicalCores();
// Derive the initial memory layout from the emulated board
KMemoryLayout memory_layout;
DeriveInitialMemoryLayout(memory_layout);
InitializeMemoryLayout(memory_layout);
InitializeSystemResourceLimit(kernel, system, memory_layout);
InitializeSlabHeaps();
InitializeSystemResourceLimit(kernel, system);
InitializeMemoryLayout();
InitializeSchedulers();
InitializeSuspendThreads();
InitializePreemption(kernel);
@@ -142,32 +137,27 @@ struct KernelCore::Impl {
}
// Creates the default system resource limit
void InitializeSystemResourceLimit(KernelCore& kernel, Core::System& system,
const KMemoryLayout& memory_layout) {
void InitializeSystemResourceLimit(KernelCore& kernel, Core::System& system) {
system_resource_limit = std::make_shared<KResourceLimit>(kernel, system);
const auto [total_size, kernel_size] = memory_layout.GetTotalAndKernelMemorySizes();
// If setting the default system values fails, then something seriously wrong has occurred.
ASSERT(system_resource_limit->SetLimitValue(LimitableResource::PhysicalMemory, total_size)
ASSERT(system_resource_limit->SetLimitValue(LimitableResource::PhysicalMemory, 0x100000000)
.IsSuccess());
ASSERT(system_resource_limit->SetLimitValue(LimitableResource::Threads, 800).IsSuccess());
ASSERT(system_resource_limit->SetLimitValue(LimitableResource::Events, 900).IsSuccess());
ASSERT(system_resource_limit->SetLimitValue(LimitableResource::TransferMemory, 200)
.IsSuccess());
ASSERT(system_resource_limit->SetLimitValue(LimitableResource::Sessions, 1133).IsSuccess());
system_resource_limit->Reserve(LimitableResource::PhysicalMemory, kernel_size);
// Derived from recent software updates. The kernel reserves 27MB
constexpr u64 kernel_size{0x1b00000};
if (!system_resource_limit->Reserve(LimitableResource::PhysicalMemory, kernel_size)) {
UNREACHABLE();
}
// Reserve secure applet memory, introduced in firmware 5.0.0
constexpr u64 secure_applet_memory_size{Common::Size_4_MB};
constexpr u64 secure_applet_memory_size{0x400000};
ASSERT(system_resource_limit->Reserve(LimitableResource::PhysicalMemory,
secure_applet_memory_size));
// This memory seems to be reserved on hardware, but is not reserved/used by yuzu.
// Likely Horizon OS reserved memory
// TODO(ameerj): Derive the memory rather than hardcode it.
constexpr u64 unknown_reserved_memory{0x2f896000};
ASSERT(system_resource_limit->Reserve(LimitableResource::PhysicalMemory,
unknown_reserved_memory));
}
void InitializePreemption(KernelCore& kernel) {
@@ -541,7 +531,11 @@ struct KernelCore::Impl {
linear_region_start);
}
void InitializeMemoryLayout(const KMemoryLayout& memory_layout) {
void InitializeMemoryLayout() {
// Derive the initial memory layout from the emulated board
KMemoryLayout memory_layout;
DeriveInitialMemoryLayout(memory_layout);
const auto system_pool = memory_layout.GetKernelSystemPoolRegionPhysicalExtents();
const auto applet_pool = memory_layout.GetKernelAppletPoolRegionPhysicalExtents();
const auto application_pool = memory_layout.GetKernelApplicationPoolRegionPhysicalExtents();
@@ -584,14 +578,11 @@ struct KernelCore::Impl {
system.Kernel(), system.DeviceMemory(), nullptr, {time_phys_addr, time_size / PageSize},
KMemoryPermission::None, KMemoryPermission::Read, time_phys_addr, time_size,
"Time:SharedMemory");
}
void InitializeSlabHeaps() {
// Allocate slab heaps
user_slab_heap_pages = std::make_unique<KSlabHeap<Page>>();
// TODO(ameerj): This should be derived, not hardcoded within the kernel
constexpr u64 user_slab_heap_size{0x3de000};
constexpr u64 user_slab_heap_size{0x1ef000};
// Reserve slab heaps
ASSERT(
system_resource_limit->Reserve(LimitableResource::PhysicalMemory, user_slab_heap_size));

View File

@@ -120,7 +120,9 @@ std::shared_ptr<Process> Process::Create(Core::System& system, std::string name,
std::shared_ptr<Process> process = std::make_shared<Process>(system);
process->name = std::move(name);
process->resource_limit = kernel.GetSystemResourceLimit();
// TODO: This is inaccurate
// The process should hold a reference to the kernel-wide resource limit.
process->resource_limit = std::make_shared<KResourceLimit>(kernel, system);
process->status = ProcessStatus::Created;
process->program_id = 0;
process->process_id = type == ProcessType::KernelInternal ? kernel.CreateNewKernelProcessID()
@@ -158,6 +160,9 @@ void Process::DecrementThreadCount() {
}
u64 Process::GetTotalPhysicalMemoryAvailable() const {
// TODO: This is expected to always return the application memory pool size after accurately
// reserving kernel resources. The current workaround uses a process-local resource limit of
// application memory pool size, which is inaccurate.
const u64 capacity{resource_limit->GetFreeValue(LimitableResource::PhysicalMemory) +
page_table->GetTotalHeapSize() + GetSystemResourceSize() + image_size +
main_thread_stack_size};
@@ -165,6 +170,7 @@ u64 Process::GetTotalPhysicalMemoryAvailable() const {
if (capacity < memory_usage_capacity) {
return capacity;
}
return memory_usage_capacity;
}
@@ -266,6 +272,10 @@ ResultCode Process::LoadFromMetadata(const FileSys::ProgramMetadata& metadata,
system_resource_size = metadata.GetSystemResourceSize();
image_size = code_size;
// Set initial resource limits
resource_limit->SetLimitValue(
LimitableResource::PhysicalMemory,
kernel.MemoryManager().GetSize(KMemoryManager::Pool::Application));
KScopedResourceReservation memory_reservation(resource_limit, LimitableResource::PhysicalMemory,
code_size + system_resource_size);
if (!memory_reservation.Succeeded()) {
@@ -314,6 +324,16 @@ ResultCode Process::LoadFromMetadata(const FileSys::ProgramMetadata& metadata,
UNREACHABLE();
}
// Set initial resource limits
resource_limit->SetLimitValue(
LimitableResource::PhysicalMemory,
kernel.MemoryManager().GetSize(KMemoryManager::Pool::Application));
resource_limit->SetLimitValue(LimitableResource::Threads, 608);
resource_limit->SetLimitValue(LimitableResource::Events, 700);
resource_limit->SetLimitValue(LimitableResource::TransferMemory, 128);
resource_limit->SetLimitValue(LimitableResource::Sessions, 894);
// Create TLS region
tls_region_address = CreateTLSRegion();
memory_reservation.Commit();

View File

@@ -971,7 +971,7 @@ private:
auto storage = applet->GetBroker().PopNormalDataToGame();
if (storage == nullptr) {
LOG_DEBUG(Service_AM,
LOG_ERROR(Service_AM,
"storage is a nullptr. There is no data in the current normal channel");
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ERR_NO_DATA_IN_CHANNEL);
@@ -1002,7 +1002,7 @@ private:
auto storage = applet->GetBroker().PopInteractiveDataToGame();
if (storage == nullptr) {
LOG_DEBUG(Service_AM,
LOG_ERROR(Service_AM,
"storage is a nullptr. There is no data in the current interactive channel");
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ERR_NO_DATA_IN_CHANNEL);
@@ -1125,7 +1125,7 @@ ILibraryAppletCreator::ILibraryAppletCreator(Core::System& system_)
{2, nullptr, "AreAnyLibraryAppletsLeft"},
{10, &ILibraryAppletCreator::CreateStorage, "CreateStorage"},
{11, &ILibraryAppletCreator::CreateTransferMemoryStorage, "CreateTransferMemoryStorage"},
{12, &ILibraryAppletCreator::CreateHandleStorage, "CreateHandleStorage"},
{12, nullptr, "CreateHandleStorage"},
};
RegisterHandlers(functions);
}
@@ -1134,15 +1134,14 @@ ILibraryAppletCreator::~ILibraryAppletCreator() = default;
void ILibraryAppletCreator::CreateLibraryApplet(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto applet_id = rp.PopRaw<Applets::AppletId>();
const auto applet_mode = rp.PopRaw<Applets::LibraryAppletMode>();
const auto applet_mode = rp.PopRaw<u32>();
LOG_DEBUG(Service_AM, "called with applet_id={:08X}, applet_mode={:08X}", applet_id,
applet_mode);
const auto& applet_manager{system.GetAppletManager()};
const auto applet = applet_manager.GetApplet(applet_id, applet_mode);
const auto applet = applet_manager.GetApplet(applet_id);
if (applet == nullptr) {
LOG_ERROR(Service_AM, "Applet doesn't exist! applet_id={}", applet_id);
@@ -1160,18 +1159,9 @@ void ILibraryAppletCreator::CreateLibraryApplet(Kernel::HLERequestContext& ctx)
void ILibraryAppletCreator::CreateStorage(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const s64 size{rp.Pop<s64>()};
const u64 size{rp.Pop<u64>()};
LOG_DEBUG(Service_AM, "called, size={}", size);
if (size <= 0) {
LOG_ERROR(Service_AM, "size is less than or equal to 0");
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_UNKNOWN);
return;
}
std::vector<u8> buffer(size);
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
@@ -1180,65 +1170,18 @@ void ILibraryAppletCreator::CreateStorage(Kernel::HLERequestContext& ctx) {
}
void ILibraryAppletCreator::CreateTransferMemoryStorage(Kernel::HLERequestContext& ctx) {
LOG_DEBUG(Service_AM, "called");
IPC::RequestParser rp{ctx};
struct Parameters {
u8 permissions;
s64 size;
};
const auto parameters{rp.PopRaw<Parameters>()};
const auto handle{ctx.GetCopyHandle(0)};
LOG_DEBUG(Service_AM, "called, permissions={}, size={}, handle={:08X}", parameters.permissions,
parameters.size, handle);
if (parameters.size <= 0) {
LOG_ERROR(Service_AM, "size is less than or equal to 0");
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_UNKNOWN);
return;
}
rp.SetCurrentOffset(3);
const auto handle{rp.Pop<Kernel::Handle>()};
auto transfer_mem =
system.CurrentProcess()->GetHandleTable().Get<Kernel::TransferMemory>(handle);
if (transfer_mem == nullptr) {
LOG_ERROR(Service_AM, "transfer_mem is a nullptr for handle={:08X}", handle);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_UNKNOWN);
return;
}
const u8* const mem_begin = transfer_mem->GetPointer();
const u8* const mem_end = mem_begin + transfer_mem->GetSize();
std::vector<u8> memory{mem_begin, mem_end};
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
rb.PushIpcInterface<IStorage>(system, std::move(memory));
}
void ILibraryAppletCreator::CreateHandleStorage(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const s64 size{rp.Pop<s64>()};
const auto handle{ctx.GetCopyHandle(0)};
LOG_DEBUG(Service_AM, "called, size={}, handle={:08X}", size, handle);
if (size <= 0) {
LOG_ERROR(Service_AM, "size is less than or equal to 0");
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_UNKNOWN);
return;
}
auto transfer_mem =
system.CurrentProcess()->GetHandleTable().Get<Kernel::TransferMemory>(handle);
if (transfer_mem == nullptr) {
LOG_ERROR(Service_AM, "transfer_mem is a nullptr for handle={:08X}", handle);
LOG_ERROR(Service_AM, "shared_mem is a nullpr for handle={:08X}", handle);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_UNKNOWN);
return;

View File

@@ -254,7 +254,6 @@ private:
void CreateLibraryApplet(Kernel::HLERequestContext& ctx);
void CreateStorage(Kernel::HLERequestContext& ctx);
void CreateTransferMemoryStorage(Kernel::HLERequestContext& ctx);
void CreateHandleStorage(Kernel::HLERequestContext& ctx);
};
class IApplicationFunctions final : public ServiceFramework<IApplicationFunctions> {

View File

@@ -241,31 +241,31 @@ void AppletManager::ClearAll() {
frontend = {};
}
std::shared_ptr<Applet> AppletManager::GetApplet(AppletId id, LibraryAppletMode mode) const {
std::shared_ptr<Applet> AppletManager::GetApplet(AppletId id) const {
switch (id) {
case AppletId::Auth:
return std::make_shared<Auth>(system, mode, *frontend.parental_controls);
return std::make_shared<Auth>(system, *frontend.parental_controls);
case AppletId::Controller:
return std::make_shared<Controller>(system, mode, *frontend.controller);
return std::make_shared<Controller>(system, *frontend.controller);
case AppletId::Error:
return std::make_shared<Error>(system, mode, *frontend.error);
return std::make_shared<Error>(system, *frontend.error);
case AppletId::ProfileSelect:
return std::make_shared<ProfileSelect>(system, mode, *frontend.profile_select);
return std::make_shared<ProfileSelect>(system, *frontend.profile_select);
case AppletId::SoftwareKeyboard:
return std::make_shared<SoftwareKeyboard>(system, mode, *frontend.software_keyboard);
return std::make_shared<SoftwareKeyboard>(system, *frontend.software_keyboard);
case AppletId::Web:
case AppletId::Shop:
case AppletId::OfflineWeb:
case AppletId::LoginShare:
case AppletId::WebAuth:
return std::make_shared<WebBrowser>(system, mode, *frontend.web_browser);
return std::make_shared<WebBrowser>(system, *frontend.web_browser);
case AppletId::PhotoViewer:
return std::make_shared<PhotoViewer>(system, mode, *frontend.photo_viewer);
return std::make_shared<PhotoViewer>(system, *frontend.photo_viewer);
default:
UNIMPLEMENTED_MSG(
"No backend implementation exists for applet_id={:02X}! Falling back to stub applet.",
static_cast<u8>(id));
return std::make_shared<StubApplet>(system, id, mode);
return std::make_shared<StubApplet>(system, id);
}
}

View File

@@ -62,14 +62,6 @@ enum class AppletId : u32 {
MyPage = 0x1A,
};
enum class LibraryAppletMode : u32 {
AllForeground = 0,
Background = 1,
NoUI = 2,
BackgroundIndirectDisplay = 3,
AllForegroundInitiallyHidden = 4,
};
class AppletDataBroker final {
public:
explicit AppletDataBroker(Kernel::KernelCore& kernel_);
@@ -208,7 +200,7 @@ public:
void SetDefaultAppletsIfMissing();
void ClearAll();
std::shared_ptr<Applet> GetApplet(AppletId id, LibraryAppletMode mode) const;
std::shared_ptr<Applet> GetApplet(AppletId id) const;
private:
AppletFrontendSet frontend;

View File

@@ -45,9 +45,8 @@ static Core::Frontend::ControllerParameters ConvertToFrontendParameters(
};
}
Controller::Controller(Core::System& system_, LibraryAppletMode applet_mode_,
const Core::Frontend::ControllerApplet& frontend_)
: Applet{system_.Kernel()}, applet_mode{applet_mode_}, frontend{frontend_}, system{system_} {}
Controller::Controller(Core::System& system_, const Core::Frontend::ControllerApplet& frontend_)
: Applet{system_.Kernel()}, frontend{frontend_}, system{system_} {}
Controller::~Controller() = default;

View File

@@ -106,8 +106,7 @@ static_assert(sizeof(ControllerSupportResultInfo) == 0xC,
class Controller final : public Applet {
public:
explicit Controller(Core::System& system_, LibraryAppletMode applet_mode_,
const Core::Frontend::ControllerApplet& frontend_);
explicit Controller(Core::System& system_, const Core::Frontend::ControllerApplet& frontend_);
~Controller() override;
void Initialize() override;
@@ -120,7 +119,6 @@ public:
void ConfigurationComplete();
private:
LibraryAppletMode applet_mode;
const Core::Frontend::ControllerApplet& frontend;
Core::System& system;

View File

@@ -86,9 +86,8 @@ ResultCode Decode64BitError(u64 error) {
} // Anonymous namespace
Error::Error(Core::System& system_, LibraryAppletMode applet_mode_,
const Core::Frontend::ErrorApplet& frontend_)
: Applet{system_.Kernel()}, applet_mode{applet_mode_}, frontend{frontend_}, system{system_} {}
Error::Error(Core::System& system_, const Core::Frontend::ErrorApplet& frontend_)
: Applet{system_.Kernel()}, frontend{frontend_}, system{system_} {}
Error::~Error() = default;

View File

@@ -25,8 +25,7 @@ enum class ErrorAppletMode : u8 {
class Error final : public Applet {
public:
explicit Error(Core::System& system_, LibraryAppletMode applet_mode_,
const Core::Frontend::ErrorApplet& frontend_);
explicit Error(Core::System& system_, const Core::Frontend::ErrorApplet& frontend_);
~Error() override;
void Initialize() override;
@@ -41,7 +40,6 @@ public:
private:
union ErrorArguments;
LibraryAppletMode applet_mode;
const Core::Frontend::ErrorApplet& frontend;
ResultCode error_code = RESULT_SUCCESS;
ErrorAppletMode mode = ErrorAppletMode::ShowError;

View File

@@ -37,9 +37,8 @@ static void LogCurrentStorage(AppletDataBroker& broker, std::string_view prefix)
}
}
Auth::Auth(Core::System& system_, LibraryAppletMode applet_mode_,
Core::Frontend::ParentalControlsApplet& frontend_)
: Applet{system_.Kernel()}, applet_mode{applet_mode_}, frontend{frontend_}, system{system_} {}
Auth::Auth(Core::System& system_, Core::Frontend::ParentalControlsApplet& frontend_)
: Applet{system_.Kernel()}, frontend{frontend_}, system{system_} {}
Auth::~Auth() = default;
@@ -153,9 +152,8 @@ void Auth::AuthFinished(bool is_successful) {
broker.SignalStateChanged();
}
PhotoViewer::PhotoViewer(Core::System& system_, LibraryAppletMode applet_mode_,
const Core::Frontend::PhotoViewerApplet& frontend_)
: Applet{system_.Kernel()}, applet_mode{applet_mode_}, frontend{frontend_}, system{system_} {}
PhotoViewer::PhotoViewer(Core::System& system_, const Core::Frontend::PhotoViewerApplet& frontend_)
: Applet{system_.Kernel()}, frontend{frontend_}, system{system_} {}
PhotoViewer::~PhotoViewer() = default;
@@ -204,8 +202,8 @@ void PhotoViewer::ViewFinished() {
broker.SignalStateChanged();
}
StubApplet::StubApplet(Core::System& system_, AppletId id_, LibraryAppletMode applet_mode_)
: Applet{system_.Kernel()}, id{id_}, applet_mode{applet_mode_}, system{system_} {}
StubApplet::StubApplet(Core::System& system_, AppletId id_)
: Applet{system_.Kernel()}, id{id_}, system{system_} {}
StubApplet::~StubApplet() = default;

View File

@@ -20,8 +20,7 @@ enum class AuthAppletType : u32 {
class Auth final : public Applet {
public:
explicit Auth(Core::System& system_, LibraryAppletMode applet_mode_,
Core::Frontend::ParentalControlsApplet& frontend_);
explicit Auth(Core::System& system_, Core::Frontend::ParentalControlsApplet& frontend_);
~Auth() override;
void Initialize() override;
@@ -33,7 +32,6 @@ public:
void AuthFinished(bool is_successful = true);
private:
LibraryAppletMode applet_mode;
Core::Frontend::ParentalControlsApplet& frontend;
Core::System& system;
bool complete = false;
@@ -52,8 +50,7 @@ enum class PhotoViewerAppletMode : u8 {
class PhotoViewer final : public Applet {
public:
explicit PhotoViewer(Core::System& system_, LibraryAppletMode applet_mode_,
const Core::Frontend::PhotoViewerApplet& frontend_);
explicit PhotoViewer(Core::System& system_, const Core::Frontend::PhotoViewerApplet& frontend_);
~PhotoViewer() override;
void Initialize() override;
@@ -65,7 +62,6 @@ public:
void ViewFinished();
private:
LibraryAppletMode applet_mode;
const Core::Frontend::PhotoViewerApplet& frontend;
bool complete = false;
PhotoViewerAppletMode mode = PhotoViewerAppletMode::CurrentApp;
@@ -74,7 +70,7 @@ private:
class StubApplet final : public Applet {
public:
explicit StubApplet(Core::System& system_, AppletId id_, LibraryAppletMode applet_mode_);
explicit StubApplet(Core::System& system_, AppletId id_);
~StubApplet() override;
void Initialize() override;
@@ -86,7 +82,6 @@ public:
private:
AppletId id;
LibraryAppletMode applet_mode;
Core::System& system;
};

View File

@@ -15,9 +15,9 @@ namespace Service::AM::Applets {
constexpr ResultCode ERR_USER_CANCELLED_SELECTION{ErrorModule::Account, 1};
ProfileSelect::ProfileSelect(Core::System& system_, LibraryAppletMode applet_mode_,
ProfileSelect::ProfileSelect(Core::System& system_,
const Core::Frontend::ProfileSelectApplet& frontend_)
: Applet{system_.Kernel()}, applet_mode{applet_mode_}, frontend{frontend_}, system{system_} {}
: Applet{system_.Kernel()}, frontend{frontend_}, system{system_} {}
ProfileSelect::~ProfileSelect() = default;

View File

@@ -33,7 +33,7 @@ static_assert(sizeof(UserSelectionOutput) == 0x18, "UserSelectionOutput has inco
class ProfileSelect final : public Applet {
public:
explicit ProfileSelect(Core::System& system_, LibraryAppletMode applet_mode_,
explicit ProfileSelect(Core::System& system_,
const Core::Frontend::ProfileSelectApplet& frontend_);
~ProfileSelect() override;
@@ -47,7 +47,6 @@ public:
void SelectionComplete(std::optional<Common::UUID> uuid);
private:
LibraryAppletMode applet_mode;
const Core::Frontend::ProfileSelectApplet& frontend;
UserSelectionConfig config;

File diff suppressed because it is too large Load Diff

View File

@@ -1,14 +1,20 @@
// Copyright 2021 yuzu Emulator Project
// Copyright 2018 yuzu emulator team
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#pragma once
#include <array>
#include <string>
#include <vector>
#include "common/common_funcs.h"
#include "common/common_types.h"
#include "core/hle/result.h"
#include "common/swap.h"
#include "core/hle/service/am/am.h"
#include "core/hle/service/am/applets/applets.h"
#include "core/hle/service/am/applets/software_keyboard_types.h"
union ResultCode;
namespace Core {
class System;
@@ -16,10 +22,45 @@ class System;
namespace Service::AM::Applets {
enum class KeysetDisable : u32 {
Space = 0x02,
Address = 0x04,
Percent = 0x08,
Slashes = 0x10,
Numbers = 0x40,
DownloadCode = 0x80,
};
struct KeyboardConfig {
INSERT_PADDING_BYTES(4);
std::array<char16_t, 9> submit_text;
u16_le left_symbol_key;
u16_le right_symbol_key;
INSERT_PADDING_BYTES(1);
KeysetDisable keyset_disable_bitmask;
u32_le initial_cursor_position;
std::array<char16_t, 65> header_text;
std::array<char16_t, 129> sub_text;
std::array<char16_t, 257> guide_text;
u32_le length_limit;
INSERT_PADDING_BYTES(4);
u32_le is_password;
INSERT_PADDING_BYTES(5);
bool utf_8;
bool draw_background;
u32_le initial_string_offset;
u32_le initial_string_size;
u32_le user_dictionary_offset;
u32_le user_dictionary_size;
bool text_check;
u64_le text_check_callback;
};
static_assert(sizeof(KeyboardConfig) == 0x3E0, "KeyboardConfig has incorrect size.");
class SoftwareKeyboard final : public Applet {
public:
explicit SoftwareKeyboard(Core::System& system_, LibraryAppletMode applet_mode_,
Core::Frontend::SoftwareKeyboardApplet& frontend_);
explicit SoftwareKeyboard(Core::System& system_,
const Core::Frontend::SoftwareKeyboardApplet& frontend_);
~SoftwareKeyboard() override;
void Initialize() override;
@@ -29,139 +70,17 @@ public:
void ExecuteInteractive() override;
void Execute() override;
/**
* Submits the input text to the application.
* If text checking is enabled, the application will verify the input text.
* If use_utf8 is enabled, the input text will be converted to UTF-8 prior to being submitted.
* This should only be used by the normal software keyboard.
*
* @param result SwkbdResult enum
* @param submitted_text UTF-16 encoded string
*/
void SubmitTextNormal(SwkbdResult result, std::u16string submitted_text);
/**
* Submits the input text to the application.
* If utf8_mode is enabled, the input text will be converted to UTF-8 prior to being submitted.
* This should only be used by the inline software keyboard.
*
* @param reply_type SwkbdReplyType enum
* @param submitted_text UTF-16 encoded string
* @param cursor_position The current position of the text cursor
*/
void SubmitTextInline(SwkbdReplyType reply_type, std::u16string submitted_text,
s32 cursor_position);
void WriteText(std::optional<std::u16string> text);
private:
/// Initializes the normal software keyboard.
void InitializeForeground();
const Core::Frontend::SoftwareKeyboardApplet& frontend;
/// Initializes the inline software keyboard.
void InitializeBackground(LibraryAppletMode applet_mode);
/// Processes the text check sent by the application.
void ProcessTextCheck();
/// Processes the inline software keyboard request command sent by the application.
void ProcessInlineKeyboardRequest();
/// Submits the input text and exits the applet.
void SubmitNormalOutputAndExit(SwkbdResult result, std::u16string submitted_text);
/// Submits the input text for text checking.
void SubmitForTextCheck(std::u16string submitted_text);
/// Sends a reply to the application after processing a request command.
void SendReply(SwkbdReplyType reply_type);
/// Changes the inline keyboard state.
void ChangeState(SwkbdState state);
/**
* Signals the frontend to initialize the software keyboard with common parameters.
* This initializes either the normal software keyboard or the inline software keyboard
* depending on the state of is_background.
* Note that this does not cause the keyboard to appear.
* Use the respective Show*Keyboard() functions to cause the respective keyboards to appear.
*/
void InitializeFrontendKeyboard();
/// Signals the frontend to show the normal software keyboard.
void ShowNormalKeyboard();
/// Signals the frontend to show the text check dialog.
void ShowTextCheckDialog(SwkbdTextCheckResult text_check_result,
std::u16string text_check_message);
/// Signals the frontend to show the inline software keyboard.
void ShowInlineKeyboard();
/// Signals the frontend to hide the inline software keyboard.
void HideInlineKeyboard();
/// Signals the frontend that the current inline keyboard text has changed.
void InlineTextChanged();
/// Signals both the frontend and application that the software keyboard is exiting.
void ExitKeyboard();
// Inline Software Keyboard Requests
void RequestFinalize(const std::vector<u8>& request_data);
void RequestSetUserWordInfo(const std::vector<u8>& request_data);
void RequestSetCustomizeDic(const std::vector<u8>& request_data);
void RequestCalc(const std::vector<u8>& request_data);
void RequestSetCustomizedDictionaries(const std::vector<u8>& request_data);
void RequestUnsetCustomizedDictionaries(const std::vector<u8>& request_data);
void RequestSetChangedStringV2Flag(const std::vector<u8>& request_data);
void RequestSetMovedCursorV2Flag(const std::vector<u8>& request_data);
// Inline Software Keyboard Replies
void ReplyFinishedInitialize();
void ReplyDefault();
void ReplyChangedString();
void ReplyMovedCursor();
void ReplyMovedTab();
void ReplyDecidedEnter();
void ReplyDecidedCancel();
void ReplyChangedStringUtf8();
void ReplyMovedCursorUtf8();
void ReplyDecidedEnterUtf8();
void ReplyUnsetCustomizeDic();
void ReplyReleasedUserWordInfo();
void ReplyUnsetCustomizedDictionaries();
void ReplyChangedStringV2();
void ReplyMovedCursorV2();
void ReplyChangedStringUtf8V2();
void ReplyMovedCursorUtf8V2();
LibraryAppletMode applet_mode;
Core::Frontend::SoftwareKeyboardApplet& frontend;
Core::System& system;
SwkbdAppletVersion swkbd_applet_version;
SwkbdConfigCommon swkbd_config_common;
SwkbdConfigOld swkbd_config_old;
SwkbdConfigOld2 swkbd_config_old2;
SwkbdConfigNew swkbd_config_new;
KeyboardConfig config;
std::u16string initial_text;
SwkbdState swkbd_state{SwkbdState::NotInitialized};
SwkbdInitializeArg swkbd_initialize_arg;
SwkbdCalcArg swkbd_calc_arg;
bool use_changed_string_v2{false};
bool use_moved_cursor_v2{false};
bool inline_use_utf8{false};
s32 current_cursor_position{};
std::u16string current_text;
bool is_background{false};
bool complete{false};
ResultCode status{RESULT_SUCCESS};
bool complete = false;
bool is_inline = false;
std::vector<u8> final_data;
Core::System& system;
};
} // namespace Service::AM::Applets

View File

@@ -208,9 +208,8 @@ void ExtractSharedFonts(Core::System& system) {
} // namespace
WebBrowser::WebBrowser(Core::System& system_, LibraryAppletMode applet_mode_,
const Core::Frontend::WebBrowserApplet& frontend_)
: Applet{system_.Kernel()}, applet_mode{applet_mode_}, frontend(frontend_), system{system_} {}
WebBrowser::WebBrowser(Core::System& system_, const Core::Frontend::WebBrowserApplet& frontend_)
: Applet{system_.Kernel()}, frontend(frontend_), system{system_} {}
WebBrowser::~WebBrowser() = default;

View File

@@ -25,8 +25,7 @@ namespace Service::AM::Applets {
class WebBrowser final : public Applet {
public:
WebBrowser(Core::System& system_, LibraryAppletMode applet_mode_,
const Core::Frontend::WebBrowserApplet& frontend_);
WebBrowser(Core::System& system_, const Core::Frontend::WebBrowserApplet& frontend_);
~WebBrowser() override;
@@ -64,7 +63,6 @@ private:
void ExecuteWifi();
void ExecuteLobby();
LibraryAppletMode applet_mode;
const Core::Frontend::WebBrowserApplet& frontend;
bool complete{false};

View File

@@ -36,7 +36,6 @@ NvResult nvhost_nvdec::Ioctl1(DeviceFD fd, Ioctl command, const std::vector<u8>&
LOG_INFO(Service_NVDRV, "NVDEC video stream ended");
Tegra::ChCommandHeaderList cmdlist{{0xDEADB33F}};
system.GPU().PushCommandBuffer(cmdlist);
system.GPU().MemoryManager().InvalidateQueuedCaches();
}
return UnmapBuffer(input, output);
}

View File

@@ -198,13 +198,7 @@ NvResult nvhost_nvdec_common::UnmapBuffer(const std::vector<u8>& input, std::vec
return NvResult::InvalidState;
}
if (const auto size{RemoveBufferMap(object->dma_map_addr)}; size) {
if (vic_device) {
// UnmapVicFrame defers texture_cache invalidation of the frame address until
// the stream is over
gpu.MemoryManager().UnmapVicFrame(object->dma_map_addr, *size);
} else {
gpu.MemoryManager().Unmap(object->dma_map_addr, *size);
}
gpu.MemoryManager().Unmap(object->dma_map_addr, *size);
} else {
// This occurs quite frequently, however does not seem to impact functionality
LOG_DEBUG(Service_NVDRV, "invalid offset=0x{:X} dma=0x{:X}", object->addr,

View File

@@ -160,7 +160,6 @@ protected:
s32_le nvmap_fd{};
u32_le submit_timeout{};
bool vic_device{};
std::shared_ptr<nvmap> nvmap_dev;
SyncpointManager& syncpoint_manager;
std::array<u32, MaxSyncPoints> device_syncpoints{};

View File

@@ -12,9 +12,8 @@
namespace Service::Nvidia::Devices {
nvhost_vic::nvhost_vic(Core::System& system, std::shared_ptr<nvmap> nvmap_dev,
SyncpointManager& syncpoint_manager)
: nvhost_nvdec_common(system, std::move(nvmap_dev), syncpoint_manager) {
vic_device = true;
}
: nvhost_nvdec_common(system, std::move(nvmap_dev), syncpoint_manager) {}
nvhost_vic::~nvhost_vic() = default;
NvResult nvhost_vic::Ioctl1(DeviceFD fd, Ioctl command, const std::vector<u8>& input,