early-access version 4172
This commit is contained in:
parent
3f175c996a
commit
09fb494463
62 changed files with 1685 additions and 2543 deletions
|
@ -1,7 +1,7 @@
|
||||||
yuzu emulator early access
|
yuzu emulator early access
|
||||||
=============
|
=============
|
||||||
|
|
||||||
This is the source code for early-access 4171.
|
This is the source code for early-access 4172.
|
||||||
|
|
||||||
## Legal Notice
|
## Legal Notice
|
||||||
|
|
||||||
|
|
|
@ -401,16 +401,14 @@ add_library(core STATIC
|
||||||
hle/service/am/am_types.h
|
hle/service/am/am_types.h
|
||||||
hle/service/am/applet.cpp
|
hle/service/am/applet.cpp
|
||||||
hle/service/am/applet.h
|
hle/service/am/applet.h
|
||||||
hle/service/am/applet_manager.cpp
|
|
||||||
hle/service/am/applet_data_broker.cpp
|
hle/service/am/applet_data_broker.cpp
|
||||||
hle/service/am/applet_data_broker.h
|
hle/service/am/applet_data_broker.h
|
||||||
|
hle/service/am/applet_manager.cpp
|
||||||
hle/service/am/applet_manager.h
|
hle/service/am/applet_manager.h
|
||||||
hle/service/am/button_poller.cpp
|
hle/service/am/applet_message_queue.cpp
|
||||||
hle/service/am/button_poller.h
|
hle/service/am/applet_message_queue.h
|
||||||
hle/service/am/display_layer_manager.cpp
|
hle/service/am/display_layer_manager.cpp
|
||||||
hle/service/am/display_layer_manager.h
|
hle/service/am/display_layer_manager.h
|
||||||
hle/service/am/event_observer.cpp
|
|
||||||
hle/service/am/event_observer.h
|
|
||||||
hle/service/am/frontend/applet_cabinet.cpp
|
hle/service/am/frontend/applet_cabinet.cpp
|
||||||
hle/service/am/frontend/applet_cabinet.h
|
hle/service/am/frontend/applet_cabinet.h
|
||||||
hle/service/am/frontend/applet_controller.cpp
|
hle/service/am/frontend/applet_controller.cpp
|
||||||
|
@ -436,12 +434,8 @@ add_library(core STATIC
|
||||||
hle/service/am/hid_registration.h
|
hle/service/am/hid_registration.h
|
||||||
hle/service/am/library_applet_storage.cpp
|
hle/service/am/library_applet_storage.cpp
|
||||||
hle/service/am/library_applet_storage.h
|
hle/service/am/library_applet_storage.h
|
||||||
hle/service/am/lifecycle_manager.cpp
|
hle/service/am/process.cpp
|
||||||
hle/service/am/lifecycle_manager.h
|
hle/service/am/process.h
|
||||||
hle/service/am/process_creation.cpp
|
|
||||||
hle/service/am/process_creation.h
|
|
||||||
hle/service/am/process_holder.cpp
|
|
||||||
hle/service/am/process_holder.h
|
|
||||||
hle/service/am/service/all_system_applet_proxies_service.cpp
|
hle/service/am/service/all_system_applet_proxies_service.cpp
|
||||||
hle/service/am/service/all_system_applet_proxies_service.h
|
hle/service/am/service/all_system_applet_proxies_service.h
|
||||||
hle/service/am/service/applet_common_functions.cpp
|
hle/service/am/service/applet_common_functions.cpp
|
||||||
|
@ -492,8 +486,6 @@ add_library(core STATIC
|
||||||
hle/service/am/service/system_applet_proxy.h
|
hle/service/am/service/system_applet_proxy.h
|
||||||
hle/service/am/service/window_controller.cpp
|
hle/service/am/service/window_controller.cpp
|
||||||
hle/service/am/service/window_controller.h
|
hle/service/am/service/window_controller.h
|
||||||
hle/service/am/window_system.cpp
|
|
||||||
hle/service/am/window_system.h
|
|
||||||
hle/service/aoc/addon_content_manager.cpp
|
hle/service/aoc/addon_content_manager.cpp
|
||||||
hle/service/aoc/addon_content_manager.h
|
hle/service/aoc/addon_content_manager.h
|
||||||
hle/service/aoc/purchase_event_manager.cpp
|
hle/service/aoc/purchase_event_manager.cpp
|
||||||
|
@ -676,6 +668,10 @@ add_library(core STATIC
|
||||||
hle/service/glue/time/worker.h
|
hle/service/glue/time/worker.h
|
||||||
hle/service/grc/grc.cpp
|
hle/service/grc/grc.cpp
|
||||||
hle/service/grc/grc.h
|
hle/service/grc/grc.h
|
||||||
|
hle/service/hid/active_vibration_device_list.cpp
|
||||||
|
hle/service/hid/active_vibration_device_list.h
|
||||||
|
hle/service/hid/applet_resource.cpp
|
||||||
|
hle/service/hid/applet_resource.h
|
||||||
hle/service/hid/hid.cpp
|
hle/service/hid/hid.cpp
|
||||||
hle/service/hid/hid.h
|
hle/service/hid/hid.h
|
||||||
hle/service/hid/hid_debug_server.cpp
|
hle/service/hid/hid_debug_server.cpp
|
||||||
|
@ -922,8 +918,6 @@ add_library(core STATIC
|
||||||
hle/service/os/multi_wait_utils.h
|
hle/service/os/multi_wait_utils.h
|
||||||
hle/service/os/mutex.cpp
|
hle/service/os/mutex.cpp
|
||||||
hle/service/os/mutex.h
|
hle/service/os/mutex.h
|
||||||
hle/service/os/process.cpp
|
|
||||||
hle/service/os/process.h
|
|
||||||
hle/service/pcie/pcie.cpp
|
hle/service/pcie/pcie.cpp
|
||||||
hle/service/pcie/pcie.h
|
hle/service/pcie/pcie.h
|
||||||
hle/service/pctl/parental_control_service_factory.cpp
|
hle/service/pctl/parental_control_service_factory.cpp
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
|
#include <exception>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
|
@ -19,6 +20,7 @@
|
||||||
#include "core/cpu_manager.h"
|
#include "core/cpu_manager.h"
|
||||||
#include "core/debugger/debugger.h"
|
#include "core/debugger/debugger.h"
|
||||||
#include "core/device_memory.h"
|
#include "core/device_memory.h"
|
||||||
|
#include "core/file_sys/bis_factory.h"
|
||||||
#include "core/file_sys/fs_filesystem.h"
|
#include "core/file_sys/fs_filesystem.h"
|
||||||
#include "core/file_sys/patch_manager.h"
|
#include "core/file_sys/patch_manager.h"
|
||||||
#include "core/file_sys/registered_cache.h"
|
#include "core/file_sys/registered_cache.h"
|
||||||
|
@ -36,7 +38,6 @@
|
||||||
#include "core/hle/service/acc/profile_manager.h"
|
#include "core/hle/service/acc/profile_manager.h"
|
||||||
#include "core/hle/service/am/applet_manager.h"
|
#include "core/hle/service/am/applet_manager.h"
|
||||||
#include "core/hle/service/am/frontend/applets.h"
|
#include "core/hle/service/am/frontend/applets.h"
|
||||||
#include "core/hle/service/am/process_creation.h"
|
|
||||||
#include "core/hle/service/apm/apm_controller.h"
|
#include "core/hle/service/apm/apm_controller.h"
|
||||||
#include "core/hle/service/filesystem/filesystem.h"
|
#include "core/hle/service/filesystem/filesystem.h"
|
||||||
#include "core/hle/service/glue/glue_manager.h"
|
#include "core/hle/service/glue/glue_manager.h"
|
||||||
|
@ -71,6 +72,30 @@ MICROPROFILE_DEFINE(ARM_CPU3, "ARM", "CPU 3", MP_RGB(255, 64, 64));
|
||||||
|
|
||||||
namespace Core {
|
namespace Core {
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
FileSys::StorageId GetStorageIdForFrontendSlot(
|
||||||
|
std::optional<FileSys::ContentProviderUnionSlot> slot) {
|
||||||
|
if (!slot.has_value()) {
|
||||||
|
return FileSys::StorageId::None;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (*slot) {
|
||||||
|
case FileSys::ContentProviderUnionSlot::UserNAND:
|
||||||
|
return FileSys::StorageId::NandUser;
|
||||||
|
case FileSys::ContentProviderUnionSlot::SysNAND:
|
||||||
|
return FileSys::StorageId::NandSystem;
|
||||||
|
case FileSys::ContentProviderUnionSlot::SDMC:
|
||||||
|
return FileSys::StorageId::SdCard;
|
||||||
|
case FileSys::ContentProviderUnionSlot::FrontendManual:
|
||||||
|
return FileSys::StorageId::Host;
|
||||||
|
default:
|
||||||
|
return FileSys::StorageId::None;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // Anonymous namespace
|
||||||
|
|
||||||
FileSys::VirtualFile GetGameFileFromPath(const FileSys::VirtualFilesystem& vfs,
|
FileSys::VirtualFile GetGameFileFromPath(const FileSys::VirtualFilesystem& vfs,
|
||||||
const std::string& path) {
|
const std::string& path) {
|
||||||
// To account for split 00+01+etc files.
|
// To account for split 00+01+etc files.
|
||||||
|
@ -272,6 +297,9 @@ struct System::Impl {
|
||||||
}
|
}
|
||||||
|
|
||||||
SystemResultStatus SetupForApplicationProcess(System& system, Frontend::EmuWindow& emu_window) {
|
SystemResultStatus SetupForApplicationProcess(System& system, Frontend::EmuWindow& emu_window) {
|
||||||
|
/// Reset all glue registrations
|
||||||
|
arp_manager.ResetAll();
|
||||||
|
|
||||||
telemetry_session = std::make_unique<Core::TelemetrySession>();
|
telemetry_session = std::make_unique<Core::TelemetrySession>();
|
||||||
|
|
||||||
host1x_core = std::make_unique<Tegra::Host1x::Host1x>(system);
|
host1x_core = std::make_unique<Tegra::Host1x::Host1x>(system);
|
||||||
|
@ -307,32 +335,16 @@ struct System::Impl {
|
||||||
SystemResultStatus Load(System& system, Frontend::EmuWindow& emu_window,
|
SystemResultStatus Load(System& system, Frontend::EmuWindow& emu_window,
|
||||||
const std::string& filepath,
|
const std::string& filepath,
|
||||||
Service::AM::FrontendAppletParameters& params) {
|
Service::AM::FrontendAppletParameters& params) {
|
||||||
InitializeKernel(system);
|
app_loader = Loader::GetLoader(system, GetGameFileFromPath(virtual_filesystem, filepath),
|
||||||
|
|
||||||
const auto file = GetGameFileFromPath(virtual_filesystem, filepath);
|
|
||||||
|
|
||||||
// Create the application process
|
|
||||||
Loader::ResultStatus load_result{};
|
|
||||||
std::vector<u8> control;
|
|
||||||
auto process =
|
|
||||||
Service::AM::CreateApplicationProcess(control, app_loader, load_result, system, file,
|
|
||||||
params.program_id, params.program_index);
|
params.program_id, params.program_index);
|
||||||
|
|
||||||
if (load_result != Loader::ResultStatus::Success) {
|
|
||||||
LOG_CRITICAL(Core, "Failed to load ROM (Error {})!", load_result);
|
|
||||||
ShutdownMainProcess();
|
|
||||||
|
|
||||||
return static_cast<SystemResultStatus>(
|
|
||||||
static_cast<u32>(SystemResultStatus::ErrorLoader) + static_cast<u32>(load_result));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!app_loader) {
|
if (!app_loader) {
|
||||||
LOG_CRITICAL(Core, "Failed to obtain loader for {}!", filepath);
|
LOG_CRITICAL(Core, "Failed to obtain loader for {}!", filepath);
|
||||||
return SystemResultStatus::ErrorGetLoader;
|
return SystemResultStatus::ErrorGetLoader;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (app_loader->ReadProgramId(params.program_id) != Loader::ResultStatus::Success) {
|
if (app_loader->ReadProgramId(params.program_id) != Loader::ResultStatus::Success) {
|
||||||
LOG_ERROR(Core, "Failed to find program id for ROM!");
|
LOG_ERROR(Core, "Failed to find title id for ROM!");
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string name = "Unknown program";
|
std::string name = "Unknown program";
|
||||||
|
@ -340,10 +352,23 @@ struct System::Impl {
|
||||||
LOG_ERROR(Core, "Failed to read title for ROM!");
|
LOG_ERROR(Core, "Failed to read title for ROM!");
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG_INFO(Core, "Loading {} ({:016X}) ...", name, params.program_id);
|
LOG_INFO(Core, "Loading {} ({})", name, params.program_id);
|
||||||
|
|
||||||
// Make the process created be the application
|
InitializeKernel(system);
|
||||||
kernel.MakeApplicationProcess(process->GetHandle());
|
|
||||||
|
// Create the application process.
|
||||||
|
auto main_process = Kernel::KProcess::Create(system.Kernel());
|
||||||
|
Kernel::KProcess::Register(system.Kernel(), main_process);
|
||||||
|
kernel.AppendNewProcess(main_process);
|
||||||
|
kernel.MakeApplicationProcess(main_process);
|
||||||
|
const auto [load_result, load_parameters] = app_loader->Load(*main_process, system);
|
||||||
|
if (load_result != Loader::ResultStatus::Success) {
|
||||||
|
LOG_CRITICAL(Core, "Failed to load ROM (Error {})!", load_result);
|
||||||
|
ShutdownMainProcess();
|
||||||
|
|
||||||
|
return static_cast<SystemResultStatus>(
|
||||||
|
static_cast<u32>(SystemResultStatus::ErrorLoader) + static_cast<u32>(load_result));
|
||||||
|
}
|
||||||
|
|
||||||
// Set up the rest of the system.
|
// Set up the rest of the system.
|
||||||
SystemResultStatus init_result{SetupForApplicationProcess(system, emu_window)};
|
SystemResultStatus init_result{SetupForApplicationProcess(system, emu_window)};
|
||||||
|
@ -354,6 +379,7 @@ struct System::Impl {
|
||||||
return init_result;
|
return init_result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AddGlueRegistrationForProcess(*app_loader, *main_process);
|
||||||
telemetry_session->AddInitialInfo(*app_loader, fs_controller, *content_provider);
|
telemetry_session->AddInitialInfo(*app_loader, fs_controller, *content_provider);
|
||||||
|
|
||||||
// Initialize cheat engine
|
// Initialize cheat engine
|
||||||
|
@ -362,7 +388,13 @@ struct System::Impl {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Register with applet manager.
|
// Register with applet manager.
|
||||||
applet_manager.CreateAndInsertByFrontendAppletParameters(std::move(process), params);
|
applet_manager.CreateAndInsertByFrontendAppletParameters(main_process->GetProcessId(),
|
||||||
|
params);
|
||||||
|
|
||||||
|
// All threads are started, begin main process execution, now that we're in the clear.
|
||||||
|
main_process->Run(load_parameters->main_thread_priority,
|
||||||
|
load_parameters->main_thread_stack_size);
|
||||||
|
main_process->Close();
|
||||||
|
|
||||||
if (Settings::values.gamecard_inserted) {
|
if (Settings::values.gamecard_inserted) {
|
||||||
if (Settings::values.gamecard_current_game) {
|
if (Settings::values.gamecard_current_game) {
|
||||||
|
@ -434,6 +466,7 @@ struct System::Impl {
|
||||||
kernel.SuspendEmulation(true);
|
kernel.SuspendEmulation(true);
|
||||||
kernel.CloseServices();
|
kernel.CloseServices();
|
||||||
kernel.ShutdownCores();
|
kernel.ShutdownCores();
|
||||||
|
applet_manager.Reset();
|
||||||
services.reset();
|
services.reset();
|
||||||
service_manager.reset();
|
service_manager.reset();
|
||||||
fs_controller.Reset();
|
fs_controller.Reset();
|
||||||
|
@ -459,9 +492,6 @@ struct System::Impl {
|
||||||
// Workarounds
|
// Workarounds
|
||||||
Settings::values.renderer_amdvlk_depth_bias_workaround = false;
|
Settings::values.renderer_amdvlk_depth_bias_workaround = false;
|
||||||
|
|
||||||
// Reset all glue registrations
|
|
||||||
arp_manager.ResetAll();
|
|
||||||
|
|
||||||
LOG_DEBUG(Core, "Shutdown OK");
|
LOG_DEBUG(Core, "Shutdown OK");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -479,6 +509,31 @@ struct System::Impl {
|
||||||
return app_loader->ReadTitle(out);
|
return app_loader->ReadTitle(out);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AddGlueRegistrationForProcess(Loader::AppLoader& loader, Kernel::KProcess& process) {
|
||||||
|
std::vector<u8> nacp_data;
|
||||||
|
FileSys::NACP nacp;
|
||||||
|
if (loader.ReadControlData(nacp) == Loader::ResultStatus::Success) {
|
||||||
|
nacp_data = nacp.GetRawBytes();
|
||||||
|
} else {
|
||||||
|
nacp_data.resize(sizeof(FileSys::RawNACP));
|
||||||
|
}
|
||||||
|
|
||||||
|
Service::Glue::ApplicationLaunchProperty launch{};
|
||||||
|
launch.title_id = process.GetProgramId();
|
||||||
|
|
||||||
|
FileSys::PatchManager pm{launch.title_id, fs_controller, *content_provider};
|
||||||
|
launch.version = pm.GetGameVersion().value_or(0);
|
||||||
|
|
||||||
|
// TODO(DarkLordZach): When FSController/Game Card Support is added, if
|
||||||
|
// current_process_game_card use correct StorageId
|
||||||
|
launch.base_game_storage_id = GetStorageIdForFrontendSlot(content_provider->GetSlotForEntry(
|
||||||
|
launch.title_id, FileSys::ContentRecordType::Program));
|
||||||
|
launch.update_storage_id = GetStorageIdForFrontendSlot(content_provider->GetSlotForEntry(
|
||||||
|
FileSys::GetUpdateTitleID(launch.title_id), FileSys::ContentRecordType::Program));
|
||||||
|
|
||||||
|
arp_manager.Register(launch.title_id, launch, std::move(nacp_data));
|
||||||
|
}
|
||||||
|
|
||||||
void SetStatus(SystemResultStatus new_status, const char* details = nullptr) {
|
void SetStatus(SystemResultStatus new_status, const char* details = nullptr) {
|
||||||
status = new_status;
|
status = new_status;
|
||||||
if (details) {
|
if (details) {
|
||||||
|
|
|
@ -2,26 +2,19 @@
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
#include "core/hle/service/am/am.h"
|
#include "core/hle/service/am/am.h"
|
||||||
#include "core/hle/service/am/button_poller.h"
|
|
||||||
#include "core/hle/service/am/event_observer.h"
|
|
||||||
#include "core/hle/service/am/service/all_system_applet_proxies_service.h"
|
#include "core/hle/service/am/service/all_system_applet_proxies_service.h"
|
||||||
#include "core/hle/service/am/service/application_proxy_service.h"
|
#include "core/hle/service/am/service/application_proxy_service.h"
|
||||||
#include "core/hle/service/am/window_system.h"
|
|
||||||
#include "core/hle/service/server_manager.h"
|
#include "core/hle/service/server_manager.h"
|
||||||
|
|
||||||
namespace Service::AM {
|
namespace Service::AM {
|
||||||
|
|
||||||
void LoopProcess(Core::System& system) {
|
void LoopProcess(Core::System& system) {
|
||||||
WindowSystem window_system(system);
|
|
||||||
ButtonPoller button_poller(system, window_system);
|
|
||||||
EventObserver event_observer(system, window_system);
|
|
||||||
|
|
||||||
auto server_manager = std::make_unique<ServerManager>(system);
|
auto server_manager = std::make_unique<ServerManager>(system);
|
||||||
|
|
||||||
server_manager->RegisterNamedService(
|
server_manager->RegisterNamedService("appletAE",
|
||||||
"appletAE", std::make_shared<IAllSystemAppletProxiesService>(system, window_system));
|
std::make_shared<IAllSystemAppletProxiesService>(system));
|
||||||
server_manager->RegisterNamedService(
|
server_manager->RegisterNamedService("appletOE",
|
||||||
"appletOE", std::make_shared<IApplicationProxyService>(system, window_system));
|
std::make_shared<IApplicationProxyService>(system));
|
||||||
ServerManager::RunServer(std::move(server_manager));
|
ServerManager::RunServer(std::move(server_manager));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,6 @@ namespace Service::AM {
|
||||||
|
|
||||||
constexpr Result ResultNoDataInChannel{ErrorModule::AM, 2};
|
constexpr Result ResultNoDataInChannel{ErrorModule::AM, 2};
|
||||||
constexpr Result ResultNoMessages{ErrorModule::AM, 3};
|
constexpr Result ResultNoMessages{ErrorModule::AM, 3};
|
||||||
constexpr Result ResultLibraryAppletTerminated{ErrorModule::AM, 22};
|
|
||||||
constexpr Result ResultInvalidOffset{ErrorModule::AM, 503};
|
constexpr Result ResultInvalidOffset{ErrorModule::AM, 503};
|
||||||
constexpr Result ResultInvalidStorageType{ErrorModule::AM, 511};
|
constexpr Result ResultInvalidStorageType{ErrorModule::AM, 511};
|
||||||
constexpr Result ResultFatalSectionCountImbalance{ErrorModule::AM, 512};
|
constexpr Result ResultFatalSectionCountImbalance{ErrorModule::AM, 512};
|
||||||
|
|
|
@ -61,6 +61,12 @@ enum class ScreenshotPermission : u32 {
|
||||||
Disable = 2,
|
Disable = 2,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct FocusHandlingMode {
|
||||||
|
bool notify;
|
||||||
|
bool background;
|
||||||
|
bool suspend;
|
||||||
|
};
|
||||||
|
|
||||||
enum class IdleTimeDetectionExtension : u32 {
|
enum class IdleTimeDetectionExtension : u32 {
|
||||||
Disabled = 0,
|
Disabled = 0,
|
||||||
Extended = 1,
|
Extended = 1,
|
||||||
|
@ -233,6 +239,7 @@ struct ApplicationPlayStatistics {
|
||||||
static_assert(sizeof(ApplicationPlayStatistics) == 0x18,
|
static_assert(sizeof(ApplicationPlayStatistics) == 0x18,
|
||||||
"ApplicationPlayStatistics has incorrect size.");
|
"ApplicationPlayStatistics has incorrect size.");
|
||||||
|
|
||||||
|
using AppletResourceUserId = u64;
|
||||||
using ProgramId = u64;
|
using ProgramId = u64;
|
||||||
|
|
||||||
struct Applet;
|
struct Applet;
|
||||||
|
|
|
@ -1,71 +1,27 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#include "common/scope_exit.h"
|
||||||
|
|
||||||
#include "core/core.h"
|
#include "core/core.h"
|
||||||
|
#include "core/hle/service/am/am_results.h"
|
||||||
#include "core/hle/service/am/applet.h"
|
#include "core/hle/service/am/applet.h"
|
||||||
#include "core/hle/service/am/applet_manager.h"
|
#include "core/hle/service/am/applet_manager.h"
|
||||||
|
|
||||||
namespace Service::AM {
|
namespace Service::AM {
|
||||||
|
|
||||||
Applet::Applet(Core::System& system, std::unique_ptr<Process> process_, bool is_application)
|
Applet::Applet(Core::System& system, std::unique_ptr<Process> process_)
|
||||||
: context(system, "Applet"), lifecycle_manager(system, context, is_application),
|
: context(system, "Applet"), message_queue(system), process(std::move(process_)),
|
||||||
process(std::move(process_)), hid_registration(system, *process),
|
hid_registration(system, *process), gpu_error_detected_event(context),
|
||||||
gpu_error_detected_event(context), friend_invitation_storage_channel_event(context),
|
friend_invitation_storage_channel_event(context), notification_storage_channel_event(context),
|
||||||
notification_storage_channel_event(context), health_warning_disappeared_system_event(context),
|
health_warning_disappeared_system_event(context), acquired_sleep_lock_event(context),
|
||||||
acquired_sleep_lock_event(context), pop_from_general_channel_event(context),
|
pop_from_general_channel_event(context), library_applet_launchable_event(context),
|
||||||
library_applet_launchable_event(context), accumulated_suspended_tick_changed_event(context),
|
accumulated_suspended_tick_changed_event(context), sleep_lock_event(context) {
|
||||||
sleep_lock_event(context), state_changed_event(context) {
|
|
||||||
|
|
||||||
aruid.pid = process->GetProcessId();
|
aruid = process->GetProcessId();
|
||||||
program_id = process->GetProgramId();
|
program_id = process->GetProgramId();
|
||||||
}
|
}
|
||||||
|
|
||||||
Applet::~Applet() = default;
|
Applet::~Applet() = default;
|
||||||
|
|
||||||
void Applet::UpdateSuspensionStateLocked(bool force_message) {
|
|
||||||
// Remove any forced resumption.
|
|
||||||
lifecycle_manager.RemoveForceResumeIfPossible();
|
|
||||||
|
|
||||||
// Check if we're runnable.
|
|
||||||
const bool curr_activity_runnable = lifecycle_manager.IsRunnable();
|
|
||||||
const bool prev_activity_runnable = is_activity_runnable;
|
|
||||||
const bool was_changed = curr_activity_runnable != prev_activity_runnable;
|
|
||||||
|
|
||||||
if (was_changed) {
|
|
||||||
if (curr_activity_runnable) {
|
|
||||||
process->Suspend(false);
|
|
||||||
} else {
|
|
||||||
process->Suspend(true);
|
|
||||||
lifecycle_manager.RequestResumeNotification();
|
|
||||||
}
|
|
||||||
|
|
||||||
is_activity_runnable = curr_activity_runnable;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (lifecycle_manager.GetForcedSuspend()) {
|
|
||||||
// TODO: why is this allowed?
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Signal if the focus state was changed or the process state was changed.
|
|
||||||
if (lifecycle_manager.UpdateRequestedFocusState() || was_changed || force_message) {
|
|
||||||
lifecycle_manager.SignalSystemEventIfNeeded();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Applet::SetInteractibleLocked(bool interactible) {
|
|
||||||
if (is_interactible == interactible) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
is_interactible = interactible;
|
|
||||||
|
|
||||||
hid_registration.EnableAppletToGetInput(interactible && !lifecycle_manager.GetExitRequested());
|
|
||||||
}
|
|
||||||
|
|
||||||
void Applet::OnProcessTerminatedLocked() {
|
|
||||||
is_completed = true;
|
|
||||||
state_changed_event.Signal();
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace Service::AM
|
} // namespace Service::AM
|
||||||
|
|
|
@ -3,28 +3,25 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <deque>
|
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
|
||||||
#include "common/math_util.h"
|
#include "common/math_util.h"
|
||||||
#include "core/hle/service/apm/apm_controller.h"
|
#include "core/hle/service/apm/apm_controller.h"
|
||||||
#include "core/hle/service/caps/caps_types.h"
|
#include "core/hle/service/caps/caps_types.h"
|
||||||
#include "core/hle/service/cmif_types.h"
|
|
||||||
#include "core/hle/service/kernel_helpers.h"
|
#include "core/hle/service/kernel_helpers.h"
|
||||||
#include "core/hle/service/os/event.h"
|
#include "core/hle/service/os/event.h"
|
||||||
#include "core/hle/service/os/process.h"
|
|
||||||
#include "core/hle/service/service.h"
|
#include "core/hle/service/service.h"
|
||||||
|
|
||||||
#include "core/hle/service/am/am_types.h"
|
#include "core/hle/service/am/am_types.h"
|
||||||
|
#include "core/hle/service/am/applet_message_queue.h"
|
||||||
#include "core/hle/service/am/display_layer_manager.h"
|
#include "core/hle/service/am/display_layer_manager.h"
|
||||||
#include "core/hle/service/am/hid_registration.h"
|
#include "core/hle/service/am/hid_registration.h"
|
||||||
#include "core/hle/service/am/lifecycle_manager.h"
|
#include "core/hle/service/am/process.h"
|
||||||
#include "core/hle/service/am/process_holder.h"
|
|
||||||
|
|
||||||
namespace Service::AM {
|
namespace Service::AM {
|
||||||
|
|
||||||
struct Applet {
|
struct Applet {
|
||||||
explicit Applet(Core::System& system, std::unique_ptr<Process> process_, bool is_application);
|
explicit Applet(Core::System& system, std::unique_ptr<Process> process_);
|
||||||
~Applet();
|
~Applet();
|
||||||
|
|
||||||
// Lock
|
// Lock
|
||||||
|
@ -33,13 +30,11 @@ struct Applet {
|
||||||
// Event creation helper
|
// Event creation helper
|
||||||
KernelHelpers::ServiceContext context;
|
KernelHelpers::ServiceContext context;
|
||||||
|
|
||||||
// Lifecycle manager
|
// Applet message queue
|
||||||
LifecycleManager lifecycle_manager;
|
AppletMessageQueue message_queue;
|
||||||
|
|
||||||
// Process
|
// Process
|
||||||
std::unique_ptr<Process> process;
|
std::unique_ptr<Process> process;
|
||||||
std::optional<ProcessHolder> process_holder;
|
|
||||||
bool is_process_running{};
|
|
||||||
|
|
||||||
// Creation state
|
// Creation state
|
||||||
AppletId applet_id{};
|
AppletId applet_id{};
|
||||||
|
@ -80,9 +75,11 @@ struct Applet {
|
||||||
bool game_play_recording_supported{};
|
bool game_play_recording_supported{};
|
||||||
GamePlayRecordingState game_play_recording_state{GamePlayRecordingState::Disabled};
|
GamePlayRecordingState game_play_recording_state{GamePlayRecordingState::Disabled};
|
||||||
bool jit_service_launched{};
|
bool jit_service_launched{};
|
||||||
|
bool is_running{};
|
||||||
bool application_crash_report_enabled{};
|
bool application_crash_report_enabled{};
|
||||||
|
|
||||||
// Common state
|
// Common state
|
||||||
|
FocusState focus_state{};
|
||||||
bool sleep_lock_enabled{};
|
bool sleep_lock_enabled{};
|
||||||
bool vr_mode_enabled{};
|
bool vr_mode_enabled{};
|
||||||
bool lcd_backlight_off_enabled{};
|
bool lcd_backlight_off_enabled{};
|
||||||
|
@ -96,12 +93,15 @@ struct Applet {
|
||||||
// Caller applet
|
// Caller applet
|
||||||
std::weak_ptr<Applet> caller_applet{};
|
std::weak_ptr<Applet> caller_applet{};
|
||||||
std::shared_ptr<AppletDataBroker> caller_applet_broker{};
|
std::shared_ptr<AppletDataBroker> caller_applet_broker{};
|
||||||
std::list<std::shared_ptr<Applet>> child_applets{};
|
|
||||||
bool is_completed{};
|
|
||||||
|
|
||||||
// Self state
|
// Self state
|
||||||
bool exit_locked{};
|
bool exit_locked{};
|
||||||
s32 fatal_section_count{};
|
s32 fatal_section_count{};
|
||||||
|
bool operation_mode_changed_notification_enabled{true};
|
||||||
|
bool performance_mode_changed_notification_enabled{true};
|
||||||
|
FocusHandlingMode focus_handling_mode{};
|
||||||
|
bool restart_message_enabled{};
|
||||||
|
bool out_of_focus_suspension_enabled{true};
|
||||||
Capture::AlbumImageOrientation album_image_orientation{};
|
Capture::AlbumImageOrientation album_image_orientation{};
|
||||||
bool handles_request_to_display{};
|
bool handles_request_to_display{};
|
||||||
ScreenshotPermission screenshot_permission{};
|
ScreenshotPermission screenshot_permission{};
|
||||||
|
@ -110,9 +110,6 @@ struct Applet {
|
||||||
u64 suspended_ticks{};
|
u64 suspended_ticks{};
|
||||||
bool album_image_taken_notification_enabled{};
|
bool album_image_taken_notification_enabled{};
|
||||||
bool record_volume_muted{};
|
bool record_volume_muted{};
|
||||||
bool is_activity_runnable{};
|
|
||||||
bool is_interactible{true};
|
|
||||||
bool window_visible{true};
|
|
||||||
|
|
||||||
// Events
|
// Events
|
||||||
Event gpu_error_detected_event;
|
Event gpu_error_detected_event;
|
||||||
|
@ -124,15 +121,9 @@ struct Applet {
|
||||||
Event library_applet_launchable_event;
|
Event library_applet_launchable_event;
|
||||||
Event accumulated_suspended_tick_changed_event;
|
Event accumulated_suspended_tick_changed_event;
|
||||||
Event sleep_lock_event;
|
Event sleep_lock_event;
|
||||||
Event state_changed_event;
|
|
||||||
|
|
||||||
// Frontend state
|
// Frontend state
|
||||||
std::shared_ptr<Frontend::FrontendApplet> frontend{};
|
std::shared_ptr<Frontend::FrontendApplet> frontend{};
|
||||||
|
|
||||||
// Process state management
|
|
||||||
void UpdateSuspensionStateLocked(bool force_message);
|
|
||||||
void SetInteractibleLocked(bool interactible);
|
|
||||||
void OnProcessTerminatedLocked();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Service::AM
|
} // namespace Service::AM
|
||||||
|
|
|
@ -44,8 +44,24 @@ Kernel::KReadableEvent* AppletStorageChannel::GetEvent() {
|
||||||
|
|
||||||
AppletDataBroker::AppletDataBroker(Core::System& system_)
|
AppletDataBroker::AppletDataBroker(Core::System& system_)
|
||||||
: system(system_), context(system_, "AppletDataBroker"), in_data(context),
|
: system(system_), context(system_, "AppletDataBroker"), in_data(context),
|
||||||
interactive_in_data(context), out_data(context), interactive_out_data(context) {}
|
interactive_in_data(context), out_data(context), interactive_out_data(context),
|
||||||
|
state_changed_event(context), is_completed(false) {}
|
||||||
|
|
||||||
AppletDataBroker::~AppletDataBroker() = default;
|
AppletDataBroker::~AppletDataBroker() = default;
|
||||||
|
|
||||||
|
void AppletDataBroker::SignalCompletion() {
|
||||||
|
{
|
||||||
|
std::scoped_lock lk{lock};
|
||||||
|
|
||||||
|
if (is_completed) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
is_completed = true;
|
||||||
|
state_changed_event.Signal();
|
||||||
|
}
|
||||||
|
|
||||||
|
system.GetAppletManager().FocusStateChanged();
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Service::AM
|
} // namespace Service::AM
|
||||||
|
|
|
@ -53,6 +53,16 @@ public:
|
||||||
return interactive_out_data;
|
return interactive_out_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Event& GetStateChangedEvent() {
|
||||||
|
return state_changed_event;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsCompleted() const {
|
||||||
|
return is_completed;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SignalCompletion();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Core::System& system;
|
Core::System& system;
|
||||||
KernelHelpers::ServiceContext context;
|
KernelHelpers::ServiceContext context;
|
||||||
|
@ -61,6 +71,10 @@ private:
|
||||||
AppletStorageChannel interactive_in_data;
|
AppletStorageChannel interactive_in_data;
|
||||||
AppletStorageChannel out_data;
|
AppletStorageChannel out_data;
|
||||||
AppletStorageChannel interactive_out_data;
|
AppletStorageChannel interactive_out_data;
|
||||||
|
Event state_changed_event;
|
||||||
|
|
||||||
|
std::mutex lock;
|
||||||
|
bool is_completed;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Service::AM
|
} // namespace Service::AM
|
||||||
|
|
|
@ -13,7 +13,6 @@
|
||||||
#include "core/hle/service/am/frontend/applet_mii_edit_types.h"
|
#include "core/hle/service/am/frontend/applet_mii_edit_types.h"
|
||||||
#include "core/hle/service/am/frontend/applet_software_keyboard_types.h"
|
#include "core/hle/service/am/frontend/applet_software_keyboard_types.h"
|
||||||
#include "core/hle/service/am/service/storage.h"
|
#include "core/hle/service/am/service/storage.h"
|
||||||
#include "core/hle/service/am/window_system.h"
|
|
||||||
#include "hid_core/hid_types.h"
|
#include "hid_core/hid_types.h"
|
||||||
|
|
||||||
namespace Service::AM {
|
namespace Service::AM {
|
||||||
|
@ -226,46 +225,49 @@ void PushInShowSoftwareKeyboard(Core::System& system, AppletStorageChannel& chan
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
AppletManager::AppletManager(Core::System& system) : m_system(system) {}
|
AppletManager::AppletManager(Core::System& system) : m_system(system) {}
|
||||||
AppletManager::~AppletManager() = default;
|
AppletManager::~AppletManager() {
|
||||||
|
this->Reset();
|
||||||
|
}
|
||||||
|
|
||||||
void AppletManager::CreateAndInsertByFrontendAppletParameters(
|
void AppletManager::InsertApplet(std::shared_ptr<Applet> applet) {
|
||||||
std::unique_ptr<Process> process, const FrontendAppletParameters& params) {
|
std::scoped_lock lk{m_lock};
|
||||||
|
|
||||||
|
m_applets.emplace(applet->aruid, std::move(applet));
|
||||||
|
}
|
||||||
|
|
||||||
|
void AppletManager::TerminateAndRemoveApplet(AppletResourceUserId aruid) {
|
||||||
|
std::shared_ptr<Applet> applet;
|
||||||
|
bool should_stop = false;
|
||||||
{
|
{
|
||||||
std::scoped_lock lk{m_lock};
|
std::scoped_lock lk{m_lock};
|
||||||
m_pending_process = std::move(process);
|
|
||||||
m_pending_parameters = params;
|
|
||||||
}
|
|
||||||
m_cv.notify_all();
|
|
||||||
}
|
|
||||||
|
|
||||||
void AppletManager::RequestExit() {
|
const auto it = m_applets.find(aruid);
|
||||||
std::scoped_lock lk{m_lock};
|
if (it == m_applets.end()) {
|
||||||
if (m_window_system) {
|
|
||||||
m_window_system->OnExitRequested();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void AppletManager::OperationModeChanged() {
|
|
||||||
std::scoped_lock lk{m_lock};
|
|
||||||
if (m_window_system) {
|
|
||||||
m_window_system->OnOperationModeChanged();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void AppletManager::SetWindowSystem(WindowSystem* window_system) {
|
|
||||||
std::unique_lock lk{m_lock};
|
|
||||||
|
|
||||||
m_window_system = window_system;
|
|
||||||
if (!m_window_system) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_cv.wait(lk, [&] { return m_pending_process != nullptr; });
|
applet = it->second;
|
||||||
|
m_applets.erase(it);
|
||||||
|
|
||||||
const auto& params = m_pending_parameters;
|
should_stop = m_applets.empty();
|
||||||
auto applet = std::make_shared<Applet>(m_system, std::move(m_pending_process),
|
}
|
||||||
params.applet_id == AppletId::Application);
|
|
||||||
|
|
||||||
|
// Terminate process.
|
||||||
|
applet->process->Terminate();
|
||||||
|
|
||||||
|
// If there were no applets left, stop emulation.
|
||||||
|
if (should_stop) {
|
||||||
|
m_system.Exit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AppletManager::CreateAndInsertByFrontendAppletParameters(
|
||||||
|
AppletResourceUserId aruid, const FrontendAppletParameters& params) {
|
||||||
|
// TODO: this should be run inside AM so that the events will have a parent process
|
||||||
|
// TODO: have am create the guest process
|
||||||
|
auto applet = std::make_shared<Applet>(m_system, std::make_unique<Process>(m_system));
|
||||||
|
|
||||||
|
applet->aruid = aruid;
|
||||||
applet->program_id = params.program_id;
|
applet->program_id = params.program_id;
|
||||||
applet->applet_id = params.applet_id;
|
applet->applet_id = params.applet_id;
|
||||||
applet->type = params.applet_type;
|
applet->type = params.applet_type;
|
||||||
|
@ -320,19 +322,59 @@ void AppletManager::SetWindowSystem(WindowSystem* window_system) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Applet was started by frontend, so it is foreground.
|
// Applet was started by frontend, so it is foreground.
|
||||||
applet->lifecycle_manager.SetFocusState(FocusState::InFocus);
|
applet->message_queue.PushMessage(AppletMessage::ChangeIntoForeground);
|
||||||
|
applet->message_queue.PushMessage(AppletMessage::FocusStateChanged);
|
||||||
|
applet->focus_state = FocusState::InFocus;
|
||||||
|
|
||||||
if (applet->applet_id == AppletId::QLaunch) {
|
this->InsertApplet(std::move(applet));
|
||||||
applet->lifecycle_manager.SetFocusHandlingMode(false);
|
|
||||||
applet->lifecycle_manager.SetOutOfFocusSuspendingEnabled(false);
|
|
||||||
m_window_system->TrackApplet(applet, false);
|
|
||||||
m_window_system->RequestHomeMenuToGetForeground();
|
|
||||||
} else {
|
|
||||||
m_window_system->TrackApplet(applet, true);
|
|
||||||
m_window_system->RequestApplicationToGetForeground();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
applet->process->Run();
|
std::shared_ptr<Applet> AppletManager::GetByAppletResourceUserId(AppletResourceUserId aruid) const {
|
||||||
|
std::scoped_lock lk{m_lock};
|
||||||
|
|
||||||
|
if (const auto it = m_applets.find(aruid); it != m_applets.end()) {
|
||||||
|
return it->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
void AppletManager::Reset() {
|
||||||
|
std::scoped_lock lk{m_lock};
|
||||||
|
|
||||||
|
m_applets.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AppletManager::RequestExit() {
|
||||||
|
std::scoped_lock lk{m_lock};
|
||||||
|
|
||||||
|
for (const auto& [aruid, applet] : m_applets) {
|
||||||
|
applet->message_queue.RequestExit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AppletManager::RequestResume() {
|
||||||
|
std::scoped_lock lk{m_lock};
|
||||||
|
|
||||||
|
for (const auto& [aruid, applet] : m_applets) {
|
||||||
|
applet->message_queue.RequestResume();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AppletManager::OperationModeChanged() {
|
||||||
|
std::scoped_lock lk{m_lock};
|
||||||
|
|
||||||
|
for (const auto& [aruid, applet] : m_applets) {
|
||||||
|
applet->message_queue.OperationModeChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AppletManager::FocusStateChanged() {
|
||||||
|
std::scoped_lock lk{m_lock};
|
||||||
|
|
||||||
|
for (const auto& [aruid, applet] : m_applets) {
|
||||||
|
applet->message_queue.FocusStateChanged();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Service::AM
|
} // namespace Service::AM
|
||||||
|
|
|
@ -3,23 +3,17 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <condition_variable>
|
#include <map>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
|
||||||
#include "core/hle/service/am/am_types.h"
|
#include "core/hle/service/am/applet.h"
|
||||||
|
|
||||||
namespace Core {
|
namespace Core {
|
||||||
class System;
|
class System;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace Service {
|
|
||||||
class Process;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace Service::AM {
|
namespace Service::AM {
|
||||||
|
|
||||||
class WindowSystem;
|
|
||||||
|
|
||||||
enum class LaunchType {
|
enum class LaunchType {
|
||||||
FrontendInitiated,
|
FrontendInitiated,
|
||||||
ApplicationInitiated,
|
ApplicationInitiated,
|
||||||
|
@ -39,24 +33,27 @@ public:
|
||||||
explicit AppletManager(Core::System& system);
|
explicit AppletManager(Core::System& system);
|
||||||
~AppletManager();
|
~AppletManager();
|
||||||
|
|
||||||
void CreateAndInsertByFrontendAppletParameters(std::unique_ptr<Process> process,
|
void InsertApplet(std::shared_ptr<Applet> applet);
|
||||||
const FrontendAppletParameters& params);
|
void TerminateAndRemoveApplet(AppletResourceUserId aruid);
|
||||||
void RequestExit();
|
|
||||||
void OperationModeChanged();
|
|
||||||
|
|
||||||
public:
|
void CreateAndInsertByFrontendAppletParameters(AppletResourceUserId aruid,
|
||||||
void SetWindowSystem(WindowSystem* window_system);
|
const FrontendAppletParameters& params);
|
||||||
|
std::shared_ptr<Applet> GetByAppletResourceUserId(AppletResourceUserId aruid) const;
|
||||||
|
|
||||||
|
void Reset();
|
||||||
|
|
||||||
|
void RequestExit();
|
||||||
|
void RequestResume();
|
||||||
|
void OperationModeChanged();
|
||||||
|
void FocusStateChanged();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Core::System& m_system;
|
Core::System& m_system;
|
||||||
|
|
||||||
std::mutex m_lock;
|
mutable std::mutex m_lock{};
|
||||||
std::condition_variable m_cv;
|
std::map<AppletResourceUserId, std::shared_ptr<Applet>> m_applets{};
|
||||||
|
|
||||||
WindowSystem* m_window_system{};
|
// AudioController state goes here
|
||||||
|
|
||||||
FrontendAppletParameters m_pending_parameters{};
|
|
||||||
std::unique_ptr<Process> m_pending_process{};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Service::AM
|
} // namespace Service::AM
|
||||||
|
|
|
@ -69,11 +69,7 @@ void FrontendApplet::PushInteractiveOutData(std::shared_ptr<IStorage> storage) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void FrontendApplet::Exit() {
|
void FrontendApplet::Exit() {
|
||||||
auto applet_ = applet.lock();
|
applet.lock()->caller_applet_broker->SignalCompletion();
|
||||||
|
|
||||||
std::scoped_lock lk{applet_->lock};
|
|
||||||
applet_->is_completed = true;
|
|
||||||
applet_->state_changed_event.Signal();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FrontendAppletSet::FrontendAppletSet() = default;
|
FrontendAppletSet::FrontendAppletSet() = default;
|
||||||
|
|
|
@ -3,28 +3,24 @@
|
||||||
|
|
||||||
#include "core/core.h"
|
#include "core/core.h"
|
||||||
#include "core/hle/service/am/hid_registration.h"
|
#include "core/hle/service/am/hid_registration.h"
|
||||||
|
#include "core/hle/service/am/process.h"
|
||||||
#include "core/hle/service/hid/hid_server.h"
|
#include "core/hle/service/hid/hid_server.h"
|
||||||
#include "core/hle/service/os/process.h"
|
|
||||||
#include "core/hle/service/sm/sm.h"
|
#include "core/hle/service/sm/sm.h"
|
||||||
#include "hid_core/resource_manager.h"
|
#include "hid_core/resource_manager.h"
|
||||||
|
|
||||||
namespace Service::AM {
|
namespace Service::AM {
|
||||||
|
|
||||||
HidRegistration::HidRegistration(Core::System& system, Process& process) : m_process(process) {
|
HidRegistration::HidRegistration(Core::System& system, Process& process) : m_process(process) {
|
||||||
m_hid_server = system.ServiceManager().GetService<HID::IHidServer>("hid", true);
|
m_hid_server = system.ServiceManager().GetService<HID::IHidServer>("hid");
|
||||||
|
|
||||||
if (m_process.IsInitialized()) {
|
if (m_process.IsInitialized()) {
|
||||||
m_hid_server->GetResourceManager()->RegisterAppletResourceUserId(m_process.GetProcessId(),
|
m_hid_server->GetResourceManager()->RegisterAppletResourceUserId(m_process.GetProcessId(),
|
||||||
true);
|
true);
|
||||||
m_hid_server->GetResourceManager()->SetAruidValidForVibration(m_process.GetProcessId(),
|
|
||||||
true);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
HidRegistration::~HidRegistration() {
|
HidRegistration::~HidRegistration() {
|
||||||
if (m_process.IsInitialized()) {
|
if (m_process.IsInitialized()) {
|
||||||
m_hid_server->GetResourceManager()->SetAruidValidForVibration(m_process.GetProcessId(),
|
|
||||||
false);
|
|
||||||
m_hid_server->GetResourceManager()->UnregisterAppletResourceUserId(
|
m_hid_server->GetResourceManager()->UnregisterAppletResourceUserId(
|
||||||
m_process.GetProcessId());
|
m_process.GetProcessId());
|
||||||
}
|
}
|
||||||
|
@ -32,8 +28,6 @@ HidRegistration::~HidRegistration() {
|
||||||
|
|
||||||
void HidRegistration::EnableAppletToGetInput(bool enable) {
|
void HidRegistration::EnableAppletToGetInput(bool enable) {
|
||||||
if (m_process.IsInitialized()) {
|
if (m_process.IsInitialized()) {
|
||||||
m_hid_server->GetResourceManager()->SetAruidValidForVibration(m_process.GetProcessId(),
|
|
||||||
enable);
|
|
||||||
m_hid_server->GetResourceManager()->EnableInput(m_process.GetProcessId(), enable);
|
m_hid_server->GetResourceManager()->EnableInput(m_process.GetProcessId(), enable);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,12 +13,10 @@ namespace Service::HID {
|
||||||
class IHidServer;
|
class IHidServer;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace Service {
|
|
||||||
class Process;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace Service::AM {
|
namespace Service::AM {
|
||||||
|
|
||||||
|
class Process;
|
||||||
|
|
||||||
class HidRegistration {
|
class HidRegistration {
|
||||||
public:
|
public:
|
||||||
explicit HidRegistration(Core::System& system, Process& process);
|
explicit HidRegistration(Core::System& system, Process& process);
|
||||||
|
|
|
@ -6,14 +6,12 @@
|
||||||
#include "core/hle/service/am/service/all_system_applet_proxies_service.h"
|
#include "core/hle/service/am/service/all_system_applet_proxies_service.h"
|
||||||
#include "core/hle/service/am/service/library_applet_proxy.h"
|
#include "core/hle/service/am/service/library_applet_proxy.h"
|
||||||
#include "core/hle/service/am/service/system_applet_proxy.h"
|
#include "core/hle/service/am/service/system_applet_proxy.h"
|
||||||
#include "core/hle/service/am/window_system.h"
|
|
||||||
#include "core/hle/service/cmif_serialization.h"
|
#include "core/hle/service/cmif_serialization.h"
|
||||||
|
|
||||||
namespace Service::AM {
|
namespace Service::AM {
|
||||||
|
|
||||||
IAllSystemAppletProxiesService::IAllSystemAppletProxiesService(Core::System& system_,
|
IAllSystemAppletProxiesService::IAllSystemAppletProxiesService(Core::System& system_)
|
||||||
WindowSystem& window_system)
|
: ServiceFramework{system_, "appletAE"} {
|
||||||
: ServiceFramework{system_, "appletAE"}, m_window_system{window_system} {
|
|
||||||
// clang-format off
|
// clang-format off
|
||||||
static const FunctionInfo functions[] = {
|
static const FunctionInfo functions[] = {
|
||||||
{100, D<&IAllSystemAppletProxiesService::OpenSystemAppletProxy>, "OpenSystemAppletProxy"},
|
{100, D<&IAllSystemAppletProxiesService::OpenSystemAppletProxy>, "OpenSystemAppletProxy"},
|
||||||
|
@ -38,8 +36,8 @@ Result IAllSystemAppletProxiesService::OpenSystemAppletProxy(
|
||||||
LOG_DEBUG(Service_AM, "called");
|
LOG_DEBUG(Service_AM, "called");
|
||||||
|
|
||||||
if (const auto applet = this->GetAppletFromProcessId(pid); applet) {
|
if (const auto applet = this->GetAppletFromProcessId(pid); applet) {
|
||||||
*out_system_applet_proxy = std::make_shared<ISystemAppletProxy>(
|
*out_system_applet_proxy =
|
||||||
system, applet, process_handle.Get(), m_window_system);
|
std::make_shared<ISystemAppletProxy>(system, applet, process_handle.Get());
|
||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
} else {
|
} else {
|
||||||
UNIMPLEMENTED();
|
UNIMPLEMENTED();
|
||||||
|
@ -54,8 +52,8 @@ Result IAllSystemAppletProxiesService::OpenLibraryAppletProxy(
|
||||||
LOG_DEBUG(Service_AM, "called");
|
LOG_DEBUG(Service_AM, "called");
|
||||||
|
|
||||||
if (const auto applet = this->GetAppletFromProcessId(pid); applet) {
|
if (const auto applet = this->GetAppletFromProcessId(pid); applet) {
|
||||||
*out_library_applet_proxy = std::make_shared<ILibraryAppletProxy>(
|
*out_library_applet_proxy =
|
||||||
system, applet, process_handle.Get(), m_window_system);
|
std::make_shared<ILibraryAppletProxy>(system, applet, process_handle.Get());
|
||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
} else {
|
} else {
|
||||||
UNIMPLEMENTED();
|
UNIMPLEMENTED();
|
||||||
|
@ -75,7 +73,7 @@ Result IAllSystemAppletProxiesService::OpenLibraryAppletProxyOld(
|
||||||
|
|
||||||
std::shared_ptr<Applet> IAllSystemAppletProxiesService::GetAppletFromProcessId(
|
std::shared_ptr<Applet> IAllSystemAppletProxiesService::GetAppletFromProcessId(
|
||||||
ProcessId process_id) {
|
ProcessId process_id) {
|
||||||
return m_window_system.GetByAppletResourceUserId(process_id.pid);
|
return system.GetAppletManager().GetByAppletResourceUserId(process_id.pid);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Service::AM
|
} // namespace Service::AM
|
||||||
|
|
|
@ -14,12 +14,11 @@ struct Applet;
|
||||||
struct AppletAttribute;
|
struct AppletAttribute;
|
||||||
class ILibraryAppletProxy;
|
class ILibraryAppletProxy;
|
||||||
class ISystemAppletProxy;
|
class ISystemAppletProxy;
|
||||||
class WindowSystem;
|
|
||||||
|
|
||||||
class IAllSystemAppletProxiesService final
|
class IAllSystemAppletProxiesService final
|
||||||
: public ServiceFramework<IAllSystemAppletProxiesService> {
|
: public ServiceFramework<IAllSystemAppletProxiesService> {
|
||||||
public:
|
public:
|
||||||
explicit IAllSystemAppletProxiesService(Core::System& system_, WindowSystem& window_system);
|
explicit IAllSystemAppletProxiesService(Core::System& system_);
|
||||||
~IAllSystemAppletProxiesService() override;
|
~IAllSystemAppletProxiesService() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -36,8 +35,6 @@ private:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::shared_ptr<Applet> GetAppletFromProcessId(ProcessId pid);
|
std::shared_ptr<Applet> GetAppletFromProcessId(ProcessId pid);
|
||||||
|
|
||||||
WindowSystem& m_window_system;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace AM
|
} // namespace AM
|
||||||
|
|
|
@ -19,7 +19,7 @@ IAppletCommonFunctions::IAppletCommonFunctions(Core::System& system_,
|
||||||
{21, nullptr, "TryPopFromAppletBoundChannel"},
|
{21, nullptr, "TryPopFromAppletBoundChannel"},
|
||||||
{40, nullptr, "GetDisplayLogicalResolution"},
|
{40, nullptr, "GetDisplayLogicalResolution"},
|
||||||
{42, nullptr, "SetDisplayMagnification"},
|
{42, nullptr, "SetDisplayMagnification"},
|
||||||
{50, D<&IAppletCommonFunctions::SetHomeButtonDoubleClickEnabled>, "SetHomeButtonDoubleClickEnabled"},
|
{50, nullptr, "SetHomeButtonDoubleClickEnabled"},
|
||||||
{51, D<&IAppletCommonFunctions::GetHomeButtonDoubleClickEnabled>, "GetHomeButtonDoubleClickEnabled"},
|
{51, D<&IAppletCommonFunctions::GetHomeButtonDoubleClickEnabled>, "GetHomeButtonDoubleClickEnabled"},
|
||||||
{52, nullptr, "IsHomeButtonShortPressedBlocked"},
|
{52, nullptr, "IsHomeButtonShortPressedBlocked"},
|
||||||
{60, nullptr, "IsVrModeCurtainRequired"},
|
{60, nullptr, "IsVrModeCurtainRequired"},
|
||||||
|
@ -40,13 +40,6 @@ IAppletCommonFunctions::IAppletCommonFunctions(Core::System& system_,
|
||||||
|
|
||||||
IAppletCommonFunctions::~IAppletCommonFunctions() = default;
|
IAppletCommonFunctions::~IAppletCommonFunctions() = default;
|
||||||
|
|
||||||
Result IAppletCommonFunctions::SetHomeButtonDoubleClickEnabled(
|
|
||||||
bool home_button_double_click_enabled) {
|
|
||||||
LOG_WARNING(Service_AM, "(STUBBED) called, home_button_double_click_enabled={}",
|
|
||||||
home_button_double_click_enabled);
|
|
||||||
R_SUCCEED();
|
|
||||||
}
|
|
||||||
|
|
||||||
Result IAppletCommonFunctions::GetHomeButtonDoubleClickEnabled(
|
Result IAppletCommonFunctions::GetHomeButtonDoubleClickEnabled(
|
||||||
Out<bool> out_home_button_double_click_enabled) {
|
Out<bool> out_home_button_double_click_enabled) {
|
||||||
LOG_WARNING(Service_AM, "(STUBBED) called");
|
LOG_WARNING(Service_AM, "(STUBBED) called");
|
||||||
|
|
|
@ -16,7 +16,6 @@ public:
|
||||||
~IAppletCommonFunctions() override;
|
~IAppletCommonFunctions() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Result SetHomeButtonDoubleClickEnabled(bool home_button_double_click_enabled);
|
|
||||||
Result GetHomeButtonDoubleClickEnabled(Out<bool> out_home_button_double_click_enabled);
|
Result GetHomeButtonDoubleClickEnabled(Out<bool> out_home_button_double_click_enabled);
|
||||||
Result SetCpuBoostRequestPriority(s32 priority);
|
Result SetCpuBoostRequestPriority(s32 priority);
|
||||||
Result GetCurrentApplicationId(Out<u64> out_application_id);
|
Result GetCurrentApplicationId(Out<u64> out_application_id);
|
||||||
|
|
|
@ -9,16 +9,12 @@
|
||||||
#include "core/hle/service/am/service/application_accessor.h"
|
#include "core/hle/service/am/service/application_accessor.h"
|
||||||
#include "core/hle/service/am/service/library_applet_accessor.h"
|
#include "core/hle/service/am/service/library_applet_accessor.h"
|
||||||
#include "core/hle/service/am/service/storage.h"
|
#include "core/hle/service/am/service/storage.h"
|
||||||
#include "core/hle/service/am/window_system.h"
|
|
||||||
#include "core/hle/service/cmif_serialization.h"
|
#include "core/hle/service/cmif_serialization.h"
|
||||||
#include "core/hle/service/glue/glue_manager.h"
|
|
||||||
|
|
||||||
namespace Service::AM {
|
namespace Service::AM {
|
||||||
|
|
||||||
IApplicationAccessor::IApplicationAccessor(Core::System& system_, std::shared_ptr<Applet> applet,
|
IApplicationAccessor::IApplicationAccessor(Core::System& system_, std::shared_ptr<Applet> applet)
|
||||||
WindowSystem& window_system)
|
: ServiceFramework{system_, "IApplicationAccessor"}, m_applet(std::move(applet)) {
|
||||||
: ServiceFramework{system_, "IApplicationAccessor"}, m_window_system(window_system),
|
|
||||||
m_applet(std::move(applet)) {
|
|
||||||
// clang-format off
|
// clang-format off
|
||||||
static const FunctionInfo functions[] = {
|
static const FunctionInfo functions[] = {
|
||||||
{0, D<&IApplicationAccessor::GetAppletStateChangedEvent>, "GetAppletStateChangedEvent"},
|
{0, D<&IApplicationAccessor::GetAppletStateChangedEvent>, "GetAppletStateChangedEvent"},
|
||||||
|
@ -63,15 +59,7 @@ Result IApplicationAccessor::Start() {
|
||||||
|
|
||||||
Result IApplicationAccessor::RequestExit() {
|
Result IApplicationAccessor::RequestExit() {
|
||||||
LOG_INFO(Service_AM, "called");
|
LOG_INFO(Service_AM, "called");
|
||||||
|
m_applet->message_queue.RequestExit();
|
||||||
std::scoped_lock lk{m_applet->lock};
|
|
||||||
if (m_applet->exit_locked) {
|
|
||||||
m_applet->lifecycle_manager.RequestExit();
|
|
||||||
m_applet->UpdateSuspensionStateLocked(true);
|
|
||||||
} else {
|
|
||||||
m_applet->process->Terminate();
|
|
||||||
}
|
|
||||||
|
|
||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -83,14 +71,13 @@ Result IApplicationAccessor::Terminate() {
|
||||||
|
|
||||||
Result IApplicationAccessor::GetResult() {
|
Result IApplicationAccessor::GetResult() {
|
||||||
LOG_INFO(Service_AM, "called");
|
LOG_INFO(Service_AM, "called");
|
||||||
std::scoped_lock lk{m_applet->lock};
|
R_SUCCEED();
|
||||||
R_RETURN(m_applet->terminate_result);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Result IApplicationAccessor::GetAppletStateChangedEvent(
|
Result IApplicationAccessor::GetAppletStateChangedEvent(
|
||||||
OutCopyHandle<Kernel::KReadableEvent> out_event) {
|
OutCopyHandle<Kernel::KReadableEvent> out_event) {
|
||||||
LOG_INFO(Service_AM, "called");
|
LOG_INFO(Service_AM, "called");
|
||||||
*out_event = m_applet->state_changed_event.GetHandle();
|
*out_event = m_applet->caller_applet_broker->GetStateChangedEvent().GetHandle();
|
||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -109,15 +96,8 @@ Result IApplicationAccessor::PushLaunchParameter(LaunchParameterKind kind,
|
||||||
|
|
||||||
Result IApplicationAccessor::GetApplicationControlProperty(
|
Result IApplicationAccessor::GetApplicationControlProperty(
|
||||||
OutBuffer<BufferAttr_HipcMapAlias> out_control_property) {
|
OutBuffer<BufferAttr_HipcMapAlias> out_control_property) {
|
||||||
LOG_INFO(Service_AM, "called");
|
LOG_WARNING(Service_AM, "(STUBBED) called");
|
||||||
|
R_THROW(ResultUnknown);
|
||||||
std::vector<u8> nacp;
|
|
||||||
R_TRY(system.GetARPManager().GetControlProperty(&nacp, m_applet->program_id));
|
|
||||||
|
|
||||||
std::memcpy(out_control_property.data(), nacp.data(),
|
|
||||||
std::min(out_control_property.size(), nacp.size()));
|
|
||||||
|
|
||||||
R_SUCCEED();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Result IApplicationAccessor::SetUsers(bool enable,
|
Result IApplicationAccessor::SetUsers(bool enable,
|
||||||
|
@ -134,9 +114,8 @@ Result IApplicationAccessor::GetCurrentLibraryApplet(
|
||||||
}
|
}
|
||||||
|
|
||||||
Result IApplicationAccessor::RequestForApplicationToGetForeground() {
|
Result IApplicationAccessor::RequestForApplicationToGetForeground() {
|
||||||
LOG_INFO(Service_AM, "called");
|
LOG_WARNING(Service_AM, "(STUBBED) called");
|
||||||
m_window_system.RequestApplicationToGetForeground();
|
R_THROW(ResultUnknown);
|
||||||
R_SUCCEED();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Result IApplicationAccessor::CheckRightsEnvironmentAvailable(Out<bool> out_is_available) {
|
Result IApplicationAccessor::CheckRightsEnvironmentAvailable(Out<bool> out_is_available) {
|
||||||
|
|
|
@ -13,12 +13,10 @@ namespace Service::AM {
|
||||||
struct Applet;
|
struct Applet;
|
||||||
class ILibraryAppletAccessor;
|
class ILibraryAppletAccessor;
|
||||||
class IStorage;
|
class IStorage;
|
||||||
class WindowSystem;
|
|
||||||
|
|
||||||
class IApplicationAccessor final : public ServiceFramework<IApplicationAccessor> {
|
class IApplicationAccessor final : public ServiceFramework<IApplicationAccessor> {
|
||||||
public:
|
public:
|
||||||
explicit IApplicationAccessor(Core::System& system_, std::shared_ptr<Applet> applet,
|
explicit IApplicationAccessor(Core::System& system_, std::shared_ptr<Applet> applet);
|
||||||
WindowSystem& window_system);
|
|
||||||
~IApplicationAccessor() override;
|
~IApplicationAccessor() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -36,7 +34,6 @@ private:
|
||||||
Result GetNsRightsEnvironmentHandle(Out<u64> out_handle);
|
Result GetNsRightsEnvironmentHandle(Out<u64> out_handle);
|
||||||
Result ReportApplicationExitTimeout();
|
Result ReportApplicationExitTimeout();
|
||||||
|
|
||||||
WindowSystem& m_window_system;
|
|
||||||
const std::shared_ptr<Applet> m_applet;
|
const std::shared_ptr<Applet> m_applet;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,57 +1,17 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
#include "core/file_sys/nca_metadata.h"
|
|
||||||
#include "core/file_sys/registered_cache.h"
|
|
||||||
#include "core/hle/service/am/am_types.h"
|
#include "core/hle/service/am/am_types.h"
|
||||||
#include "core/hle/service/am/applet.h"
|
#include "core/hle/service/am/applet.h"
|
||||||
#include "core/hle/service/am/applet_manager.h"
|
#include "core/hle/service/am/applet_manager.h"
|
||||||
#include "core/hle/service/am/process_creation.h"
|
|
||||||
#include "core/hle/service/am/service/application_accessor.h"
|
#include "core/hle/service/am/service/application_accessor.h"
|
||||||
#include "core/hle/service/am/service/application_creator.h"
|
#include "core/hle/service/am/service/application_creator.h"
|
||||||
#include "core/hle/service/am/window_system.h"
|
|
||||||
#include "core/hle/service/cmif_serialization.h"
|
#include "core/hle/service/cmif_serialization.h"
|
||||||
#include "core/loader/loader.h"
|
|
||||||
|
|
||||||
namespace Service::AM {
|
namespace Service::AM {
|
||||||
|
|
||||||
namespace {
|
IApplicationCreator::IApplicationCreator(Core::System& system_)
|
||||||
|
: ServiceFramework{system_, "IApplicationCreator"} {
|
||||||
Result CreateGuestApplication(SharedPointer<IApplicationAccessor>* out_application_accessor,
|
|
||||||
Core::System& system, WindowSystem& window_system, u64 program_id) {
|
|
||||||
FileSys::VirtualFile nca_raw{};
|
|
||||||
|
|
||||||
// Get the program NCA from storage.
|
|
||||||
auto& storage = system.GetContentProviderUnion();
|
|
||||||
nca_raw = storage.GetEntryRaw(program_id, FileSys::ContentRecordType::Program);
|
|
||||||
|
|
||||||
// Ensure we retrieved a program NCA.
|
|
||||||
R_UNLESS(nca_raw != nullptr, ResultUnknown);
|
|
||||||
|
|
||||||
std::vector<u8> control;
|
|
||||||
std::unique_ptr<Loader::AppLoader> loader;
|
|
||||||
Loader::ResultStatus result;
|
|
||||||
auto process =
|
|
||||||
CreateApplicationProcess(control, loader, result, system, nca_raw, program_id, 0);
|
|
||||||
R_UNLESS(process != nullptr, ResultUnknown);
|
|
||||||
|
|
||||||
const auto applet = std::make_shared<Applet>(system, std::move(process), true);
|
|
||||||
applet->program_id = program_id;
|
|
||||||
applet->applet_id = AppletId::Application;
|
|
||||||
applet->type = AppletType::Application;
|
|
||||||
applet->library_applet_mode = LibraryAppletMode::AllForeground;
|
|
||||||
|
|
||||||
window_system.TrackApplet(applet, true);
|
|
||||||
|
|
||||||
*out_application_accessor =
|
|
||||||
std::make_shared<IApplicationAccessor>(system, applet, window_system);
|
|
||||||
R_SUCCEED();
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
IApplicationCreator::IApplicationCreator(Core::System& system_, WindowSystem& window_system)
|
|
||||||
: ServiceFramework{system_, "IApplicationCreator"}, m_window_system{window_system} {
|
|
||||||
// clang-format off
|
// clang-format off
|
||||||
static const FunctionInfo functions[] = {
|
static const FunctionInfo functions[] = {
|
||||||
{0, D<&IApplicationCreator::CreateApplication>, "CreateApplication"},
|
{0, D<&IApplicationCreator::CreateApplication>, "CreateApplication"},
|
||||||
|
@ -68,9 +28,8 @@ IApplicationCreator::~IApplicationCreator() = default;
|
||||||
|
|
||||||
Result IApplicationCreator::CreateApplication(
|
Result IApplicationCreator::CreateApplication(
|
||||||
Out<SharedPointer<IApplicationAccessor>> out_application_accessor, u64 application_id) {
|
Out<SharedPointer<IApplicationAccessor>> out_application_accessor, u64 application_id) {
|
||||||
LOG_INFO(Service_NS, "called, application_id={:016X}", application_id);
|
LOG_ERROR(Service_NS, "called, application_id={:x}", application_id);
|
||||||
R_RETURN(
|
R_THROW(ResultUnknown);
|
||||||
CreateGuestApplication(out_application_accessor, system, m_window_system, application_id));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Service::AM
|
} // namespace Service::AM
|
||||||
|
|
|
@ -10,17 +10,14 @@ namespace Service::AM {
|
||||||
|
|
||||||
class IApplicationAccessor;
|
class IApplicationAccessor;
|
||||||
struct Applet;
|
struct Applet;
|
||||||
class WindowSystem;
|
|
||||||
|
|
||||||
class IApplicationCreator final : public ServiceFramework<IApplicationCreator> {
|
class IApplicationCreator final : public ServiceFramework<IApplicationCreator> {
|
||||||
public:
|
public:
|
||||||
explicit IApplicationCreator(Core::System& system_, WindowSystem& window_system);
|
explicit IApplicationCreator(Core::System& system_);
|
||||||
~IApplicationCreator() override;
|
~IApplicationCreator() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Result CreateApplication(Out<SharedPointer<IApplicationAccessor>>, u64 application_id);
|
Result CreateApplication(Out<SharedPointer<IApplicationAccessor>>, u64 application_id);
|
||||||
|
|
||||||
WindowSystem& m_window_system;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Service::AM
|
} // namespace Service::AM
|
||||||
|
|
|
@ -181,8 +181,7 @@ Result IApplicationFunctions::GetDesiredLanguage(Out<u64> out_language_code) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Result IApplicationFunctions::SetTerminateResult(Result terminate_result) {
|
Result IApplicationFunctions::SetTerminateResult(Result terminate_result) {
|
||||||
LOG_INFO(Service_AM, "(STUBBED) called, result={:#x} ({:04}-{:04})",
|
LOG_INFO(Service_AM, "(STUBBED) called, result={:#x} ({}-{})", terminate_result.GetInnerValue(),
|
||||||
terminate_result.GetInnerValue(),
|
|
||||||
static_cast<u32>(terminate_result.GetModule()) + 2000,
|
static_cast<u32>(terminate_result.GetModule()) + 2000,
|
||||||
terminate_result.GetDescription());
|
terminate_result.GetDescription());
|
||||||
|
|
||||||
|
|
|
@ -17,9 +17,9 @@
|
||||||
namespace Service::AM {
|
namespace Service::AM {
|
||||||
|
|
||||||
IApplicationProxy::IApplicationProxy(Core::System& system_, std::shared_ptr<Applet> applet,
|
IApplicationProxy::IApplicationProxy(Core::System& system_, std::shared_ptr<Applet> applet,
|
||||||
Kernel::KProcess* process, WindowSystem& window_system)
|
Kernel::KProcess* process)
|
||||||
: ServiceFramework{system_, "IApplicationProxy"},
|
: ServiceFramework{system_, "IApplicationProxy"}, m_process{process}, m_applet{
|
||||||
m_window_system{window_system}, m_process{process}, m_applet{std::move(applet)} {
|
std::move(applet)} {
|
||||||
// clang-format off
|
// clang-format off
|
||||||
static const FunctionInfo functions[] = {
|
static const FunctionInfo functions[] = {
|
||||||
{0, D<&IApplicationProxy::GetCommonStateGetter>, "GetCommonStateGetter"},
|
{0, D<&IApplicationProxy::GetCommonStateGetter>, "GetCommonStateGetter"},
|
||||||
|
@ -70,7 +70,7 @@ Result IApplicationProxy::GetDebugFunctions(
|
||||||
Result IApplicationProxy::GetWindowController(
|
Result IApplicationProxy::GetWindowController(
|
||||||
Out<SharedPointer<IWindowController>> out_window_controller) {
|
Out<SharedPointer<IWindowController>> out_window_controller) {
|
||||||
LOG_DEBUG(Service_AM, "called");
|
LOG_DEBUG(Service_AM, "called");
|
||||||
*out_window_controller = std::make_shared<IWindowController>(system, m_applet, m_window_system);
|
*out_window_controller = std::make_shared<IWindowController>(system, m_applet);
|
||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -91,8 +91,7 @@ Result IApplicationProxy::GetCommonStateGetter(
|
||||||
Result IApplicationProxy::GetLibraryAppletCreator(
|
Result IApplicationProxy::GetLibraryAppletCreator(
|
||||||
Out<SharedPointer<ILibraryAppletCreator>> out_library_applet_creator) {
|
Out<SharedPointer<ILibraryAppletCreator>> out_library_applet_creator) {
|
||||||
LOG_DEBUG(Service_AM, "called");
|
LOG_DEBUG(Service_AM, "called");
|
||||||
*out_library_applet_creator =
|
*out_library_applet_creator = std::make_shared<ILibraryAppletCreator>(system, m_applet);
|
||||||
std::make_shared<ILibraryAppletCreator>(system, m_applet, m_window_system);
|
|
||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,12 +18,11 @@ class ILibraryAppletCreator;
|
||||||
class IProcessWindingController;
|
class IProcessWindingController;
|
||||||
class ISelfController;
|
class ISelfController;
|
||||||
class IWindowController;
|
class IWindowController;
|
||||||
class WindowSystem;
|
|
||||||
|
|
||||||
class IApplicationProxy final : public ServiceFramework<IApplicationProxy> {
|
class IApplicationProxy final : public ServiceFramework<IApplicationProxy> {
|
||||||
public:
|
public:
|
||||||
explicit IApplicationProxy(Core::System& system_, std::shared_ptr<Applet> applet,
|
explicit IApplicationProxy(Core::System& system_, std::shared_ptr<Applet> applet,
|
||||||
Kernel::KProcess* process, WindowSystem& window_system);
|
Kernel::KProcess* process);
|
||||||
~IApplicationProxy();
|
~IApplicationProxy();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -41,7 +40,6 @@ private:
|
||||||
Out<SharedPointer<IApplicationFunctions>> out_application_functions);
|
Out<SharedPointer<IApplicationFunctions>> out_application_functions);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
WindowSystem& m_window_system;
|
|
||||||
Kernel::KProcess* const m_process;
|
Kernel::KProcess* const m_process;
|
||||||
const std::shared_ptr<Applet> m_applet;
|
const std::shared_ptr<Applet> m_applet;
|
||||||
};
|
};
|
||||||
|
|
|
@ -6,14 +6,12 @@
|
||||||
#include "core/hle/service/am/applet_manager.h"
|
#include "core/hle/service/am/applet_manager.h"
|
||||||
#include "core/hle/service/am/service/application_proxy.h"
|
#include "core/hle/service/am/service/application_proxy.h"
|
||||||
#include "core/hle/service/am/service/application_proxy_service.h"
|
#include "core/hle/service/am/service/application_proxy_service.h"
|
||||||
#include "core/hle/service/am/window_system.h"
|
|
||||||
#include "core/hle/service/cmif_serialization.h"
|
#include "core/hle/service/cmif_serialization.h"
|
||||||
|
|
||||||
namespace Service::AM {
|
namespace Service::AM {
|
||||||
|
|
||||||
IApplicationProxyService::IApplicationProxyService(Core::System& system_,
|
IApplicationProxyService::IApplicationProxyService(Core::System& system_)
|
||||||
WindowSystem& window_system)
|
: ServiceFramework{system_, "appletOE"} {
|
||||||
: ServiceFramework{system_, "appletOE"}, m_window_system{window_system} {
|
|
||||||
static const FunctionInfo functions[] = {
|
static const FunctionInfo functions[] = {
|
||||||
{0, D<&IApplicationProxyService::OpenApplicationProxy>, "OpenApplicationProxy"},
|
{0, D<&IApplicationProxyService::OpenApplicationProxy>, "OpenApplicationProxy"},
|
||||||
};
|
};
|
||||||
|
@ -28,8 +26,8 @@ Result IApplicationProxyService::OpenApplicationProxy(
|
||||||
LOG_DEBUG(Service_AM, "called");
|
LOG_DEBUG(Service_AM, "called");
|
||||||
|
|
||||||
if (const auto applet = this->GetAppletFromProcessId(pid)) {
|
if (const auto applet = this->GetAppletFromProcessId(pid)) {
|
||||||
*out_application_proxy = std::make_shared<IApplicationProxy>(
|
*out_application_proxy =
|
||||||
system, applet, process_handle.Get(), m_window_system);
|
std::make_shared<IApplicationProxy>(system, applet, process_handle.Get());
|
||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
} else {
|
} else {
|
||||||
UNIMPLEMENTED();
|
UNIMPLEMENTED();
|
||||||
|
@ -38,7 +36,7 @@ Result IApplicationProxyService::OpenApplicationProxy(
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<Applet> IApplicationProxyService::GetAppletFromProcessId(ProcessId process_id) {
|
std::shared_ptr<Applet> IApplicationProxyService::GetAppletFromProcessId(ProcessId process_id) {
|
||||||
return m_window_system.GetByAppletResourceUserId(process_id.pid);
|
return system.GetAppletManager().GetByAppletResourceUserId(process_id.pid);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Service::AM
|
} // namespace Service::AM
|
||||||
|
|
|
@ -12,11 +12,10 @@ namespace AM {
|
||||||
|
|
||||||
struct Applet;
|
struct Applet;
|
||||||
class IApplicationProxy;
|
class IApplicationProxy;
|
||||||
class WindowSystem;
|
|
||||||
|
|
||||||
class IApplicationProxyService final : public ServiceFramework<IApplicationProxyService> {
|
class IApplicationProxyService final : public ServiceFramework<IApplicationProxyService> {
|
||||||
public:
|
public:
|
||||||
explicit IApplicationProxyService(Core::System& system_, WindowSystem& window_system);
|
explicit IApplicationProxyService(Core::System& system_);
|
||||||
~IApplicationProxyService() override;
|
~IApplicationProxyService() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -25,8 +24,6 @@ private:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::shared_ptr<Applet> GetAppletFromProcessId(ProcessId pid);
|
std::shared_ptr<Applet> GetAppletFromProcessId(ProcessId pid);
|
||||||
|
|
||||||
WindowSystem& m_window_system;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace AM
|
} // namespace AM
|
||||||
|
|
|
@ -80,14 +80,15 @@ ICommonStateGetter::~ICommonStateGetter() = default;
|
||||||
|
|
||||||
Result ICommonStateGetter::GetEventHandle(OutCopyHandle<Kernel::KReadableEvent> out_event) {
|
Result ICommonStateGetter::GetEventHandle(OutCopyHandle<Kernel::KReadableEvent> out_event) {
|
||||||
LOG_DEBUG(Service_AM, "called");
|
LOG_DEBUG(Service_AM, "called");
|
||||||
*out_event = m_applet->lifecycle_manager.GetSystemEvent().GetHandle();
|
*out_event = &m_applet->message_queue.GetMessageReceiveEvent();
|
||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ICommonStateGetter::ReceiveMessage(Out<AppletMessage> out_applet_message) {
|
Result ICommonStateGetter::ReceiveMessage(Out<AppletMessage> out_applet_message) {
|
||||||
LOG_DEBUG(Service_AM, "called");
|
LOG_DEBUG(Service_AM, "called");
|
||||||
|
|
||||||
if (!m_applet->lifecycle_manager.PopMessage(out_applet_message)) {
|
*out_applet_message = m_applet->message_queue.PopMessage();
|
||||||
|
if (*out_applet_message == AppletMessage::None) {
|
||||||
LOG_ERROR(Service_AM, "Tried to pop message but none was available!");
|
LOG_ERROR(Service_AM, "Tried to pop message but none was available!");
|
||||||
R_THROW(AM::ResultNoMessages);
|
R_THROW(AM::ResultNoMessages);
|
||||||
}
|
}
|
||||||
|
@ -99,7 +100,7 @@ Result ICommonStateGetter::GetCurrentFocusState(Out<FocusState> out_focus_state)
|
||||||
LOG_DEBUG(Service_AM, "called");
|
LOG_DEBUG(Service_AM, "called");
|
||||||
|
|
||||||
std::scoped_lock lk{m_applet->lock};
|
std::scoped_lock lk{m_applet->lock};
|
||||||
*out_focus_state = m_applet->lifecycle_manager.GetAndClearFocusState();
|
*out_focus_state = m_applet->focus_state;
|
||||||
|
|
||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
@ -136,7 +137,7 @@ Result ICommonStateGetter::GetWriterLockAccessorEx(
|
||||||
Result ICommonStateGetter::GetDefaultDisplayResolutionChangeEvent(
|
Result ICommonStateGetter::GetDefaultDisplayResolutionChangeEvent(
|
||||||
OutCopyHandle<Kernel::KReadableEvent> out_event) {
|
OutCopyHandle<Kernel::KReadableEvent> out_event) {
|
||||||
LOG_DEBUG(Service_AM, "called");
|
LOG_DEBUG(Service_AM, "called");
|
||||||
*out_event = m_applet->lifecycle_manager.GetOperationModeChangedSystemEvent().GetHandle();
|
*out_event = &m_applet->message_queue.GetOperationModeChangedEvent();
|
||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,16 +4,13 @@
|
||||||
#include "core/hle/result.h"
|
#include "core/hle/result.h"
|
||||||
#include "core/hle/service/am/applet_manager.h"
|
#include "core/hle/service/am/applet_manager.h"
|
||||||
#include "core/hle/service/am/service/home_menu_functions.h"
|
#include "core/hle/service/am/service/home_menu_functions.h"
|
||||||
#include "core/hle/service/am/window_system.h"
|
|
||||||
#include "core/hle/service/cmif_serialization.h"
|
#include "core/hle/service/cmif_serialization.h"
|
||||||
|
|
||||||
namespace Service::AM {
|
namespace Service::AM {
|
||||||
|
|
||||||
IHomeMenuFunctions::IHomeMenuFunctions(Core::System& system_, std::shared_ptr<Applet> applet,
|
IHomeMenuFunctions::IHomeMenuFunctions(Core::System& system_, std::shared_ptr<Applet> applet)
|
||||||
WindowSystem& window_system)
|
: ServiceFramework{system_, "IHomeMenuFunctions"}, m_applet{std::move(applet)},
|
||||||
: ServiceFramework{system_, "IHomeMenuFunctions"}, m_window_system{window_system},
|
m_context{system, "IHomeMenuFunctions"}, m_pop_from_general_channel_event{m_context} {
|
||||||
m_applet{std::move(applet)}, m_context{system, "IHomeMenuFunctions"},
|
|
||||||
m_pop_from_general_channel_event{m_context} {
|
|
||||||
// clang-format off
|
// clang-format off
|
||||||
static const FunctionInfo functions[] = {
|
static const FunctionInfo functions[] = {
|
||||||
{10, D<&IHomeMenuFunctions::RequestToGetForeground>, "RequestToGetForeground"},
|
{10, D<&IHomeMenuFunctions::RequestToGetForeground>, "RequestToGetForeground"},
|
||||||
|
@ -40,20 +37,17 @@ IHomeMenuFunctions::IHomeMenuFunctions(Core::System& system_, std::shared_ptr<Ap
|
||||||
IHomeMenuFunctions::~IHomeMenuFunctions() = default;
|
IHomeMenuFunctions::~IHomeMenuFunctions() = default;
|
||||||
|
|
||||||
Result IHomeMenuFunctions::RequestToGetForeground() {
|
Result IHomeMenuFunctions::RequestToGetForeground() {
|
||||||
LOG_INFO(Service_AM, "called");
|
LOG_WARNING(Service_AM, "(STUBBED) called");
|
||||||
m_window_system.RequestHomeMenuToGetForeground();
|
|
||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result IHomeMenuFunctions::LockForeground() {
|
Result IHomeMenuFunctions::LockForeground() {
|
||||||
LOG_INFO(Service_AM, "called");
|
LOG_WARNING(Service_AM, "(STUBBED) called");
|
||||||
m_window_system.RequestLockHomeMenuIntoForeground();
|
|
||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result IHomeMenuFunctions::UnlockForeground() {
|
Result IHomeMenuFunctions::UnlockForeground() {
|
||||||
LOG_INFO(Service_AM, "called");
|
LOG_WARNING(Service_AM, "(STUBBED) called");
|
||||||
m_window_system.RequestUnlockHomeMenuIntoForeground();
|
|
||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,12 +11,10 @@
|
||||||
namespace Service::AM {
|
namespace Service::AM {
|
||||||
|
|
||||||
struct Applet;
|
struct Applet;
|
||||||
class WindowSystem;
|
|
||||||
|
|
||||||
class IHomeMenuFunctions final : public ServiceFramework<IHomeMenuFunctions> {
|
class IHomeMenuFunctions final : public ServiceFramework<IHomeMenuFunctions> {
|
||||||
public:
|
public:
|
||||||
explicit IHomeMenuFunctions(Core::System& system_, std::shared_ptr<Applet> applet,
|
explicit IHomeMenuFunctions(Core::System& system_, std::shared_ptr<Applet> applet);
|
||||||
WindowSystem& window_system);
|
|
||||||
~IHomeMenuFunctions() override;
|
~IHomeMenuFunctions() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -28,7 +26,6 @@ private:
|
||||||
Result IsForceTerminateApplicationDisabledForDebug(
|
Result IsForceTerminateApplicationDisabledForDebug(
|
||||||
Out<bool> out_is_force_terminate_application_disabled_for_debug);
|
Out<bool> out_is_force_terminate_application_disabled_for_debug);
|
||||||
|
|
||||||
WindowSystem& m_window_system;
|
|
||||||
const std::shared_ptr<Applet> m_applet;
|
const std::shared_ptr<Applet> m_applet;
|
||||||
KernelHelpers::ServiceContext m_context;
|
KernelHelpers::ServiceContext m_context;
|
||||||
Event m_pop_from_general_channel_event;
|
Event m_pop_from_general_channel_event;
|
||||||
|
|
|
@ -47,21 +47,20 @@ ILibraryAppletAccessor::~ILibraryAppletAccessor() = default;
|
||||||
Result ILibraryAppletAccessor::GetAppletStateChangedEvent(
|
Result ILibraryAppletAccessor::GetAppletStateChangedEvent(
|
||||||
OutCopyHandle<Kernel::KReadableEvent> out_event) {
|
OutCopyHandle<Kernel::KReadableEvent> out_event) {
|
||||||
LOG_DEBUG(Service_AM, "called");
|
LOG_DEBUG(Service_AM, "called");
|
||||||
*out_event = m_applet->state_changed_event.GetHandle();
|
*out_event = m_broker->GetStateChangedEvent().GetHandle();
|
||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ILibraryAppletAccessor::IsCompleted(Out<bool> out_is_completed) {
|
Result ILibraryAppletAccessor::IsCompleted(Out<bool> out_is_completed) {
|
||||||
LOG_DEBUG(Service_AM, "called");
|
LOG_DEBUG(Service_AM, "called");
|
||||||
std::scoped_lock lk{m_applet->lock};
|
*out_is_completed = m_broker->IsCompleted();
|
||||||
*out_is_completed = m_applet->is_completed;
|
|
||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ILibraryAppletAccessor::GetResult() {
|
Result ILibraryAppletAccessor::GetResult(Out<Result> out_result) {
|
||||||
LOG_DEBUG(Service_AM, "called");
|
LOG_DEBUG(Service_AM, "called");
|
||||||
std::scoped_lock lk{m_applet->lock};
|
*out_result = m_applet->terminate_result;
|
||||||
R_RETURN(m_applet->terminate_result);
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ILibraryAppletAccessor::PresetLibraryAppletGpuTimeSliceZero() {
|
Result ILibraryAppletAccessor::PresetLibraryAppletGpuTimeSliceZero() {
|
||||||
|
@ -78,10 +77,7 @@ Result ILibraryAppletAccessor::Start() {
|
||||||
|
|
||||||
Result ILibraryAppletAccessor::RequestExit() {
|
Result ILibraryAppletAccessor::RequestExit() {
|
||||||
LOG_DEBUG(Service_AM, "called");
|
LOG_DEBUG(Service_AM, "called");
|
||||||
{
|
m_applet->message_queue.RequestExit();
|
||||||
std::scoped_lock lk{m_applet->lock};
|
|
||||||
m_applet->lifecycle_manager.RequestExit();
|
|
||||||
}
|
|
||||||
FrontendRequestExit();
|
FrontendRequestExit();
|
||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,7 @@ public:
|
||||||
private:
|
private:
|
||||||
Result GetAppletStateChangedEvent(OutCopyHandle<Kernel::KReadableEvent> out_event);
|
Result GetAppletStateChangedEvent(OutCopyHandle<Kernel::KReadableEvent> out_event);
|
||||||
Result IsCompleted(Out<bool> out_is_completed);
|
Result IsCompleted(Out<bool> out_is_completed);
|
||||||
Result GetResult();
|
Result GetResult(Out<Result> out_result);
|
||||||
Result PresetLibraryAppletGpuTimeSliceZero();
|
Result PresetLibraryAppletGpuTimeSliceZero();
|
||||||
Result Start();
|
Result Start();
|
||||||
Result RequestExit();
|
Result RequestExit();
|
||||||
|
|
|
@ -7,11 +7,9 @@
|
||||||
#include "core/hle/service/am/applet_manager.h"
|
#include "core/hle/service/am/applet_manager.h"
|
||||||
#include "core/hle/service/am/frontend/applets.h"
|
#include "core/hle/service/am/frontend/applets.h"
|
||||||
#include "core/hle/service/am/library_applet_storage.h"
|
#include "core/hle/service/am/library_applet_storage.h"
|
||||||
#include "core/hle/service/am/process_creation.h"
|
|
||||||
#include "core/hle/service/am/service/library_applet_accessor.h"
|
#include "core/hle/service/am/service/library_applet_accessor.h"
|
||||||
#include "core/hle/service/am/service/library_applet_creator.h"
|
#include "core/hle/service/am/service/library_applet_creator.h"
|
||||||
#include "core/hle/service/am/service/storage.h"
|
#include "core/hle/service/am/service/storage.h"
|
||||||
#include "core/hle/service/am/window_system.h"
|
|
||||||
#include "core/hle/service/cmif_serialization.h"
|
#include "core/hle/service/cmif_serialization.h"
|
||||||
#include "core/hle/service/sm/sm.h"
|
#include "core/hle/service/sm/sm.h"
|
||||||
|
|
||||||
|
@ -95,7 +93,6 @@ AppletProgramId AppletIdToProgramId(AppletId applet_id) {
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<ILibraryAppletAccessor> CreateGuestApplet(Core::System& system,
|
std::shared_ptr<ILibraryAppletAccessor> CreateGuestApplet(Core::System& system,
|
||||||
WindowSystem& window_system,
|
|
||||||
std::shared_ptr<Applet> caller_applet,
|
std::shared_ptr<Applet> caller_applet,
|
||||||
AppletId applet_id,
|
AppletId applet_id,
|
||||||
LibraryAppletMode mode) {
|
LibraryAppletMode mode) {
|
||||||
|
@ -113,38 +110,53 @@ std::shared_ptr<ILibraryAppletAccessor> CreateGuestApplet(Core::System& system,
|
||||||
Firmware1700 = 17,
|
Firmware1700 = 17,
|
||||||
};
|
};
|
||||||
|
|
||||||
auto process = CreateProcess(system, program_id, Firmware1400, Firmware1700);
|
auto process = std::make_unique<Process>(system);
|
||||||
if (!process) {
|
if (!process->Initialize(program_id, Firmware1400, Firmware1700)) {
|
||||||
// Couldn't initialize the guest process
|
// Couldn't initialize the guest process
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto applet = std::make_shared<Applet>(system, std::move(process), false);
|
const auto applet = std::make_shared<Applet>(system, std::move(process));
|
||||||
applet->program_id = program_id;
|
applet->program_id = program_id;
|
||||||
applet->applet_id = applet_id;
|
applet->applet_id = applet_id;
|
||||||
applet->type = AppletType::LibraryApplet;
|
applet->type = AppletType::LibraryApplet;
|
||||||
applet->library_applet_mode = mode;
|
applet->library_applet_mode = mode;
|
||||||
applet->window_visible = mode != LibraryAppletMode::AllForegroundInitiallyHidden;
|
|
||||||
|
// Set focus state
|
||||||
|
switch (mode) {
|
||||||
|
case LibraryAppletMode::AllForeground:
|
||||||
|
case LibraryAppletMode::NoUi:
|
||||||
|
case LibraryAppletMode::PartialForeground:
|
||||||
|
case LibraryAppletMode::PartialForegroundIndirectDisplay:
|
||||||
|
applet->hid_registration.EnableAppletToGetInput(true);
|
||||||
|
applet->focus_state = FocusState::InFocus;
|
||||||
|
applet->message_queue.PushMessage(AppletMessage::ChangeIntoForeground);
|
||||||
|
break;
|
||||||
|
case LibraryAppletMode::AllForegroundInitiallyHidden:
|
||||||
|
applet->hid_registration.EnableAppletToGetInput(false);
|
||||||
|
applet->focus_state = FocusState::NotInFocus;
|
||||||
|
applet->display_layer_manager.SetWindowVisibility(false);
|
||||||
|
applet->message_queue.PushMessage(AppletMessage::ChangeIntoBackground);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
auto broker = std::make_shared<AppletDataBroker>(system);
|
auto broker = std::make_shared<AppletDataBroker>(system);
|
||||||
applet->caller_applet = caller_applet;
|
applet->caller_applet = caller_applet;
|
||||||
applet->caller_applet_broker = broker;
|
applet->caller_applet_broker = broker;
|
||||||
caller_applet->child_applets.push_back(applet);
|
|
||||||
|
|
||||||
window_system.TrackApplet(applet, false);
|
system.GetAppletManager().InsertApplet(applet);
|
||||||
|
|
||||||
return std::make_shared<ILibraryAppletAccessor>(system, broker, applet);
|
return std::make_shared<ILibraryAppletAccessor>(system, broker, applet);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<ILibraryAppletAccessor> CreateFrontendApplet(Core::System& system,
|
std::shared_ptr<ILibraryAppletAccessor> CreateFrontendApplet(Core::System& system,
|
||||||
WindowSystem& window_system,
|
|
||||||
std::shared_ptr<Applet> caller_applet,
|
std::shared_ptr<Applet> caller_applet,
|
||||||
AppletId applet_id,
|
AppletId applet_id,
|
||||||
LibraryAppletMode mode) {
|
LibraryAppletMode mode) {
|
||||||
const auto program_id = static_cast<u64>(AppletIdToProgramId(applet_id));
|
const auto program_id = static_cast<u64>(AppletIdToProgramId(applet_id));
|
||||||
|
|
||||||
auto process = std::make_unique<Process>(system);
|
auto process = std::make_unique<Process>(system);
|
||||||
auto applet = std::make_shared<Applet>(system, std::move(process), false);
|
auto applet = std::make_shared<Applet>(system, std::move(process));
|
||||||
applet->program_id = program_id;
|
applet->program_id = program_id;
|
||||||
applet->applet_id = applet_id;
|
applet->applet_id = applet_id;
|
||||||
applet->type = AppletType::LibraryApplet;
|
applet->type = AppletType::LibraryApplet;
|
||||||
|
@ -154,19 +166,14 @@ std::shared_ptr<ILibraryAppletAccessor> CreateFrontendApplet(Core::System& syste
|
||||||
applet->caller_applet = caller_applet;
|
applet->caller_applet = caller_applet;
|
||||||
applet->caller_applet_broker = storage;
|
applet->caller_applet_broker = storage;
|
||||||
applet->frontend = system.GetFrontendAppletHolder().GetApplet(applet, applet_id, mode);
|
applet->frontend = system.GetFrontendAppletHolder().GetApplet(applet, applet_id, mode);
|
||||||
caller_applet->child_applets.push_back(applet);
|
|
||||||
|
|
||||||
window_system.TrackApplet(applet, false);
|
|
||||||
|
|
||||||
return std::make_shared<ILibraryAppletAccessor>(system, storage, applet);
|
return std::make_shared<ILibraryAppletAccessor>(system, storage, applet);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
ILibraryAppletCreator::ILibraryAppletCreator(Core::System& system_, std::shared_ptr<Applet> applet,
|
ILibraryAppletCreator::ILibraryAppletCreator(Core::System& system_, std::shared_ptr<Applet> applet)
|
||||||
WindowSystem& window_system)
|
: ServiceFramework{system_, "ILibraryAppletCreator"}, m_applet{std::move(applet)} {
|
||||||
: ServiceFramework{system_, "ILibraryAppletCreator"},
|
|
||||||
m_window_system{window_system}, m_applet{std::move(applet)} {
|
|
||||||
static const FunctionInfo functions[] = {
|
static const FunctionInfo functions[] = {
|
||||||
{0, D<&ILibraryAppletCreator::CreateLibraryApplet>, "CreateLibraryApplet"},
|
{0, D<&ILibraryAppletCreator::CreateLibraryApplet>, "CreateLibraryApplet"},
|
||||||
{1, nullptr, "TerminateAllLibraryApplets"},
|
{1, nullptr, "TerminateAllLibraryApplets"},
|
||||||
|
@ -188,12 +195,10 @@ Result ILibraryAppletCreator::CreateLibraryApplet(
|
||||||
|
|
||||||
std::shared_ptr<ILibraryAppletAccessor> library_applet;
|
std::shared_ptr<ILibraryAppletAccessor> library_applet;
|
||||||
if (ShouldCreateGuestApplet(applet_id)) {
|
if (ShouldCreateGuestApplet(applet_id)) {
|
||||||
library_applet =
|
library_applet = CreateGuestApplet(system, m_applet, applet_id, library_applet_mode);
|
||||||
CreateGuestApplet(system, m_window_system, m_applet, applet_id, library_applet_mode);
|
|
||||||
}
|
}
|
||||||
if (!library_applet) {
|
if (!library_applet) {
|
||||||
library_applet =
|
library_applet = CreateFrontendApplet(system, m_applet, applet_id, library_applet_mode);
|
||||||
CreateFrontendApplet(system, m_window_system, m_applet, applet_id, library_applet_mode);
|
|
||||||
}
|
}
|
||||||
if (!library_applet) {
|
if (!library_applet) {
|
||||||
LOG_ERROR(Service_AM, "Applet doesn't exist! applet_id={}", applet_id);
|
LOG_ERROR(Service_AM, "Applet doesn't exist! applet_id={}", applet_id);
|
||||||
|
|
|
@ -12,12 +12,10 @@ namespace Service::AM {
|
||||||
struct Applet;
|
struct Applet;
|
||||||
class ILibraryAppletAccessor;
|
class ILibraryAppletAccessor;
|
||||||
class IStorage;
|
class IStorage;
|
||||||
class WindowSystem;
|
|
||||||
|
|
||||||
class ILibraryAppletCreator final : public ServiceFramework<ILibraryAppletCreator> {
|
class ILibraryAppletCreator final : public ServiceFramework<ILibraryAppletCreator> {
|
||||||
public:
|
public:
|
||||||
explicit ILibraryAppletCreator(Core::System& system_, std::shared_ptr<Applet> applet,
|
explicit ILibraryAppletCreator(Core::System& system_, std::shared_ptr<Applet> applet);
|
||||||
WindowSystem& window_system);
|
|
||||||
~ILibraryAppletCreator() override;
|
~ILibraryAppletCreator() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -31,7 +29,6 @@ private:
|
||||||
Result CreateHandleStorage(Out<SharedPointer<IStorage>> out_storage, s64 size,
|
Result CreateHandleStorage(Out<SharedPointer<IStorage>> out_storage, s64 size,
|
||||||
InCopyHandle<Kernel::KTransferMemory> transfer_memory_handle);
|
InCopyHandle<Kernel::KTransferMemory> transfer_memory_handle);
|
||||||
|
|
||||||
WindowSystem& m_window_system;
|
|
||||||
const std::shared_ptr<Applet> m_applet;
|
const std::shared_ptr<Applet> m_applet;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -19,9 +19,9 @@
|
||||||
namespace Service::AM {
|
namespace Service::AM {
|
||||||
|
|
||||||
ILibraryAppletProxy::ILibraryAppletProxy(Core::System& system_, std::shared_ptr<Applet> applet,
|
ILibraryAppletProxy::ILibraryAppletProxy(Core::System& system_, std::shared_ptr<Applet> applet,
|
||||||
Kernel::KProcess* process, WindowSystem& window_system)
|
Kernel::KProcess* process)
|
||||||
: ServiceFramework{system_, "ILibraryAppletProxy"},
|
: ServiceFramework{system_, "ILibraryAppletProxy"}, m_process{process}, m_applet{
|
||||||
m_window_system{window_system}, m_process{process}, m_applet{std::move(applet)} {
|
std::move(applet)} {
|
||||||
// clang-format off
|
// clang-format off
|
||||||
static const FunctionInfo functions[] = {
|
static const FunctionInfo functions[] = {
|
||||||
{0, D<&ILibraryAppletProxy::GetCommonStateGetter>, "GetCommonStateGetter"},
|
{0, D<&ILibraryAppletProxy::GetCommonStateGetter>, "GetCommonStateGetter"},
|
||||||
|
@ -75,7 +75,7 @@ Result ILibraryAppletProxy::GetDebugFunctions(
|
||||||
Result ILibraryAppletProxy::GetWindowController(
|
Result ILibraryAppletProxy::GetWindowController(
|
||||||
Out<SharedPointer<IWindowController>> out_window_controller) {
|
Out<SharedPointer<IWindowController>> out_window_controller) {
|
||||||
LOG_DEBUG(Service_AM, "called");
|
LOG_DEBUG(Service_AM, "called");
|
||||||
*out_window_controller = std::make_shared<IWindowController>(system, m_applet, m_window_system);
|
*out_window_controller = std::make_shared<IWindowController>(system, m_applet);
|
||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -96,8 +96,7 @@ Result ILibraryAppletProxy::GetCommonStateGetter(
|
||||||
Result ILibraryAppletProxy::GetLibraryAppletCreator(
|
Result ILibraryAppletProxy::GetLibraryAppletCreator(
|
||||||
Out<SharedPointer<ILibraryAppletCreator>> out_library_applet_creator) {
|
Out<SharedPointer<ILibraryAppletCreator>> out_library_applet_creator) {
|
||||||
LOG_DEBUG(Service_AM, "called");
|
LOG_DEBUG(Service_AM, "called");
|
||||||
*out_library_applet_creator =
|
*out_library_applet_creator = std::make_shared<ILibraryAppletCreator>(system, m_applet);
|
||||||
std::make_shared<ILibraryAppletCreator>(system, m_applet, m_window_system);
|
|
||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -119,8 +118,7 @@ Result ILibraryAppletProxy::GetAppletCommonFunctions(
|
||||||
Result ILibraryAppletProxy::GetHomeMenuFunctions(
|
Result ILibraryAppletProxy::GetHomeMenuFunctions(
|
||||||
Out<SharedPointer<IHomeMenuFunctions>> out_home_menu_functions) {
|
Out<SharedPointer<IHomeMenuFunctions>> out_home_menu_functions) {
|
||||||
LOG_DEBUG(Service_AM, "called");
|
LOG_DEBUG(Service_AM, "called");
|
||||||
*out_home_menu_functions =
|
*out_home_menu_functions = std::make_shared<IHomeMenuFunctions>(system, m_applet);
|
||||||
std::make_shared<IHomeMenuFunctions>(system, m_applet, m_window_system);
|
|
||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,12 +21,11 @@ class ILibraryAppletSelfAccessor;
|
||||||
class IProcessWindingController;
|
class IProcessWindingController;
|
||||||
class ISelfController;
|
class ISelfController;
|
||||||
class IWindowController;
|
class IWindowController;
|
||||||
class WindowSystem;
|
|
||||||
|
|
||||||
class ILibraryAppletProxy final : public ServiceFramework<ILibraryAppletProxy> {
|
class ILibraryAppletProxy final : public ServiceFramework<ILibraryAppletProxy> {
|
||||||
public:
|
public:
|
||||||
explicit ILibraryAppletProxy(Core::System& system_, std::shared_ptr<Applet> applet,
|
explicit ILibraryAppletProxy(Core::System& system_, std::shared_ptr<Applet> applet,
|
||||||
Kernel::KProcess* process, WindowSystem& window_system);
|
Kernel::KProcess* process);
|
||||||
~ILibraryAppletProxy();
|
~ILibraryAppletProxy();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -48,7 +47,6 @@ private:
|
||||||
Result GetGlobalStateController(
|
Result GetGlobalStateController(
|
||||||
Out<SharedPointer<IGlobalStateController>> out_global_state_controller);
|
Out<SharedPointer<IGlobalStateController>> out_global_state_controller);
|
||||||
|
|
||||||
WindowSystem& m_window_system;
|
|
||||||
Kernel::KProcess* const m_process;
|
Kernel::KProcess* const m_process;
|
||||||
const std::shared_ptr<Applet> m_applet;
|
const std::shared_ptr<Applet> m_applet;
|
||||||
};
|
};
|
||||||
|
|
|
@ -176,7 +176,8 @@ Result ILibraryAppletSelfAccessor::GetMainAppletStorageId(Out<FileSys::StorageId
|
||||||
|
|
||||||
Result ILibraryAppletSelfAccessor::ExitProcessAndReturn() {
|
Result ILibraryAppletSelfAccessor::ExitProcessAndReturn() {
|
||||||
LOG_INFO(Service_AM, "called");
|
LOG_INFO(Service_AM, "called");
|
||||||
m_applet->process->Terminate();
|
system.GetAppletManager().TerminateAndRemoveApplet(m_applet->aruid);
|
||||||
|
m_broker->SignalCompletion();
|
||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -86,7 +86,8 @@ ISelfController::~ISelfController() {
|
||||||
Result ISelfController::Exit() {
|
Result ISelfController::Exit() {
|
||||||
LOG_DEBUG(Service_AM, "called");
|
LOG_DEBUG(Service_AM, "called");
|
||||||
|
|
||||||
m_applet->process->Terminate();
|
// TODO
|
||||||
|
system.Exit();
|
||||||
|
|
||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
@ -94,16 +95,7 @@ Result ISelfController::Exit() {
|
||||||
Result ISelfController::LockExit() {
|
Result ISelfController::LockExit() {
|
||||||
LOG_DEBUG(Service_AM, "called");
|
LOG_DEBUG(Service_AM, "called");
|
||||||
|
|
||||||
std::scoped_lock lk{m_applet->lock};
|
|
||||||
|
|
||||||
if (m_applet->lifecycle_manager.GetExitRequested()) {
|
|
||||||
// With exit already requested, ignore and terminate immediately.
|
|
||||||
m_applet->process->Terminate();
|
|
||||||
} else {
|
|
||||||
// Otherwise, set exit lock state.
|
|
||||||
m_applet->exit_locked = true;
|
|
||||||
system.SetExitLocked(true);
|
system.SetExitLocked(true);
|
||||||
}
|
|
||||||
|
|
||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
@ -111,13 +103,10 @@ Result ISelfController::LockExit() {
|
||||||
Result ISelfController::UnlockExit() {
|
Result ISelfController::UnlockExit() {
|
||||||
LOG_DEBUG(Service_AM, "called");
|
LOG_DEBUG(Service_AM, "called");
|
||||||
|
|
||||||
std::scoped_lock lk{m_applet->lock};
|
|
||||||
|
|
||||||
m_applet->exit_locked = false;
|
|
||||||
system.SetExitLocked(false);
|
system.SetExitLocked(false);
|
||||||
|
|
||||||
if (m_applet->lifecycle_manager.GetExitRequested()) {
|
if (system.GetExitRequested()) {
|
||||||
m_applet->process->Terminate();
|
system.Exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
|
@ -166,7 +155,7 @@ Result ISelfController::SetOperationModeChangedNotification(bool enabled) {
|
||||||
LOG_INFO(Service_AM, "called, enabled={}", enabled);
|
LOG_INFO(Service_AM, "called, enabled={}", enabled);
|
||||||
|
|
||||||
std::scoped_lock lk{m_applet->lock};
|
std::scoped_lock lk{m_applet->lock};
|
||||||
m_applet->lifecycle_manager.SetOperationModeChangedNotificationEnabled(enabled);
|
m_applet->operation_mode_changed_notification_enabled = enabled;
|
||||||
|
|
||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
@ -175,18 +164,17 @@ Result ISelfController::SetPerformanceModeChangedNotification(bool enabled) {
|
||||||
LOG_INFO(Service_AM, "called, enabled={}", enabled);
|
LOG_INFO(Service_AM, "called, enabled={}", enabled);
|
||||||
|
|
||||||
std::scoped_lock lk{m_applet->lock};
|
std::scoped_lock lk{m_applet->lock};
|
||||||
m_applet->lifecycle_manager.SetPerformanceModeChangedNotificationEnabled(enabled);
|
m_applet->performance_mode_changed_notification_enabled = enabled;
|
||||||
|
|
||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ISelfController::SetFocusHandlingMode(bool notify, bool background, bool suspend) {
|
Result ISelfController::SetFocusHandlingMode(bool notify, bool background, bool suspend) {
|
||||||
LOG_INFO(Service_AM, "called, notify={} background={} suspend={}", notify, background, suspend);
|
LOG_WARNING(Service_AM, "(STUBBED) called, notify={} background={} suspend={}", notify,
|
||||||
|
background, suspend);
|
||||||
|
|
||||||
std::scoped_lock lk{m_applet->lock};
|
std::scoped_lock lk{m_applet->lock};
|
||||||
m_applet->lifecycle_manager.SetFocusStateChangedNotificationEnabled(notify);
|
m_applet->focus_handling_mode = {notify, background, suspend};
|
||||||
m_applet->lifecycle_manager.SetFocusHandlingMode(suspend);
|
|
||||||
m_applet->UpdateSuspensionStateLocked(true);
|
|
||||||
|
|
||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
@ -195,7 +183,7 @@ Result ISelfController::SetRestartMessageEnabled(bool enabled) {
|
||||||
LOG_INFO(Service_AM, "called, enabled={}", enabled);
|
LOG_INFO(Service_AM, "called, enabled={}", enabled);
|
||||||
|
|
||||||
std::scoped_lock lk{m_applet->lock};
|
std::scoped_lock lk{m_applet->lock};
|
||||||
m_applet->lifecycle_manager.SetResumeNotificationEnabled(enabled);
|
m_applet->restart_message_enabled = enabled;
|
||||||
|
|
||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
@ -214,8 +202,7 @@ Result ISelfController::SetOutOfFocusSuspendingEnabled(bool enabled) {
|
||||||
LOG_INFO(Service_AM, "called, enabled={}", enabled);
|
LOG_INFO(Service_AM, "called, enabled={}", enabled);
|
||||||
|
|
||||||
std::scoped_lock lk{m_applet->lock};
|
std::scoped_lock lk{m_applet->lock};
|
||||||
m_applet->lifecycle_manager.SetOutOfFocusSuspendingEnabled(enabled);
|
m_applet->out_of_focus_suspension_enabled = enabled;
|
||||||
m_applet->UpdateSuspensionStateLocked(false);
|
|
||||||
|
|
||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,9 +19,9 @@
|
||||||
namespace Service::AM {
|
namespace Service::AM {
|
||||||
|
|
||||||
ISystemAppletProxy::ISystemAppletProxy(Core::System& system_, std::shared_ptr<Applet> applet,
|
ISystemAppletProxy::ISystemAppletProxy(Core::System& system_, std::shared_ptr<Applet> applet,
|
||||||
Kernel::KProcess* process, WindowSystem& window_system)
|
Kernel::KProcess* process)
|
||||||
: ServiceFramework{system_, "ISystemAppletProxy"},
|
: ServiceFramework{system_, "ISystemAppletProxy"}, m_process{process}, m_applet{
|
||||||
m_window_system{window_system}, m_process{process}, m_applet{std::move(applet)} {
|
std::move(applet)} {
|
||||||
// clang-format off
|
// clang-format off
|
||||||
static const FunctionInfo functions[] = {
|
static const FunctionInfo functions[] = {
|
||||||
{0, D<&ISystemAppletProxy::GetCommonStateGetter>, "GetCommonStateGetter"},
|
{0, D<&ISystemAppletProxy::GetCommonStateGetter>, "GetCommonStateGetter"},
|
||||||
|
@ -75,7 +75,7 @@ Result ISystemAppletProxy::GetDebugFunctions(
|
||||||
Result ISystemAppletProxy::GetWindowController(
|
Result ISystemAppletProxy::GetWindowController(
|
||||||
Out<SharedPointer<IWindowController>> out_window_controller) {
|
Out<SharedPointer<IWindowController>> out_window_controller) {
|
||||||
LOG_DEBUG(Service_AM, "called");
|
LOG_DEBUG(Service_AM, "called");
|
||||||
*out_window_controller = std::make_shared<IWindowController>(system, m_applet, m_window_system);
|
*out_window_controller = std::make_shared<IWindowController>(system, m_applet);
|
||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -96,15 +96,14 @@ Result ISystemAppletProxy::GetCommonStateGetter(
|
||||||
Result ISystemAppletProxy::GetLibraryAppletCreator(
|
Result ISystemAppletProxy::GetLibraryAppletCreator(
|
||||||
Out<SharedPointer<ILibraryAppletCreator>> out_library_applet_creator) {
|
Out<SharedPointer<ILibraryAppletCreator>> out_library_applet_creator) {
|
||||||
LOG_DEBUG(Service_AM, "called");
|
LOG_DEBUG(Service_AM, "called");
|
||||||
*out_library_applet_creator =
|
*out_library_applet_creator = std::make_shared<ILibraryAppletCreator>(system, m_applet);
|
||||||
std::make_shared<ILibraryAppletCreator>(system, m_applet, m_window_system);
|
|
||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ISystemAppletProxy::GetApplicationCreator(
|
Result ISystemAppletProxy::GetApplicationCreator(
|
||||||
Out<SharedPointer<IApplicationCreator>> out_application_creator) {
|
Out<SharedPointer<IApplicationCreator>> out_application_creator) {
|
||||||
LOG_DEBUG(Service_AM, "called");
|
LOG_DEBUG(Service_AM, "called");
|
||||||
*out_application_creator = std::make_shared<IApplicationCreator>(system, m_window_system);
|
*out_application_creator = std::make_shared<IApplicationCreator>(system);
|
||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -118,8 +117,7 @@ Result ISystemAppletProxy::GetAppletCommonFunctions(
|
||||||
Result ISystemAppletProxy::GetHomeMenuFunctions(
|
Result ISystemAppletProxy::GetHomeMenuFunctions(
|
||||||
Out<SharedPointer<IHomeMenuFunctions>> out_home_menu_functions) {
|
Out<SharedPointer<IHomeMenuFunctions>> out_home_menu_functions) {
|
||||||
LOG_DEBUG(Service_AM, "called");
|
LOG_DEBUG(Service_AM, "called");
|
||||||
*out_home_menu_functions =
|
*out_home_menu_functions = std::make_shared<IHomeMenuFunctions>(system, m_applet);
|
||||||
std::make_shared<IHomeMenuFunctions>(system, m_applet, m_window_system);
|
|
||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,12 +21,11 @@ class ILibraryAppletCreator;
|
||||||
class IProcessWindingController;
|
class IProcessWindingController;
|
||||||
class ISelfController;
|
class ISelfController;
|
||||||
class IWindowController;
|
class IWindowController;
|
||||||
class WindowSystem;
|
|
||||||
|
|
||||||
class ISystemAppletProxy final : public ServiceFramework<ISystemAppletProxy> {
|
class ISystemAppletProxy final : public ServiceFramework<ISystemAppletProxy> {
|
||||||
public:
|
public:
|
||||||
explicit ISystemAppletProxy(Core::System& system, std::shared_ptr<Applet> applet,
|
explicit ISystemAppletProxy(Core::System& system, std::shared_ptr<Applet> applet,
|
||||||
Kernel::KProcess* process, WindowSystem& window_system);
|
Kernel::KProcess* process);
|
||||||
~ISystemAppletProxy();
|
~ISystemAppletProxy();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -47,7 +46,6 @@ private:
|
||||||
Result GetGlobalStateController(
|
Result GetGlobalStateController(
|
||||||
Out<SharedPointer<IGlobalStateController>> out_global_state_controller);
|
Out<SharedPointer<IGlobalStateController>> out_global_state_controller);
|
||||||
|
|
||||||
WindowSystem& m_window_system;
|
|
||||||
Kernel::KProcess* const m_process;
|
Kernel::KProcess* const m_process;
|
||||||
const std::shared_ptr<Applet> m_applet;
|
const std::shared_ptr<Applet> m_applet;
|
||||||
};
|
};
|
||||||
|
|
|
@ -4,15 +4,12 @@
|
||||||
#include "core/hle/service/am/applet.h"
|
#include "core/hle/service/am/applet.h"
|
||||||
#include "core/hle/service/am/applet_manager.h"
|
#include "core/hle/service/am/applet_manager.h"
|
||||||
#include "core/hle/service/am/service/window_controller.h"
|
#include "core/hle/service/am/service/window_controller.h"
|
||||||
#include "core/hle/service/am/window_system.h"
|
|
||||||
#include "core/hle/service/cmif_serialization.h"
|
#include "core/hle/service/cmif_serialization.h"
|
||||||
|
|
||||||
namespace Service::AM {
|
namespace Service::AM {
|
||||||
|
|
||||||
IWindowController::IWindowController(Core::System& system_, std::shared_ptr<Applet> applet,
|
IWindowController::IWindowController(Core::System& system_, std::shared_ptr<Applet> applet)
|
||||||
WindowSystem& window_system)
|
: ServiceFramework{system_, "IWindowController"}, m_applet{std::move(applet)} {
|
||||||
: ServiceFramework{system_, "IWindowController"},
|
|
||||||
m_window_system{window_system}, m_applet{std::move(applet)} {
|
|
||||||
// clang-format off
|
// clang-format off
|
||||||
static const FunctionInfo functions[] = {
|
static const FunctionInfo functions[] = {
|
||||||
{0, nullptr, "CreateWindow"},
|
{0, nullptr, "CreateWindow"},
|
||||||
|
@ -66,9 +63,17 @@ Result IWindowController::RejectToChangeIntoBackground() {
|
||||||
}
|
}
|
||||||
|
|
||||||
Result IWindowController::SetAppletWindowVisibility(bool visible) {
|
Result IWindowController::SetAppletWindowVisibility(bool visible) {
|
||||||
LOG_INFO(Service_AM, "called");
|
m_applet->display_layer_manager.SetWindowVisibility(visible);
|
||||||
|
m_applet->hid_registration.EnableAppletToGetInput(visible);
|
||||||
|
|
||||||
m_window_system.RequestAppletVisibilityState(*m_applet, visible);
|
if (visible) {
|
||||||
|
m_applet->message_queue.PushMessage(AppletMessage::ChangeIntoForeground);
|
||||||
|
m_applet->focus_state = FocusState::InFocus;
|
||||||
|
} else {
|
||||||
|
m_applet->focus_state = FocusState::NotInFocus;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_applet->message_queue.PushMessage(AppletMessage::FocusStateChanged);
|
||||||
|
|
||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,12 +9,10 @@
|
||||||
namespace Service::AM {
|
namespace Service::AM {
|
||||||
|
|
||||||
struct Applet;
|
struct Applet;
|
||||||
class WindowSystem;
|
|
||||||
|
|
||||||
class IWindowController final : public ServiceFramework<IWindowController> {
|
class IWindowController final : public ServiceFramework<IWindowController> {
|
||||||
public:
|
public:
|
||||||
explicit IWindowController(Core::System& system_, std::shared_ptr<Applet> applet,
|
explicit IWindowController(Core::System& system_, std::shared_ptr<Applet> applet);
|
||||||
WindowSystem& window_system);
|
|
||||||
~IWindowController() override;
|
~IWindowController() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -26,7 +24,6 @@ private:
|
||||||
Result SetAppletWindowVisibility(bool visible);
|
Result SetAppletWindowVisibility(bool visible);
|
||||||
Result SetAppletGpuTimeSlice(s64 time_slice);
|
Result SetAppletGpuTimeSlice(s64 time_slice);
|
||||||
|
|
||||||
WindowSystem& m_window_system;
|
|
||||||
const std::shared_ptr<Applet> m_applet;
|
const std::shared_ptr<Applet> m_applet;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
53
src/core/hle/service/hid/active_vibration_device_list.cpp
Executable file
53
src/core/hle/service/hid/active_vibration_device_list.cpp
Executable file
|
@ -0,0 +1,53 @@
|
||||||
|
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
|
#include "common/logging/log.h"
|
||||||
|
#include "core/hle/service/cmif_serialization.h"
|
||||||
|
#include "core/hle/service/hid/active_vibration_device_list.h"
|
||||||
|
#include "hid_core/hid_result.h"
|
||||||
|
#include "hid_core/hid_util.h"
|
||||||
|
#include "hid_core/resource_manager.h"
|
||||||
|
#include "hid_core/resources/vibration/vibration_device.h"
|
||||||
|
|
||||||
|
namespace Service::HID {
|
||||||
|
|
||||||
|
IActiveVibrationDeviceList::IActiveVibrationDeviceList(Core::System& system_,
|
||||||
|
std::shared_ptr<ResourceManager> resource)
|
||||||
|
: ServiceFramework{system_, "IActiveVibrationDeviceList"}, resource_manager(resource) {
|
||||||
|
// clang-format off
|
||||||
|
static const FunctionInfo functions[] = {
|
||||||
|
{0, C<&IActiveVibrationDeviceList::ActivateVibrationDevice>, "ActivateVibrationDevice"},
|
||||||
|
};
|
||||||
|
// clang-format on
|
||||||
|
|
||||||
|
RegisterHandlers(functions);
|
||||||
|
}
|
||||||
|
|
||||||
|
IActiveVibrationDeviceList::~IActiveVibrationDeviceList() = default;
|
||||||
|
|
||||||
|
Result IActiveVibrationDeviceList::ActivateVibrationDevice(
|
||||||
|
Core::HID::VibrationDeviceHandle vibration_device_handle) {
|
||||||
|
LOG_DEBUG(Service_HID, "called, npad_type={}, npad_id={}, device_index={}",
|
||||||
|
vibration_device_handle.npad_type, vibration_device_handle.npad_id,
|
||||||
|
vibration_device_handle.device_index);
|
||||||
|
|
||||||
|
std::scoped_lock lock{mutex};
|
||||||
|
|
||||||
|
R_TRY(IsVibrationHandleValid(vibration_device_handle));
|
||||||
|
|
||||||
|
for (std::size_t i = 0; i < list_size; i++) {
|
||||||
|
if (vibration_device_handle.device_index == vibration_device_list[i].device_index &&
|
||||||
|
vibration_device_handle.npad_id == vibration_device_list[i].npad_id &&
|
||||||
|
vibration_device_handle.npad_type == vibration_device_list[i].npad_type) {
|
||||||
|
R_SUCCEED();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
R_UNLESS(list_size < MaxVibrationDevicesHandles, ResultVibrationDeviceIndexOutOfRange);
|
||||||
|
R_TRY(resource_manager->GetVibrationDevice(vibration_device_handle)->Activate());
|
||||||
|
|
||||||
|
vibration_device_list[list_size++] = vibration_device_handle;
|
||||||
|
R_SUCCEED();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Service::HID
|
39
src/core/hle/service/hid/active_vibration_device_list.h
Executable file
39
src/core/hle/service/hid/active_vibration_device_list.h
Executable file
|
@ -0,0 +1,39 @@
|
||||||
|
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <array>
|
||||||
|
#include <memory>
|
||||||
|
#include <mutex>
|
||||||
|
|
||||||
|
#include "core/hle/service/cmif_types.h"
|
||||||
|
#include "core/hle/service/service.h"
|
||||||
|
#include "hid_core/hid_types.h"
|
||||||
|
|
||||||
|
namespace Core {
|
||||||
|
class System;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace Service::HID {
|
||||||
|
class ResourceManager;
|
||||||
|
|
||||||
|
class IActiveVibrationDeviceList final : public ServiceFramework<IActiveVibrationDeviceList> {
|
||||||
|
public:
|
||||||
|
explicit IActiveVibrationDeviceList(Core::System& system_,
|
||||||
|
std::shared_ptr<ResourceManager> resource);
|
||||||
|
~IActiveVibrationDeviceList() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
static constexpr std::size_t MaxVibrationDevicesHandles{0x100};
|
||||||
|
|
||||||
|
Result ActivateVibrationDevice(Core::HID::VibrationDeviceHandle vibration_device_handle);
|
||||||
|
|
||||||
|
mutable std::mutex mutex;
|
||||||
|
std::size_t list_size{};
|
||||||
|
std::array<Core::HID::VibrationDeviceHandle, MaxVibrationDevicesHandles>
|
||||||
|
vibration_device_list{};
|
||||||
|
std::shared_ptr<ResourceManager> resource_manager;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Service::HID
|
34
src/core/hle/service/hid/applet_resource.cpp
Executable file
34
src/core/hle/service/hid/applet_resource.cpp
Executable file
|
@ -0,0 +1,34 @@
|
||||||
|
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
|
#include "common/logging/log.h"
|
||||||
|
#include "core/hle/kernel/k_shared_memory.h"
|
||||||
|
#include "core/hle/service/cmif_serialization.h"
|
||||||
|
#include "core/hle/service/hid/applet_resource.h"
|
||||||
|
#include "hid_core/resource_manager.h"
|
||||||
|
|
||||||
|
namespace Service::HID {
|
||||||
|
|
||||||
|
IAppletResource::IAppletResource(Core::System& system_, std::shared_ptr<ResourceManager> resource,
|
||||||
|
u64 applet_resource_user_id)
|
||||||
|
: ServiceFramework{system_, "IAppletResource"}, aruid{applet_resource_user_id},
|
||||||
|
resource_manager{resource} {
|
||||||
|
static const FunctionInfo functions[] = {
|
||||||
|
{0, C<&IAppletResource::GetSharedMemoryHandle>, "GetSharedMemoryHandle"},
|
||||||
|
};
|
||||||
|
RegisterHandlers(functions);
|
||||||
|
}
|
||||||
|
|
||||||
|
IAppletResource::~IAppletResource() {
|
||||||
|
resource_manager->FreeAppletResourceId(aruid);
|
||||||
|
}
|
||||||
|
|
||||||
|
Result IAppletResource::GetSharedMemoryHandle(
|
||||||
|
OutCopyHandle<Kernel::KSharedMemory> out_shared_memory_handle) {
|
||||||
|
const auto result = resource_manager->GetSharedMemoryHandle(out_shared_memory_handle, aruid);
|
||||||
|
|
||||||
|
LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}, result=0x{:X}", aruid, result.raw);
|
||||||
|
R_RETURN(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Service::HID
|
36
src/core/hle/service/hid/applet_resource.h
Executable file
36
src/core/hle/service/hid/applet_resource.h
Executable file
|
@ -0,0 +1,36 @@
|
||||||
|
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
#include "common/common_types.h"
|
||||||
|
#include "core/hle/service/cmif_types.h"
|
||||||
|
#include "core/hle/service/service.h"
|
||||||
|
|
||||||
|
namespace Core {
|
||||||
|
class System;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace Kernel {
|
||||||
|
class KSharedMemory;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace Service::HID {
|
||||||
|
class ResourceManager;
|
||||||
|
|
||||||
|
class IAppletResource final : public ServiceFramework<IAppletResource> {
|
||||||
|
public:
|
||||||
|
explicit IAppletResource(Core::System& system_, std::shared_ptr<ResourceManager> resource,
|
||||||
|
u64 applet_resource_user_id);
|
||||||
|
~IAppletResource() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
Result GetSharedMemoryHandle(OutCopyHandle<Kernel::KSharedMemory> out_shared_memory_handle);
|
||||||
|
|
||||||
|
u64 aruid{};
|
||||||
|
std::shared_ptr<ResourceManager> resource_manager;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Service::HID
|
|
@ -23,7 +23,11 @@ void LoopProcess(Core::System& system) {
|
||||||
std::shared_ptr<ResourceManager> resource_manager =
|
std::shared_ptr<ResourceManager> resource_manager =
|
||||||
std::make_shared<ResourceManager>(system, firmware_settings);
|
std::make_shared<ResourceManager>(system, firmware_settings);
|
||||||
|
|
||||||
|
// TODO: Remove this hack when am is emulated properly.
|
||||||
resource_manager->Initialize();
|
resource_manager->Initialize();
|
||||||
|
resource_manager->RegisterAppletResourceUserId(system.ApplicationProcess()->GetProcessId(),
|
||||||
|
true);
|
||||||
|
resource_manager->SetAruidValidForVibration(system.ApplicationProcess()->GetProcessId(), true);
|
||||||
|
|
||||||
server_manager->RegisterNamedService(
|
server_manager->RegisterNamedService(
|
||||||
"hid", std::make_shared<IHidServer>(system, resource_manager, firmware_settings));
|
"hid", std::make_shared<IHidServer>(system, resource_manager, firmware_settings));
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -6,12 +6,20 @@
|
||||||
#include "core/hle/service/cmif_types.h"
|
#include "core/hle/service/cmif_types.h"
|
||||||
#include "core/hle/service/service.h"
|
#include "core/hle/service/service.h"
|
||||||
#include "hid_core/hid_types.h"
|
#include "hid_core/hid_types.h"
|
||||||
|
#include "hid_core/resources/npad/npad_types.h"
|
||||||
|
#include "hid_core/resources/palma/palma.h"
|
||||||
|
|
||||||
namespace Core {
|
namespace Core {
|
||||||
class System;
|
class System;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace Kernel {
|
||||||
|
class KReadableEvent;
|
||||||
|
}
|
||||||
|
|
||||||
namespace Service::HID {
|
namespace Service::HID {
|
||||||
|
class IActiveVibrationDeviceList;
|
||||||
|
class IAppletResource;
|
||||||
class ResourceManager;
|
class ResourceManager;
|
||||||
class HidFirmwareSettings;
|
class HidFirmwareSettings;
|
||||||
|
|
||||||
|
@ -24,128 +32,232 @@ public:
|
||||||
std::shared_ptr<ResourceManager> GetResourceManager();
|
std::shared_ptr<ResourceManager> GetResourceManager();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void CreateAppletResource(HLERequestContext& ctx);
|
Result CreateAppletResource(OutInterface<IAppletResource> out_applet_resource,
|
||||||
void ActivateDebugPad(HLERequestContext& ctx);
|
ClientAppletResourceUserId aruid);
|
||||||
void ActivateTouchScreen(HLERequestContext& ctx);
|
Result ActivateDebugPad(ClientAppletResourceUserId aruid);
|
||||||
void ActivateMouse(HLERequestContext& ctx);
|
Result ActivateTouchScreen(ClientAppletResourceUserId aruid);
|
||||||
void ActivateKeyboard(HLERequestContext& ctx);
|
Result ActivateMouse(ClientAppletResourceUserId aruid);
|
||||||
void SendKeyboardLockKeyEvent(HLERequestContext& ctx);
|
Result ActivateKeyboard(ClientAppletResourceUserId aruid);
|
||||||
void AcquireXpadIdEventHandle(HLERequestContext& ctx);
|
Result SendKeyboardLockKeyEvent(u32 flags);
|
||||||
void ReleaseXpadIdEventHandle(HLERequestContext& ctx);
|
Result AcquireXpadIdEventHandle(OutCopyHandle<Kernel::KReadableEvent> out_event,
|
||||||
void ActivateXpad(HLERequestContext& ctx);
|
ClientAppletResourceUserId aruid);
|
||||||
void GetXpadIds(HLERequestContext& ctx);
|
Result ReleaseXpadIdEventHandle(ClientAppletResourceUserId aruid);
|
||||||
void ActivateJoyXpad(HLERequestContext& ctx);
|
Result ActivateXpad(u32 basic_xpad_id, ClientAppletResourceUserId aruid);
|
||||||
void GetJoyXpadLifoHandle(HLERequestContext& ctx);
|
Result GetXpadIds(Out<u64> out_count, OutArray<u32, BufferAttr_HipcPointer> out_basic_pad_ids);
|
||||||
void GetJoyXpadIds(HLERequestContext& ctx);
|
Result ActivateJoyXpad(u32 joy_xpad_id);
|
||||||
void ActivateSixAxisSensor(HLERequestContext& ctx);
|
Result GetJoyXpadLifoHandle(OutCopyHandle<Kernel::KSharedMemory> out_shared_memory_handle,
|
||||||
void DeactivateSixAxisSensor(HLERequestContext& ctx);
|
u32 joy_xpad_id);
|
||||||
void GetSixAxisSensorLifoHandle(HLERequestContext& ctx);
|
Result GetJoyXpadIds(Out<s64> out_basic_xpad_id_count);
|
||||||
void ActivateJoySixAxisSensor(HLERequestContext& ctx);
|
Result ActivateSixAxisSensor(u32 joy_xpad_id);
|
||||||
void DeactivateJoySixAxisSensor(HLERequestContext& ctx);
|
Result DeactivateSixAxisSensor(u32 joy_xpad_id);
|
||||||
void GetJoySixAxisSensorLifoHandle(HLERequestContext& ctx);
|
Result GetSixAxisSensorLifoHandle(OutCopyHandle<Kernel::KSharedMemory> out_shared_memory_handle,
|
||||||
void StartSixAxisSensor(HLERequestContext& ctx);
|
u32 joy_xpad_id);
|
||||||
void StopSixAxisSensor(HLERequestContext& ctx);
|
Result ActivateJoySixAxisSensor(u32 joy_xpad_id);
|
||||||
void IsSixAxisSensorFusionEnabled(HLERequestContext& ctx);
|
Result DeactivateJoySixAxisSensor(u32 joy_xpad_id);
|
||||||
void EnableSixAxisSensorFusion(HLERequestContext& ctx);
|
Result GetJoySixAxisSensorLifoHandle(
|
||||||
void SetSixAxisSensorFusionParameters(HLERequestContext& ctx);
|
OutCopyHandle<Kernel::KSharedMemory> out_shared_memory_handle, u32 joy_xpad_id);
|
||||||
void GetSixAxisSensorFusionParameters(HLERequestContext& ctx);
|
Result StartSixAxisSensor(Core::HID::SixAxisSensorHandle sixaxis_handle,
|
||||||
void ResetSixAxisSensorFusionParameters(HLERequestContext& ctx);
|
ClientAppletResourceUserId aruid);
|
||||||
void SetGyroscopeZeroDriftMode(HLERequestContext& ctx);
|
Result StopSixAxisSensor(Core::HID::SixAxisSensorHandle sixaxis_handle,
|
||||||
void GetGyroscopeZeroDriftMode(HLERequestContext& ctx);
|
ClientAppletResourceUserId aruid);
|
||||||
void ResetGyroscopeZeroDriftMode(HLERequestContext& ctx);
|
Result IsSixAxisSensorFusionEnabled(Out<bool> out_is_enabled,
|
||||||
void IsSixAxisSensorAtRest(HLERequestContext& ctx);
|
Core::HID::SixAxisSensorHandle sixaxis_handle,
|
||||||
void IsFirmwareUpdateAvailableForSixAxisSensor(HLERequestContext& ctx);
|
ClientAppletResourceUserId aruid);
|
||||||
void EnableSixAxisSensorUnalteredPassthrough(HLERequestContext& ctx);
|
Result EnableSixAxisSensorFusion(bool is_enabled, Core::HID::SixAxisSensorHandle sixaxis_handle,
|
||||||
void IsSixAxisSensorUnalteredPassthroughEnabled(HLERequestContext& ctx);
|
ClientAppletResourceUserId aruid);
|
||||||
void LoadSixAxisSensorCalibrationParameter(HLERequestContext& ctx);
|
Result SetSixAxisSensorFusionParameters(Core::HID::SixAxisSensorHandle sixaxis_handle,
|
||||||
void GetSixAxisSensorIcInformation(HLERequestContext& ctx);
|
Core::HID::SixAxisSensorFusionParameters sixaxis_fusion,
|
||||||
void ResetIsSixAxisSensorDeviceNewlyAssigned(HLERequestContext& ctx);
|
ClientAppletResourceUserId aruid);
|
||||||
void ActivateGesture(HLERequestContext& ctx);
|
Result GetSixAxisSensorFusionParameters(
|
||||||
void SetSupportedNpadStyleSet(HLERequestContext& ctx);
|
Out<Core::HID::SixAxisSensorFusionParameters> out_fusion_parameters,
|
||||||
void GetSupportedNpadStyleSet(HLERequestContext& ctx);
|
Core::HID::SixAxisSensorHandle sixaxis_handle, ClientAppletResourceUserId aruid);
|
||||||
void SetSupportedNpadIdType(HLERequestContext& ctx);
|
Result ResetSixAxisSensorFusionParameters(Core::HID::SixAxisSensorHandle sixaxis_handle,
|
||||||
void ActivateNpad(HLERequestContext& ctx);
|
ClientAppletResourceUserId aruid);
|
||||||
void DeactivateNpad(HLERequestContext& ctx);
|
Result SetGyroscopeZeroDriftMode(Core::HID::SixAxisSensorHandle sixaxis_handle,
|
||||||
void AcquireNpadStyleSetUpdateEventHandle(HLERequestContext& ctx);
|
Core::HID::GyroscopeZeroDriftMode drift_mode,
|
||||||
void DisconnectNpad(HLERequestContext& ctx);
|
ClientAppletResourceUserId aruid);
|
||||||
|
Result GetGyroscopeZeroDriftMode(Out<Core::HID::GyroscopeZeroDriftMode> out_drift_mode,
|
||||||
|
Core::HID::SixAxisSensorHandle sixaxis_handle,
|
||||||
|
ClientAppletResourceUserId aruid);
|
||||||
|
Result ResetGyroscopeZeroDriftMode(Core::HID::SixAxisSensorHandle sixaxis_handle,
|
||||||
|
ClientAppletResourceUserId aruid);
|
||||||
|
Result IsSixAxisSensorAtRest(Out<bool> out_is_at_rest,
|
||||||
|
Core::HID::SixAxisSensorHandle sixaxis_handle,
|
||||||
|
ClientAppletResourceUserId aruid);
|
||||||
|
Result IsFirmwareUpdateAvailableForSixAxisSensor(Out<bool> out_is_firmware_available,
|
||||||
|
Core::HID::SixAxisSensorHandle sixaxis_handle,
|
||||||
|
ClientAppletResourceUserId aruid);
|
||||||
|
Result EnableSixAxisSensorUnalteredPassthrough(bool is_enabled,
|
||||||
|
Core::HID::SixAxisSensorHandle sixaxis_handle,
|
||||||
|
ClientAppletResourceUserId aruid);
|
||||||
|
Result IsSixAxisSensorUnalteredPassthroughEnabled(Out<bool> out_is_enabled,
|
||||||
|
Core::HID::SixAxisSensorHandle sixaxis_handle,
|
||||||
|
ClientAppletResourceUserId aruid);
|
||||||
|
Result LoadSixAxisSensorCalibrationParameter(
|
||||||
|
OutLargeData<Core::HID::SixAxisSensorCalibrationParameter, BufferAttr_HipcMapAlias>
|
||||||
|
out_calibration,
|
||||||
|
Core::HID::SixAxisSensorHandle sixaxis_handle, ClientAppletResourceUserId aruid);
|
||||||
|
Result GetSixAxisSensorIcInformation(
|
||||||
|
OutLargeData<Core::HID::SixAxisSensorIcInformation, BufferAttr_HipcPointer>
|
||||||
|
out_ic_information,
|
||||||
|
Core::HID::SixAxisSensorHandle sixaxis_handle, ClientAppletResourceUserId aruid);
|
||||||
|
Result ResetIsSixAxisSensorDeviceNewlyAssigned(Core::HID::SixAxisSensorHandle sixaxis_handle,
|
||||||
|
ClientAppletResourceUserId aruid);
|
||||||
|
Result ActivateGesture(u32 basic_gesture_id, ClientAppletResourceUserId aruid);
|
||||||
|
Result SetSupportedNpadStyleSet(Core::HID::NpadStyleSet supported_style_set,
|
||||||
|
ClientAppletResourceUserId aruid);
|
||||||
|
Result GetSupportedNpadStyleSet(Out<Core::HID::NpadStyleSet> out_supported_style_set,
|
||||||
|
ClientAppletResourceUserId aruid);
|
||||||
|
Result SetSupportedNpadIdType(
|
||||||
|
ClientAppletResourceUserId aruid,
|
||||||
|
InArray<Core::HID::NpadIdType, BufferAttr_HipcPointer> supported_npad_list);
|
||||||
|
Result ActivateNpad(ClientAppletResourceUserId aruid);
|
||||||
|
Result DeactivateNpad(ClientAppletResourceUserId aruid);
|
||||||
|
Result AcquireNpadStyleSetUpdateEventHandle(OutCopyHandle<Kernel::KReadableEvent> out_event,
|
||||||
|
Core::HID::NpadIdType npad_id,
|
||||||
|
ClientAppletResourceUserId aruid, u64 unknown);
|
||||||
|
Result DisconnectNpad(Core::HID::NpadIdType npad_id, ClientAppletResourceUserId aruid);
|
||||||
Result GetPlayerLedPattern(Out<Core::HID::LedPattern> out_led_pattern,
|
Result GetPlayerLedPattern(Out<Core::HID::LedPattern> out_led_pattern,
|
||||||
Core::HID::NpadIdType npad_id);
|
Core::HID::NpadIdType npad_id);
|
||||||
void ActivateNpadWithRevision(HLERequestContext& ctx);
|
Result ActivateNpadWithRevision(NpadRevision revision, ClientAppletResourceUserId aruid);
|
||||||
void SetNpadJoyHoldType(HLERequestContext& ctx);
|
Result SetNpadJoyHoldType(ClientAppletResourceUserId aruid, NpadJoyHoldType hold_type);
|
||||||
void GetNpadJoyHoldType(HLERequestContext& ctx);
|
Result GetNpadJoyHoldType(Out<NpadJoyHoldType> out_hold_type, ClientAppletResourceUserId aruid);
|
||||||
void SetNpadJoyAssignmentModeSingleByDefault(HLERequestContext& ctx);
|
Result SetNpadJoyAssignmentModeSingleByDefault(Core::HID::NpadIdType npad_id,
|
||||||
void SetNpadJoyAssignmentModeSingle(HLERequestContext& ctx);
|
ClientAppletResourceUserId aruid);
|
||||||
void SetNpadJoyAssignmentModeDual(HLERequestContext& ctx);
|
Result SetNpadJoyAssignmentModeSingle(Core::HID::NpadIdType npad_id,
|
||||||
void MergeSingleJoyAsDualJoy(HLERequestContext& ctx);
|
ClientAppletResourceUserId aruid,
|
||||||
void StartLrAssignmentMode(HLERequestContext& ctx);
|
NpadJoyDeviceType npad_joy_device_type);
|
||||||
void StopLrAssignmentMode(HLERequestContext& ctx);
|
Result SetNpadJoyAssignmentModeDual(Core::HID::NpadIdType npad_id,
|
||||||
void SetNpadHandheldActivationMode(HLERequestContext& ctx);
|
ClientAppletResourceUserId aruid);
|
||||||
void GetNpadHandheldActivationMode(HLERequestContext& ctx);
|
Result MergeSingleJoyAsDualJoy(Core::HID::NpadIdType npad_id_1, Core::HID::NpadIdType npad_id_2,
|
||||||
void SwapNpadAssignment(HLERequestContext& ctx);
|
ClientAppletResourceUserId aruid);
|
||||||
void IsUnintendedHomeButtonInputProtectionEnabled(HLERequestContext& ctx);
|
Result StartLrAssignmentMode(ClientAppletResourceUserId aruid);
|
||||||
void EnableUnintendedHomeButtonInputProtection(HLERequestContext& ctx);
|
Result StopLrAssignmentMode(ClientAppletResourceUserId aruid);
|
||||||
void SetNpadJoyAssignmentModeSingleWithDestination(HLERequestContext& ctx);
|
Result SetNpadHandheldActivationMode(ClientAppletResourceUserId aruid,
|
||||||
void SetNpadAnalogStickUseCenterClamp(HLERequestContext& ctx);
|
NpadHandheldActivationMode activation_mode);
|
||||||
void SetNpadCaptureButtonAssignment(HLERequestContext& ctx);
|
Result GetNpadHandheldActivationMode(Out<NpadHandheldActivationMode> out_activation_mode,
|
||||||
void ClearNpadCaptureButtonAssignment(HLERequestContext& ctx);
|
ClientAppletResourceUserId aruid);
|
||||||
void GetVibrationDeviceInfo(HLERequestContext& ctx);
|
Result SwapNpadAssignment(Core::HID::NpadIdType npad_id_1, Core::HID::NpadIdType npad_id_2,
|
||||||
void SendVibrationValue(HLERequestContext& ctx);
|
ClientAppletResourceUserId aruid);
|
||||||
void GetActualVibrationValue(HLERequestContext& ctx);
|
Result IsUnintendedHomeButtonInputProtectionEnabled(Out<bool> out_is_enabled,
|
||||||
void CreateActiveVibrationDeviceList(HLERequestContext& ctx);
|
Core::HID::NpadIdType npad_id,
|
||||||
void PermitVibration(HLERequestContext& ctx);
|
ClientAppletResourceUserId aruid);
|
||||||
void IsVibrationPermitted(HLERequestContext& ctx);
|
Result EnableUnintendedHomeButtonInputProtection(bool is_enabled, Core::HID::NpadIdType npad_id,
|
||||||
void SendVibrationValues(HLERequestContext& ctx);
|
ClientAppletResourceUserId aruid);
|
||||||
void SendVibrationGcErmCommand(HLERequestContext& ctx);
|
Result SetNpadJoyAssignmentModeSingleWithDestination(Out<bool> out_is_reassigned,
|
||||||
void GetActualVibrationGcErmCommand(HLERequestContext& ctx);
|
Out<Core::HID::NpadIdType> out_new_npad_id,
|
||||||
void BeginPermitVibrationSession(HLERequestContext& ctx);
|
Core::HID::NpadIdType npad_id,
|
||||||
void EndPermitVibrationSession(HLERequestContext& ctx);
|
ClientAppletResourceUserId aruid,
|
||||||
void IsVibrationDeviceMounted(HLERequestContext& ctx);
|
NpadJoyDeviceType npad_joy_device_type);
|
||||||
void SendVibrationValueInBool(HLERequestContext& ctx);
|
Result SetNpadAnalogStickUseCenterClamp(bool use_center_clamp,
|
||||||
void ActivateConsoleSixAxisSensor(HLERequestContext& ctx);
|
ClientAppletResourceUserId aruid);
|
||||||
void StartConsoleSixAxisSensor(HLERequestContext& ctx);
|
Result SetNpadCaptureButtonAssignment(Core::HID::NpadStyleSet npad_styleset,
|
||||||
void StopConsoleSixAxisSensor(HLERequestContext& ctx);
|
ClientAppletResourceUserId aruid,
|
||||||
void ActivateSevenSixAxisSensor(HLERequestContext& ctx);
|
Core::HID::NpadButton button);
|
||||||
void StartSevenSixAxisSensor(HLERequestContext& ctx);
|
Result ClearNpadCaptureButtonAssignment(ClientAppletResourceUserId aruid);
|
||||||
void StopSevenSixAxisSensor(HLERequestContext& ctx);
|
Result GetVibrationDeviceInfo(Out<Core::HID::VibrationDeviceInfo> out_vibration_device_info,
|
||||||
void InitializeSevenSixAxisSensor(HLERequestContext& ctx);
|
Core::HID::VibrationDeviceHandle vibration_device_handle);
|
||||||
void FinalizeSevenSixAxisSensor(HLERequestContext& ctx);
|
Result SendVibrationValue(Core::HID::VibrationDeviceHandle vibration_device_handle,
|
||||||
void ResetSevenSixAxisSensorTimestamp(HLERequestContext& ctx);
|
Core::HID::VibrationValue vibration_value,
|
||||||
void IsUsbFullKeyControllerEnabled(HLERequestContext& ctx);
|
ClientAppletResourceUserId aruid);
|
||||||
void GetPalmaConnectionHandle(HLERequestContext& ctx);
|
Result GetActualVibrationValue(Out<Core::HID::VibrationValue> out_vibration_value,
|
||||||
void InitializePalma(HLERequestContext& ctx);
|
Core::HID::VibrationDeviceHandle vibration_device_handle,
|
||||||
void AcquirePalmaOperationCompleteEvent(HLERequestContext& ctx);
|
ClientAppletResourceUserId aruid);
|
||||||
void GetPalmaOperationInfo(HLERequestContext& ctx);
|
Result CreateActiveVibrationDeviceList(OutInterface<IActiveVibrationDeviceList> out_interface);
|
||||||
void PlayPalmaActivity(HLERequestContext& ctx);
|
Result PermitVibration(bool can_vibrate);
|
||||||
void SetPalmaFrModeType(HLERequestContext& ctx);
|
Result IsVibrationPermitted(Out<bool> out_is_permitted);
|
||||||
void ReadPalmaStep(HLERequestContext& ctx);
|
Result SendVibrationValues(
|
||||||
void EnablePalmaStep(HLERequestContext& ctx);
|
ClientAppletResourceUserId aruid,
|
||||||
void ResetPalmaStep(HLERequestContext& ctx);
|
InArray<Core::HID::VibrationDeviceHandle, BufferAttr_HipcPointer> vibration_handles,
|
||||||
void ReadPalmaApplicationSection(HLERequestContext& ctx);
|
InArray<Core::HID::VibrationValue, BufferAttr_HipcPointer> vibration_values);
|
||||||
void WritePalmaApplicationSection(HLERequestContext& ctx);
|
Result SendVibrationGcErmCommand(Core::HID::VibrationDeviceHandle vibration_device_handle,
|
||||||
void ReadPalmaUniqueCode(HLERequestContext& ctx);
|
ClientAppletResourceUserId aruid,
|
||||||
void SetPalmaUniqueCodeInvalid(HLERequestContext& ctx);
|
Core::HID::VibrationGcErmCommand gc_erm_command);
|
||||||
void WritePalmaActivityEntry(HLERequestContext& ctx);
|
Result GetActualVibrationGcErmCommand(Out<Core::HID::VibrationGcErmCommand> out_gc_erm_command,
|
||||||
void WritePalmaRgbLedPatternEntry(HLERequestContext& ctx);
|
Core::HID::VibrationDeviceHandle vibration_device_handle,
|
||||||
void WritePalmaWaveEntry(HLERequestContext& ctx);
|
ClientAppletResourceUserId aruid);
|
||||||
void SetPalmaDataBaseIdentificationVersion(HLERequestContext& ctx);
|
Result BeginPermitVibrationSession(ClientAppletResourceUserId aruid);
|
||||||
void GetPalmaDataBaseIdentificationVersion(HLERequestContext& ctx);
|
Result EndPermitVibrationSession(ClientAppletResourceUserId aruid);
|
||||||
void SuspendPalmaFeature(HLERequestContext& ctx);
|
Result IsVibrationDeviceMounted(Out<bool> out_is_mounted,
|
||||||
void GetPalmaOperationResult(HLERequestContext& ctx);
|
Core::HID::VibrationDeviceHandle vibration_device_handle,
|
||||||
void ReadPalmaPlayLog(HLERequestContext& ctx);
|
ClientAppletResourceUserId aruid);
|
||||||
void ResetPalmaPlayLog(HLERequestContext& ctx);
|
Result SendVibrationValueInBool(bool is_vibrating,
|
||||||
void SetIsPalmaAllConnectable(HLERequestContext& ctx);
|
Core::HID::VibrationDeviceHandle vibration_device_handle,
|
||||||
void SetIsPalmaPairedConnectable(HLERequestContext& ctx);
|
ClientAppletResourceUserId aruid);
|
||||||
void PairPalma(HLERequestContext& ctx);
|
Result ActivateConsoleSixAxisSensor(ClientAppletResourceUserId aruid);
|
||||||
void SetPalmaBoostMode(HLERequestContext& ctx);
|
Result StartConsoleSixAxisSensor(Core::HID::ConsoleSixAxisSensorHandle console_sixaxis_handle,
|
||||||
void CancelWritePalmaWaveEntry(HLERequestContext& ctx);
|
ClientAppletResourceUserId aruid);
|
||||||
void EnablePalmaBoostMode(HLERequestContext& ctx);
|
Result StopConsoleSixAxisSensor(Core::HID::ConsoleSixAxisSensorHandle console_sixaxis_handle,
|
||||||
void GetPalmaBluetoothAddress(HLERequestContext& ctx);
|
ClientAppletResourceUserId aruid);
|
||||||
void SetDisallowedPalmaConnection(HLERequestContext& ctx);
|
Result ActivateSevenSixAxisSensor(ClientAppletResourceUserId aruid);
|
||||||
void SetNpadCommunicationMode(HLERequestContext& ctx);
|
Result StartSevenSixAxisSensor(ClientAppletResourceUserId aruid);
|
||||||
void GetNpadCommunicationMode(HLERequestContext& ctx);
|
Result StopSevenSixAxisSensor(ClientAppletResourceUserId aruid);
|
||||||
void SetTouchScreenConfiguration(HLERequestContext& ctx);
|
Result InitializeSevenSixAxisSensor(ClientAppletResourceUserId aruid, u64 t_mem_1_size,
|
||||||
void IsFirmwareUpdateNeededForNotification(HLERequestContext& ctx);
|
u64 t_mem_2_size,
|
||||||
void SetTouchScreenResolution(HLERequestContext& ctx);
|
InCopyHandle<Kernel::KTransferMemory> t_mem_1,
|
||||||
|
InCopyHandle<Kernel::KTransferMemory> t_mem_2);
|
||||||
|
Result FinalizeSevenSixAxisSensor(ClientAppletResourceUserId aruid);
|
||||||
|
Result ResetSevenSixAxisSensorTimestamp(ClientAppletResourceUserId aruid);
|
||||||
|
Result IsUsbFullKeyControllerEnabled(Out<bool> out_is_enabled,
|
||||||
|
ClientAppletResourceUserId aruid);
|
||||||
|
Result GetPalmaConnectionHandle(Out<Palma::PalmaConnectionHandle> out_handle,
|
||||||
|
Core::HID::NpadIdType npad_id,
|
||||||
|
ClientAppletResourceUserId aruid);
|
||||||
|
Result InitializePalma(Palma::PalmaConnectionHandle connection_handle);
|
||||||
|
Result AcquirePalmaOperationCompleteEvent(OutCopyHandle<Kernel::KReadableEvent> out_event,
|
||||||
|
Palma::PalmaConnectionHandle connection_handle);
|
||||||
|
Result GetPalmaOperationInfo(Out<Palma::PalmaOperationType> out_operation_type,
|
||||||
|
Palma::PalmaConnectionHandle connection_handle,
|
||||||
|
OutBuffer<BufferAttr_HipcMapAlias> out_data);
|
||||||
|
Result PlayPalmaActivity(Palma::PalmaConnectionHandle connection_handle, u64 palma_activity);
|
||||||
|
Result SetPalmaFrModeType(Palma::PalmaConnectionHandle connection_handle,
|
||||||
|
Palma::PalmaFrModeType fr_mode);
|
||||||
|
Result ReadPalmaStep(Palma::PalmaConnectionHandle connection_handle);
|
||||||
|
Result EnablePalmaStep(bool is_enabled, Palma::PalmaConnectionHandle connection_handle);
|
||||||
|
Result ResetPalmaStep(Palma::PalmaConnectionHandle connection_handle);
|
||||||
|
Result ReadPalmaApplicationSection(Palma::PalmaConnectionHandle connection_handle, u64 offset,
|
||||||
|
u64 size);
|
||||||
|
Result WritePalmaApplicationSection(
|
||||||
|
Palma::PalmaConnectionHandle connection_handle, u64 offset, u64 size,
|
||||||
|
InLargeData<Palma::PalmaApplicationSection, BufferAttr_HipcPointer> data);
|
||||||
|
Result ReadPalmaUniqueCode(Palma::PalmaConnectionHandle connection_handle);
|
||||||
|
Result SetPalmaUniqueCodeInvalid(Palma::PalmaConnectionHandle connection_handle);
|
||||||
|
Result WritePalmaActivityEntry(Palma::PalmaConnectionHandle connection_handle,
|
||||||
|
Palma::PalmaActivityEntry activity_entry);
|
||||||
|
Result WritePalmaRgbLedPatternEntry(Palma::PalmaConnectionHandle connection_handle, u64 unknown,
|
||||||
|
InBuffer<BufferAttr_HipcMapAlias> led_pattern);
|
||||||
|
Result WritePalmaWaveEntry(Palma::PalmaConnectionHandle connection_handle,
|
||||||
|
Palma::PalmaWaveSet wave_set, u64 unknown, u64 t_mem_size, u64 size,
|
||||||
|
InCopyHandle<Kernel::KTransferMemory> t_mem);
|
||||||
|
Result SetPalmaDataBaseIdentificationVersion(s32 database_id_version,
|
||||||
|
Palma::PalmaConnectionHandle connection_handle);
|
||||||
|
Result GetPalmaDataBaseIdentificationVersion(Palma::PalmaConnectionHandle connection_handle);
|
||||||
|
Result SuspendPalmaFeature(Palma::PalmaFeature feature,
|
||||||
|
Palma::PalmaConnectionHandle connection_handle);
|
||||||
|
Result GetPalmaOperationResult(Palma::PalmaConnectionHandle connection_handle);
|
||||||
|
Result ReadPalmaPlayLog(u16 unknown, Palma::PalmaConnectionHandle connection_handle);
|
||||||
|
Result ResetPalmaPlayLog(u16 unknown, Palma::PalmaConnectionHandle connection_handle);
|
||||||
|
Result SetIsPalmaAllConnectable(bool is_palma_all_connectable, ClientAppletResourceUserId arui);
|
||||||
|
Result SetIsPalmaPairedConnectable(bool is_palma_paired_connectable,
|
||||||
|
ClientAppletResourceUserId aruid);
|
||||||
|
Result PairPalma(Palma::PalmaConnectionHandle connection_handle);
|
||||||
|
Result SetPalmaBoostMode(bool is_enabled);
|
||||||
|
Result CancelWritePalmaWaveEntry(Palma::PalmaConnectionHandle connection_handle);
|
||||||
|
Result EnablePalmaBoostMode(bool is_enabled, ClientAppletResourceUserId aruid);
|
||||||
|
Result GetPalmaBluetoothAddress(Out<Palma::Address> out_bt_address,
|
||||||
|
Palma::PalmaConnectionHandle connection_handle);
|
||||||
|
Result SetDisallowedPalmaConnection(
|
||||||
|
ClientAppletResourceUserId aruid,
|
||||||
|
InArray<Palma::Address, BufferAttr_HipcPointer> disallowed_address);
|
||||||
|
Result SetNpadCommunicationMode(ClientAppletResourceUserId aruid,
|
||||||
|
NpadCommunicationMode communication_mode);
|
||||||
|
Result GetNpadCommunicationMode(Out<NpadCommunicationMode> out_communication_mode,
|
||||||
|
ClientAppletResourceUserId aruid);
|
||||||
|
Result SetTouchScreenConfiguration(Core::HID::TouchScreenConfigurationForNx touchscreen_config,
|
||||||
|
ClientAppletResourceUserId aruid);
|
||||||
|
Result IsFirmwareUpdateNeededForNotification(Out<bool> out_is_firmware_update_needed,
|
||||||
|
s32 unknown, ClientAppletResourceUserId aruid);
|
||||||
|
Result SetTouchScreenResolution(u32 width, u32 height, ClientAppletResourceUserId aruid);
|
||||||
|
|
||||||
std::shared_ptr<ResourceManager> resource_manager;
|
std::shared_ptr<ResourceManager> resource_manager;
|
||||||
std::shared_ptr<HidFirmwareSettings> firmware_settings;
|
std::shared_ptr<HidFirmwareSettings> firmware_settings;
|
||||||
|
|
|
@ -565,36 +565,28 @@ static_assert(sizeof(SixAxisSensorProperties) == 1, "SixAxisSensorProperties is
|
||||||
|
|
||||||
// This is nn::hid::SixAxisSensorCalibrationParameter
|
// This is nn::hid::SixAxisSensorCalibrationParameter
|
||||||
struct SixAxisSensorCalibrationParameter {
|
struct SixAxisSensorCalibrationParameter {
|
||||||
std::array<u8, 0x744> unknown_data{};
|
std::array<u8, 0x744> unknown_data;
|
||||||
};
|
};
|
||||||
static_assert(sizeof(SixAxisSensorCalibrationParameter) == 0x744,
|
static_assert(sizeof(SixAxisSensorCalibrationParameter) == 0x744,
|
||||||
"SixAxisSensorCalibrationParameter is an invalid size");
|
"SixAxisSensorCalibrationParameter is an invalid size");
|
||||||
|
static_assert(std::is_trivial_v<SixAxisSensorCalibrationParameter>,
|
||||||
|
"SixAxisSensorCalibrationParameter must be trivial.");
|
||||||
|
|
||||||
// This is nn::hid::SixAxisSensorIcInformation
|
// This is nn::hid::SixAxisSensorIcInformation
|
||||||
struct SixAxisSensorIcInformation {
|
struct SixAxisSensorIcInformation {
|
||||||
f32 angular_rate{2000.0f}; // dps
|
f32 angular_rate; // dps
|
||||||
std::array<f32, 6> unknown_gyro_data1{
|
std::array<f32, 6> unknown_gyro_data1; // dps
|
||||||
-10.0f, -10.0f, -10.0f, 10.0f, 10.0f, 10.0f,
|
std::array<f32, 9> unknown_gyro_data2;
|
||||||
}; // dps
|
std::array<f32, 9> unknown_gyro_data3;
|
||||||
std::array<f32, 9> unknown_gyro_data2{
|
f32 acceleration_range; // g force
|
||||||
0.95f, -0.003f, -0.003f, -0.003f, 0.95f, -0.003f, -0.003f, -0.003f, 0.95f,
|
std::array<f32, 6> unknown_accel_data1; // g force
|
||||||
};
|
std::array<f32, 9> unknown_accel_data2;
|
||||||
std::array<f32, 9> unknown_gyro_data3{
|
std::array<f32, 9> unknown_accel_data3;
|
||||||
1.05f, 0.003f, 0.003f, 0.003f, 1.05f, 0.003f, 0.003f, 0.003f, 1.05f,
|
|
||||||
};
|
|
||||||
f32 acceleration_range{8.0f}; // g force
|
|
||||||
std::array<f32, 6> unknown_accel_data1{
|
|
||||||
-0.0612f, -0.0612f, -0.0612f, 0.0612f, 0.0612f, 0.0612f,
|
|
||||||
}; // g force
|
|
||||||
std::array<f32, 9> unknown_accel_data2{
|
|
||||||
0.95f, -0.003f, -0.003f, -0.003f, 0.95f, -0.003f, -0.003f, -0.003f, 0.95f,
|
|
||||||
};
|
|
||||||
std::array<f32, 9> unknown_accel_data3{
|
|
||||||
1.05f, 0.003f, 0.003f, 0.003f, 1.05f, 0.003f, 0.003f, 0.003f, 1.05f,
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
static_assert(sizeof(SixAxisSensorIcInformation) == 0xC8,
|
static_assert(sizeof(SixAxisSensorIcInformation) == 0xC8,
|
||||||
"SixAxisSensorIcInformation is an invalid size");
|
"SixAxisSensorIcInformation is an invalid size");
|
||||||
|
static_assert(std::is_trivial_v<SixAxisSensorIcInformation>,
|
||||||
|
"SixAxisSensorIcInformation must be trivial.");
|
||||||
|
|
||||||
// This is nn::hid::SixAxisSensorAttribute
|
// This is nn::hid::SixAxisSensorAttribute
|
||||||
struct SixAxisSensorAttribute {
|
struct SixAxisSensorAttribute {
|
||||||
|
|
|
@ -4,7 +4,6 @@
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
#include "core/core.h"
|
#include "core/core.h"
|
||||||
#include "core/core_timing.h"
|
#include "core/core_timing.h"
|
||||||
#include "core/hle/kernel/k_shared_memory.h"
|
|
||||||
#include "core/hle/service/ipc_helpers.h"
|
#include "core/hle/service/ipc_helpers.h"
|
||||||
#include "core/hle/service/set/system_settings_server.h"
|
#include "core/hle/service/set/system_settings_server.h"
|
||||||
#include "core/hle/service/sm/sm.h"
|
#include "core/hle/service/sm/sm.h"
|
||||||
|
@ -501,29 +500,4 @@ void ResourceManager::UpdateMotion(std::chrono::nanoseconds ns_late) {
|
||||||
console_six_axis->OnUpdate(core_timing);
|
console_six_axis->OnUpdate(core_timing);
|
||||||
}
|
}
|
||||||
|
|
||||||
IAppletResource::IAppletResource(Core::System& system_, std::shared_ptr<ResourceManager> resource,
|
|
||||||
u64 applet_resource_user_id)
|
|
||||||
: ServiceFramework{system_, "IAppletResource"}, aruid{applet_resource_user_id},
|
|
||||||
resource_manager{resource} {
|
|
||||||
static const FunctionInfo functions[] = {
|
|
||||||
{0, &IAppletResource::GetSharedMemoryHandle, "GetSharedMemoryHandle"},
|
|
||||||
};
|
|
||||||
RegisterHandlers(functions);
|
|
||||||
}
|
|
||||||
|
|
||||||
IAppletResource::~IAppletResource() {
|
|
||||||
resource_manager->FreeAppletResourceId(aruid);
|
|
||||||
}
|
|
||||||
|
|
||||||
void IAppletResource::GetSharedMemoryHandle(HLERequestContext& ctx) {
|
|
||||||
Kernel::KSharedMemory* handle;
|
|
||||||
const auto result = resource_manager->GetSharedMemoryHandle(&handle, aruid);
|
|
||||||
|
|
||||||
LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}, result=0x{:X}", aruid, result.raw);
|
|
||||||
|
|
||||||
IPC::ResponseBuilder rb{ctx, 2, 1};
|
|
||||||
rb.Push(result);
|
|
||||||
rb.PushCopyObjects(handle);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace Service::HID
|
} // namespace Service::HID
|
||||||
|
|
|
@ -174,17 +174,4 @@ private:
|
||||||
KernelHelpers::ServiceContext service_context;
|
KernelHelpers::ServiceContext service_context;
|
||||||
};
|
};
|
||||||
|
|
||||||
class IAppletResource final : public ServiceFramework<IAppletResource> {
|
|
||||||
public:
|
|
||||||
explicit IAppletResource(Core::System& system_, std::shared_ptr<ResourceManager> resource,
|
|
||||||
u64 applet_resource_user_id);
|
|
||||||
~IAppletResource() override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
void GetSharedMemoryHandle(HLERequestContext& ctx);
|
|
||||||
|
|
||||||
u64 aruid{};
|
|
||||||
std::shared_ptr<ResourceManager> resource_manager;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace Service::HID
|
} // namespace Service::HID
|
||||||
|
|
|
@ -56,12 +56,14 @@ Kernel::KReadableEvent& Palma::AcquirePalmaOperationCompleteEvent(
|
||||||
|
|
||||||
Result Palma::GetPalmaOperationInfo(const PalmaConnectionHandle& handle,
|
Result Palma::GetPalmaOperationInfo(const PalmaConnectionHandle& handle,
|
||||||
PalmaOperationType& operation_type,
|
PalmaOperationType& operation_type,
|
||||||
PalmaOperationData& data) const {
|
std::span<u8> out_data) const {
|
||||||
if (handle.npad_id != active_handle.npad_id) {
|
if (handle.npad_id != active_handle.npad_id) {
|
||||||
return InvalidPalmaHandle;
|
return InvalidPalmaHandle;
|
||||||
}
|
}
|
||||||
operation_type = operation.operation;
|
operation_type = static_cast<PalmaOperationType>(operation.operation);
|
||||||
data = operation.data;
|
std::memcpy(out_data.data(), operation.data.data(),
|
||||||
|
std::min(out_data.size(), operation.data.size()));
|
||||||
|
|
||||||
return ResultSuccess;
|
return ResultSuccess;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -69,7 +71,7 @@ Result Palma::PlayPalmaActivity(const PalmaConnectionHandle& handle, u64 palma_a
|
||||||
if (handle.npad_id != active_handle.npad_id) {
|
if (handle.npad_id != active_handle.npad_id) {
|
||||||
return InvalidPalmaHandle;
|
return InvalidPalmaHandle;
|
||||||
}
|
}
|
||||||
operation.operation = PalmaOperationType::PlayActivity;
|
operation.operation = PackedPalmaOperationType::PlayActivity;
|
||||||
operation.result = PalmaResultSuccess;
|
operation.result = PalmaResultSuccess;
|
||||||
operation.data = {};
|
operation.data = {};
|
||||||
operation_complete_event->Signal();
|
operation_complete_event->Signal();
|
||||||
|
@ -88,7 +90,7 @@ Result Palma::ReadPalmaStep(const PalmaConnectionHandle& handle) {
|
||||||
if (handle.npad_id != active_handle.npad_id) {
|
if (handle.npad_id != active_handle.npad_id) {
|
||||||
return InvalidPalmaHandle;
|
return InvalidPalmaHandle;
|
||||||
}
|
}
|
||||||
operation.operation = PalmaOperationType::ReadStep;
|
operation.operation = PackedPalmaOperationType::ReadStep;
|
||||||
operation.result = PalmaResultSuccess;
|
operation.result = PalmaResultSuccess;
|
||||||
operation.data = {};
|
operation.data = {};
|
||||||
operation_complete_event->Signal();
|
operation_complete_event->Signal();
|
||||||
|
@ -117,7 +119,7 @@ Result Palma::ReadPalmaUniqueCode(const PalmaConnectionHandle& handle) {
|
||||||
if (handle.npad_id != active_handle.npad_id) {
|
if (handle.npad_id != active_handle.npad_id) {
|
||||||
return InvalidPalmaHandle;
|
return InvalidPalmaHandle;
|
||||||
}
|
}
|
||||||
operation.operation = PalmaOperationType::ReadUniqueCode;
|
operation.operation = PackedPalmaOperationType::ReadUniqueCode;
|
||||||
operation.result = PalmaResultSuccess;
|
operation.result = PalmaResultSuccess;
|
||||||
operation.data = {};
|
operation.data = {};
|
||||||
operation_complete_event->Signal();
|
operation_complete_event->Signal();
|
||||||
|
@ -128,7 +130,7 @@ Result Palma::SetPalmaUniqueCodeInvalid(const PalmaConnectionHandle& handle) {
|
||||||
if (handle.npad_id != active_handle.npad_id) {
|
if (handle.npad_id != active_handle.npad_id) {
|
||||||
return InvalidPalmaHandle;
|
return InvalidPalmaHandle;
|
||||||
}
|
}
|
||||||
operation.operation = PalmaOperationType::SetUniqueCodeInvalid;
|
operation.operation = PackedPalmaOperationType::SetUniqueCodeInvalid;
|
||||||
operation.result = PalmaResultSuccess;
|
operation.result = PalmaResultSuccess;
|
||||||
operation.data = {};
|
operation.data = {};
|
||||||
operation_complete_event->Signal();
|
operation_complete_event->Signal();
|
||||||
|
@ -141,7 +143,7 @@ Result Palma::WritePalmaRgbLedPatternEntry(const PalmaConnectionHandle& handle,
|
||||||
if (handle.npad_id != active_handle.npad_id) {
|
if (handle.npad_id != active_handle.npad_id) {
|
||||||
return InvalidPalmaHandle;
|
return InvalidPalmaHandle;
|
||||||
}
|
}
|
||||||
operation.operation = PalmaOperationType::WriteRgbLedPatternEntry;
|
operation.operation = PackedPalmaOperationType::WriteRgbLedPatternEntry;
|
||||||
operation.result = PalmaResultSuccess;
|
operation.result = PalmaResultSuccess;
|
||||||
operation.data = {};
|
operation.data = {};
|
||||||
operation_complete_event->Signal();
|
operation_complete_event->Signal();
|
||||||
|
@ -153,7 +155,7 @@ Result Palma::WritePalmaWaveEntry(const PalmaConnectionHandle& handle, PalmaWave
|
||||||
if (handle.npad_id != active_handle.npad_id) {
|
if (handle.npad_id != active_handle.npad_id) {
|
||||||
return InvalidPalmaHandle;
|
return InvalidPalmaHandle;
|
||||||
}
|
}
|
||||||
operation.operation = PalmaOperationType::WriteWaveEntry;
|
operation.operation = PackedPalmaOperationType::WriteWaveEntry;
|
||||||
operation.result = PalmaResultSuccess;
|
operation.result = PalmaResultSuccess;
|
||||||
operation.data = {};
|
operation.data = {};
|
||||||
operation_complete_event->Signal();
|
operation_complete_event->Signal();
|
||||||
|
@ -166,7 +168,7 @@ Result Palma::SetPalmaDataBaseIdentificationVersion(const PalmaConnectionHandle&
|
||||||
return InvalidPalmaHandle;
|
return InvalidPalmaHandle;
|
||||||
}
|
}
|
||||||
database_id_version = database_id_version_;
|
database_id_version = database_id_version_;
|
||||||
operation.operation = PalmaOperationType::ReadDataBaseIdentificationVersion;
|
operation.operation = PackedPalmaOperationType::ReadDataBaseIdentificationVersion;
|
||||||
operation.result = PalmaResultSuccess;
|
operation.result = PalmaResultSuccess;
|
||||||
operation.data[0] = {};
|
operation.data[0] = {};
|
||||||
operation_complete_event->Signal();
|
operation_complete_event->Signal();
|
||||||
|
@ -177,7 +179,7 @@ Result Palma::GetPalmaDataBaseIdentificationVersion(const PalmaConnectionHandle&
|
||||||
if (handle.npad_id != active_handle.npad_id) {
|
if (handle.npad_id != active_handle.npad_id) {
|
||||||
return InvalidPalmaHandle;
|
return InvalidPalmaHandle;
|
||||||
}
|
}
|
||||||
operation.operation = PalmaOperationType::ReadDataBaseIdentificationVersion;
|
operation.operation = PackedPalmaOperationType::ReadDataBaseIdentificationVersion;
|
||||||
operation.result = PalmaResultSuccess;
|
operation.result = PalmaResultSuccess;
|
||||||
operation.data = {};
|
operation.data = {};
|
||||||
operation.data[0] = static_cast<u8>(database_id_version);
|
operation.data[0] = static_cast<u8>(database_id_version);
|
||||||
|
|
|
@ -4,6 +4,8 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
|
#include <span>
|
||||||
|
|
||||||
#include "common/common_funcs.h"
|
#include "common/common_funcs.h"
|
||||||
#include "common/typed_address.h"
|
#include "common/typed_address.h"
|
||||||
#include "hid_core/hid_result.h"
|
#include "hid_core/hid_result.h"
|
||||||
|
@ -27,9 +29,31 @@ namespace Service::HID {
|
||||||
class Palma final : public ControllerBase {
|
class Palma final : public ControllerBase {
|
||||||
public:
|
public:
|
||||||
using PalmaOperationData = std::array<u8, 0x140>;
|
using PalmaOperationData = std::array<u8, 0x140>;
|
||||||
|
using PalmaApplicationSection = std::array<u8, 0x100>;
|
||||||
|
using Address = std::array<u8, 0x6>;
|
||||||
|
|
||||||
// This is nn::hid::PalmaOperationType
|
// This is nn::hid::PalmaOperationType
|
||||||
enum class PalmaOperationType {
|
enum class PalmaOperationType : u64 {
|
||||||
|
PlayActivity,
|
||||||
|
SetFrModeType,
|
||||||
|
ReadStep,
|
||||||
|
EnableStep,
|
||||||
|
ResetStep,
|
||||||
|
ReadApplicationSection,
|
||||||
|
WriteApplicationSection,
|
||||||
|
ReadUniqueCode,
|
||||||
|
SetUniqueCodeInvalid,
|
||||||
|
WriteActivityEntry,
|
||||||
|
WriteRgbLedPatternEntry,
|
||||||
|
WriteWaveEntry,
|
||||||
|
ReadDataBaseIdentificationVersion,
|
||||||
|
WriteDataBaseIdentificationVersion,
|
||||||
|
SuspendFeature,
|
||||||
|
ReadPlayLog,
|
||||||
|
ResetPlayLog,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class PackedPalmaOperationType : u32 {
|
||||||
PlayActivity,
|
PlayActivity,
|
||||||
SetFrModeType,
|
SetFrModeType,
|
||||||
ReadStep,
|
ReadStep,
|
||||||
|
@ -75,7 +99,7 @@ public:
|
||||||
|
|
||||||
// This is nn::hid::PalmaOperationInfo
|
// This is nn::hid::PalmaOperationInfo
|
||||||
struct PalmaOperationInfo {
|
struct PalmaOperationInfo {
|
||||||
PalmaOperationType operation{};
|
PackedPalmaOperationType operation{};
|
||||||
Result result{PalmaResultSuccess};
|
Result result{PalmaResultSuccess};
|
||||||
PalmaOperationData data{};
|
PalmaOperationData data{};
|
||||||
};
|
};
|
||||||
|
@ -92,8 +116,7 @@ public:
|
||||||
static_assert(sizeof(PalmaActivityEntry) == 0x20, "PalmaActivityEntry is an invalid size");
|
static_assert(sizeof(PalmaActivityEntry) == 0x20, "PalmaActivityEntry is an invalid size");
|
||||||
|
|
||||||
struct PalmaConnectionHandle {
|
struct PalmaConnectionHandle {
|
||||||
Core::HID::NpadIdType npad_id;
|
alignas(8) Core::HID::NpadIdType npad_id;
|
||||||
INSERT_PADDING_BYTES(4); // Unknown
|
|
||||||
};
|
};
|
||||||
static_assert(sizeof(PalmaConnectionHandle) == 0x8,
|
static_assert(sizeof(PalmaConnectionHandle) == 0x8,
|
||||||
"PalmaConnectionHandle has incorrect size.");
|
"PalmaConnectionHandle has incorrect size.");
|
||||||
|
@ -115,8 +138,7 @@ public:
|
||||||
Kernel::KReadableEvent& AcquirePalmaOperationCompleteEvent(
|
Kernel::KReadableEvent& AcquirePalmaOperationCompleteEvent(
|
||||||
const PalmaConnectionHandle& handle) const;
|
const PalmaConnectionHandle& handle) const;
|
||||||
Result GetPalmaOperationInfo(const PalmaConnectionHandle& handle,
|
Result GetPalmaOperationInfo(const PalmaConnectionHandle& handle,
|
||||||
PalmaOperationType& operation_type,
|
PalmaOperationType& operation_type, std::span<u8> out_data) const;
|
||||||
PalmaOperationData& data) const;
|
|
||||||
Result PlayPalmaActivity(const PalmaConnectionHandle& handle, u64 palma_activity);
|
Result PlayPalmaActivity(const PalmaConnectionHandle& handle, u64 palma_activity);
|
||||||
Result SetPalmaFrModeType(const PalmaConnectionHandle& handle, PalmaFrModeType fr_mode_);
|
Result SetPalmaFrModeType(const PalmaConnectionHandle& handle, PalmaFrModeType fr_mode_);
|
||||||
Result ReadPalmaStep(const PalmaConnectionHandle& handle);
|
Result ReadPalmaStep(const PalmaConnectionHandle& handle);
|
||||||
|
|
|
@ -216,14 +216,11 @@ void DrawManager::DrawTexture() {
|
||||||
const bool lower_left{regs.window_origin.mode !=
|
const bool lower_left{regs.window_origin.mode !=
|
||||||
Maxwell3D::Regs::WindowOrigin::Mode::UpperLeft};
|
Maxwell3D::Regs::WindowOrigin::Mode::UpperLeft};
|
||||||
if (lower_left) {
|
if (lower_left) {
|
||||||
draw_texture_state.dst_y0 -= dst_height;
|
draw_texture_state.dst_y0 =
|
||||||
|
static_cast<f32>(regs.surface_clip.height) - draw_texture_state.dst_y0;
|
||||||
}
|
}
|
||||||
draw_texture_state.dst_x1 =
|
draw_texture_state.dst_x1 = draw_texture_state.dst_x0 + dst_width;
|
||||||
draw_texture_state.dst_x0 +
|
draw_texture_state.dst_y1 = draw_texture_state.dst_y0 + dst_height;
|
||||||
static_cast<f32>(Settings::values.resolution_info.ScaleUp(static_cast<u32>(dst_width)));
|
|
||||||
draw_texture_state.dst_y1 =
|
|
||||||
draw_texture_state.dst_y0 +
|
|
||||||
static_cast<f32>(Settings::values.resolution_info.ScaleUp(static_cast<u32>(dst_height)));
|
|
||||||
draw_texture_state.src_x0 = static_cast<float>(regs.draw_texture.src_x0) / 4096.f;
|
draw_texture_state.src_x0 = static_cast<float>(regs.draw_texture.src_x0) / 4096.f;
|
||||||
draw_texture_state.src_y0 = static_cast<float>(regs.draw_texture.src_y0) / 4096.f;
|
draw_texture_state.src_y0 = static_cast<float>(regs.draw_texture.src_y0) / 4096.f;
|
||||||
draw_texture_state.src_x1 =
|
draw_texture_state.src_x1 =
|
||||||
|
|
|
@ -370,27 +370,32 @@ void RasterizerOpenGL::DrawTexture() {
|
||||||
const auto& sampler = texture_cache.GetGraphicsSampler(draw_texture_state.src_sampler);
|
const auto& sampler = texture_cache.GetGraphicsSampler(draw_texture_state.src_sampler);
|
||||||
const auto& texture = texture_cache.GetImageView(draw_texture_state.src_texture);
|
const auto& texture = texture_cache.GetImageView(draw_texture_state.src_texture);
|
||||||
|
|
||||||
|
const auto Scale = [&](auto dim) -> s32 {
|
||||||
|
return Settings::values.resolution_info.ScaleUp(static_cast<s32>(dim));
|
||||||
|
};
|
||||||
|
|
||||||
|
Region2D dst_region = {
|
||||||
|
Offset2D{.x = Scale(draw_texture_state.dst_x0), .y = Scale(draw_texture_state.dst_y0)},
|
||||||
|
Offset2D{.x = Scale(draw_texture_state.dst_x1), .y = Scale(draw_texture_state.dst_y1)}};
|
||||||
|
Region2D src_region = {
|
||||||
|
Offset2D{.x = Scale(draw_texture_state.src_x0), .y = Scale(draw_texture_state.src_y0)},
|
||||||
|
Offset2D{.x = Scale(draw_texture_state.src_x1), .y = Scale(draw_texture_state.src_y1)}};
|
||||||
|
Extent3D src_size = {static_cast<u32>(Scale(texture.size.width)),
|
||||||
|
static_cast<u32>(Scale(texture.size.height)), texture.size.depth};
|
||||||
|
|
||||||
if (device.HasDrawTexture()) {
|
if (device.HasDrawTexture()) {
|
||||||
state_tracker.BindFramebuffer(texture_cache.GetFramebuffer()->Handle());
|
state_tracker.BindFramebuffer(texture_cache.GetFramebuffer()->Handle());
|
||||||
|
|
||||||
glDrawTextureNV(texture.DefaultHandle(), sampler->Handle(), draw_texture_state.dst_x0,
|
glDrawTextureNV(texture.DefaultHandle(), sampler->Handle(),
|
||||||
draw_texture_state.dst_y0, draw_texture_state.dst_x1,
|
static_cast<f32>(dst_region.start.x), static_cast<f32>(dst_region.start.y),
|
||||||
draw_texture_state.dst_y1, 0,
|
static_cast<f32>(dst_region.end.x), static_cast<f32>(dst_region.end.y), 0,
|
||||||
draw_texture_state.src_x0 / static_cast<float>(texture.size.width),
|
draw_texture_state.src_x0 / static_cast<float>(texture.size.width),
|
||||||
draw_texture_state.src_y0 / static_cast<float>(texture.size.height),
|
draw_texture_state.src_y0 / static_cast<float>(texture.size.height),
|
||||||
draw_texture_state.src_x1 / static_cast<float>(texture.size.width),
|
draw_texture_state.src_x1 / static_cast<float>(texture.size.width),
|
||||||
draw_texture_state.src_y1 / static_cast<float>(texture.size.height));
|
draw_texture_state.src_y1 / static_cast<float>(texture.size.height));
|
||||||
} else {
|
} else {
|
||||||
Region2D dst_region = {Offset2D{.x = static_cast<s32>(draw_texture_state.dst_x0),
|
|
||||||
.y = static_cast<s32>(draw_texture_state.dst_y0)},
|
|
||||||
Offset2D{.x = static_cast<s32>(draw_texture_state.dst_x1),
|
|
||||||
.y = static_cast<s32>(draw_texture_state.dst_y1)}};
|
|
||||||
Region2D src_region = {Offset2D{.x = static_cast<s32>(draw_texture_state.src_x0),
|
|
||||||
.y = static_cast<s32>(draw_texture_state.src_y0)},
|
|
||||||
Offset2D{.x = static_cast<s32>(draw_texture_state.src_x1),
|
|
||||||
.y = static_cast<s32>(draw_texture_state.src_y1)}};
|
|
||||||
blit_image.BlitColor(texture_cache.GetFramebuffer()->Handle(), texture.DefaultHandle(),
|
blit_image.BlitColor(texture_cache.GetFramebuffer()->Handle(), texture.DefaultHandle(),
|
||||||
sampler->Handle(), dst_region, src_region, texture.size);
|
sampler->Handle(), dst_region, src_region, src_size);
|
||||||
state_tracker.InvalidateState();
|
state_tracker.InvalidateState();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -125,11 +125,23 @@ VkRect2D GetScissorState(const Maxwell& regs, size_t index, u32 up_scale = 1, u3
|
||||||
return value < 0 ? std::min<s32>(converted_value - acumm, -1)
|
return value < 0 ? std::min<s32>(converted_value - acumm, -1)
|
||||||
: std::max<s32>(converted_value + acumm, 1);
|
: std::max<s32>(converted_value + acumm, 1);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const bool lower_left = regs.window_origin.mode != Maxwell::WindowOrigin::Mode::UpperLeft;
|
||||||
|
const s32 clip_height = regs.surface_clip.height;
|
||||||
|
|
||||||
|
// Flip coordinates if lower left
|
||||||
|
s32 min_y = lower_left ? (clip_height - src.max_y) : src.min_y.Value();
|
||||||
|
s32 max_y = lower_left ? (clip_height - src.min_y) : src.max_y.Value();
|
||||||
|
|
||||||
|
// Bound to render area
|
||||||
|
min_y = std::max(min_y, 0);
|
||||||
|
max_y = std::max(max_y, 0);
|
||||||
|
|
||||||
if (src.enable) {
|
if (src.enable) {
|
||||||
scissor.offset.x = scale_up(static_cast<s32>(src.min_x));
|
scissor.offset.x = scale_up(src.min_x);
|
||||||
scissor.offset.y = scale_up(static_cast<s32>(src.min_y));
|
scissor.offset.y = scale_up(min_y);
|
||||||
scissor.extent.width = scale_up(src.max_x - src.min_x);
|
scissor.extent.width = scale_up(src.max_x - src.min_x);
|
||||||
scissor.extent.height = scale_up(src.max_y - src.min_y);
|
scissor.extent.height = scale_up(max_y - min_y);
|
||||||
} else {
|
} else {
|
||||||
scissor.offset.x = 0;
|
scissor.offset.x = 0;
|
||||||
scissor.offset.y = 0;
|
scissor.offset.y = 0;
|
||||||
|
@ -308,17 +320,33 @@ void RasterizerVulkan::DrawTexture() {
|
||||||
const auto& draw_texture_state = maxwell3d->draw_manager->GetDrawTextureState();
|
const auto& draw_texture_state = maxwell3d->draw_manager->GetDrawTextureState();
|
||||||
const auto& sampler = texture_cache.GetGraphicsSampler(draw_texture_state.src_sampler);
|
const auto& sampler = texture_cache.GetGraphicsSampler(draw_texture_state.src_sampler);
|
||||||
const auto& texture = texture_cache.GetImageView(draw_texture_state.src_texture);
|
const auto& texture = texture_cache.GetImageView(draw_texture_state.src_texture);
|
||||||
Region2D dst_region = {Offset2D{.x = static_cast<s32>(draw_texture_state.dst_x0),
|
const auto* framebuffer = texture_cache.GetFramebuffer();
|
||||||
.y = static_cast<s32>(draw_texture_state.dst_y0)},
|
|
||||||
Offset2D{.x = static_cast<s32>(draw_texture_state.dst_x1),
|
const bool src_rescaling = texture_cache.IsRescaling() && texture.IsRescaled();
|
||||||
.y = static_cast<s32>(draw_texture_state.dst_y1)}};
|
const bool dst_rescaling = texture_cache.IsRescaling() && framebuffer->IsRescaled();
|
||||||
Region2D src_region = {Offset2D{.x = static_cast<s32>(draw_texture_state.src_x0),
|
|
||||||
.y = static_cast<s32>(draw_texture_state.src_y0)},
|
const auto ScaleSrc = [&](auto dim_f) -> s32 {
|
||||||
Offset2D{.x = static_cast<s32>(draw_texture_state.src_x1),
|
auto dim = static_cast<s32>(dim_f);
|
||||||
.y = static_cast<s32>(draw_texture_state.src_y1)}};
|
return src_rescaling ? Settings::values.resolution_info.ScaleUp(dim) : dim;
|
||||||
blit_image.BlitColor(texture_cache.GetFramebuffer(), texture.RenderTarget(),
|
};
|
||||||
texture.ImageHandle(), sampler->Handle(), dst_region, src_region,
|
|
||||||
texture.size);
|
const auto ScaleDst = [&](auto dim_f) -> s32 {
|
||||||
|
auto dim = static_cast<s32>(dim_f);
|
||||||
|
return dst_rescaling ? Settings::values.resolution_info.ScaleUp(dim) : dim;
|
||||||
|
};
|
||||||
|
|
||||||
|
Region2D dst_region = {Offset2D{.x = ScaleDst(draw_texture_state.dst_x0),
|
||||||
|
.y = ScaleDst(draw_texture_state.dst_y0)},
|
||||||
|
Offset2D{.x = ScaleDst(draw_texture_state.dst_x1),
|
||||||
|
.y = ScaleDst(draw_texture_state.dst_y1)}};
|
||||||
|
Region2D src_region = {Offset2D{.x = ScaleSrc(draw_texture_state.src_x0),
|
||||||
|
.y = ScaleSrc(draw_texture_state.src_y0)},
|
||||||
|
Offset2D{.x = ScaleSrc(draw_texture_state.src_x1),
|
||||||
|
.y = ScaleSrc(draw_texture_state.src_y1)}};
|
||||||
|
Extent3D src_size = {static_cast<u32>(ScaleSrc(texture.size.width)),
|
||||||
|
static_cast<u32>(ScaleSrc(texture.size.height)), texture.size.depth};
|
||||||
|
blit_image.BlitColor(framebuffer, texture.RenderTarget(), texture.ImageHandle(),
|
||||||
|
sampler->Handle(), dst_region, src_region, src_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RasterizerVulkan::Clear(u32 layer_count) {
|
void RasterizerVulkan::Clear(u32 layer_count) {
|
||||||
|
|
|
@ -1962,21 +1962,22 @@ Framebuffer::Framebuffer(TextureCacheRuntime& runtime, std::span<ImageView*, NUM
|
||||||
}
|
}
|
||||||
|
|
||||||
Framebuffer::Framebuffer(TextureCacheRuntime& runtime, ImageView* color_buffer,
|
Framebuffer::Framebuffer(TextureCacheRuntime& runtime, ImageView* color_buffer,
|
||||||
ImageView* depth_buffer, VkExtent2D extent, bool is_rescaled)
|
ImageView* depth_buffer, VkExtent2D extent, bool is_rescaled_)
|
||||||
: render_area{extent} {
|
: render_area{extent} {
|
||||||
std::array<ImageView*, NUM_RT> color_buffers{color_buffer};
|
std::array<ImageView*, NUM_RT> color_buffers{color_buffer};
|
||||||
CreateFramebuffer(runtime, color_buffers, depth_buffer, is_rescaled);
|
CreateFramebuffer(runtime, color_buffers, depth_buffer, is_rescaled_);
|
||||||
}
|
}
|
||||||
|
|
||||||
Framebuffer::~Framebuffer() = default;
|
Framebuffer::~Framebuffer() = default;
|
||||||
|
|
||||||
void Framebuffer::CreateFramebuffer(TextureCacheRuntime& runtime,
|
void Framebuffer::CreateFramebuffer(TextureCacheRuntime& runtime,
|
||||||
std::span<ImageView*, NUM_RT> color_buffers,
|
std::span<ImageView*, NUM_RT> color_buffers,
|
||||||
ImageView* depth_buffer, bool is_rescaled) {
|
ImageView* depth_buffer, bool is_rescaled_) {
|
||||||
boost::container::small_vector<VkImageView, NUM_RT + 1> attachments;
|
boost::container::small_vector<VkImageView, NUM_RT + 1> attachments;
|
||||||
RenderPassKey renderpass_key{};
|
RenderPassKey renderpass_key{};
|
||||||
s32 num_layers = 1;
|
s32 num_layers = 1;
|
||||||
|
|
||||||
|
is_rescaled = is_rescaled_;
|
||||||
const auto& resolution = runtime.resolution;
|
const auto& resolution = runtime.resolution;
|
||||||
|
|
||||||
u32 width = std::numeric_limits<u32>::max();
|
u32 width = std::numeric_limits<u32>::max();
|
||||||
|
|
|
@ -361,6 +361,10 @@ public:
|
||||||
return has_stencil;
|
return has_stencil;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] bool IsRescaled() const noexcept {
|
||||||
|
return is_rescaled;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
vk::Framebuffer framebuffer;
|
vk::Framebuffer framebuffer;
|
||||||
VkRenderPass renderpass{};
|
VkRenderPass renderpass{};
|
||||||
|
@ -373,6 +377,7 @@ private:
|
||||||
std::array<size_t, NUM_RT> rt_map{};
|
std::array<size_t, NUM_RT> rt_map{};
|
||||||
bool has_depth{};
|
bool has_depth{};
|
||||||
bool has_stencil{};
|
bool has_stencil{};
|
||||||
|
bool is_rescaled{};
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TextureCacheParams {
|
struct TextureCacheParams {
|
||||||
|
|
|
@ -1461,6 +1461,7 @@ void GMainWindow::OnAppFocusStateChanged(Qt::ApplicationState state) {
|
||||||
OnPauseGame();
|
OnPauseGame();
|
||||||
} else if (!emu_thread->IsRunning() && auto_paused && state == Qt::ApplicationActive) {
|
} else if (!emu_thread->IsRunning() && auto_paused && state == Qt::ApplicationActive) {
|
||||||
auto_paused = false;
|
auto_paused = false;
|
||||||
|
RequestGameResume();
|
||||||
OnStartGame();
|
OnStartGame();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1701,6 +1702,7 @@ void GMainWindow::OnPrepareForSleep(bool prepare_sleep) {
|
||||||
} else {
|
} else {
|
||||||
if (!emu_thread->IsRunning() && auto_paused) {
|
if (!emu_thread->IsRunning() && auto_paused) {
|
||||||
auto_paused = false;
|
auto_paused = false;
|
||||||
|
RequestGameResume();
|
||||||
OnStartGame();
|
OnStartGame();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3455,6 +3457,7 @@ void GMainWindow::OnPauseContinueGame() {
|
||||||
if (emu_thread->IsRunning()) {
|
if (emu_thread->IsRunning()) {
|
||||||
OnPauseGame();
|
OnPauseGame();
|
||||||
} else {
|
} else {
|
||||||
|
RequestGameResume();
|
||||||
OnStartGame();
|
OnStartGame();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5010,6 +5013,10 @@ void GMainWindow::RequestGameExit() {
|
||||||
system->GetAppletManager().RequestExit();
|
system->GetAppletManager().RequestExit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GMainWindow::RequestGameResume() {
|
||||||
|
system->GetAppletManager().RequestResume();
|
||||||
|
}
|
||||||
|
|
||||||
void GMainWindow::filterBarSetChecked(bool state) {
|
void GMainWindow::filterBarSetChecked(bool state) {
|
||||||
ui->action_Show_Filter_Bar->setChecked(state);
|
ui->action_Show_Filter_Bar->setChecked(state);
|
||||||
emit(OnToggleFilterBar());
|
emit(OnToggleFilterBar());
|
||||||
|
|
|
@ -310,6 +310,7 @@ private:
|
||||||
bool ConfirmChangeGame();
|
bool ConfirmChangeGame();
|
||||||
bool ConfirmForceLockedExit();
|
bool ConfirmForceLockedExit();
|
||||||
void RequestGameExit();
|
void RequestGameExit();
|
||||||
|
void RequestGameResume();
|
||||||
void changeEvent(QEvent* event) override;
|
void changeEvent(QEvent* event) override;
|
||||||
void closeEvent(QCloseEvent* event) override;
|
void closeEvent(QCloseEvent* event) override;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue