Compare commits

..

41 Commits

Author SHA1 Message Date
Lioncash
f4ae449f73 service/am: Implement IsAutoSleepDisabled
This simply queries whether or not auto-sleep facilities are disabled
and has no special handling. It's a basic getter function.
2019-07-11 13:34:55 -04:00
Lioncash
b81f6f67f5 service/am: Implement SetAutoSleepDisabled
Provides a basic implementation of SetAutoSleepDisabled. Until idle
handling is implemented, this is about the best we can do.

In the meantime, provide a rough documenting of specifics that occur
when this function is called on actual hardware.
2019-07-11 13:09:03 -04:00
Flame Sage
0b3901bdd0 Merge pull request #2714 from DarkLordZach/repo-sync-pipeline
Add Repository Sync Pipeline
2019-07-10 22:22:04 -04:00
Zach Hilman
502358ab05 Add Repository Sync Pipeline 2019-07-10 22:18:32 -04:00
bunnei
fd066ffbce Merge pull request #2697 from lioncash/doc
gl_rasterizer: Amend documentation comment for ConfigureFramebuffers()
2019-07-10 16:38:09 -04:00
bunnei
7fb7054bc8 Merge pull request #2686 from ReinUsesLisp/vk-scheduler
vk_scheduler: Drop execution context in favor of views
2019-07-10 16:35:48 -04:00
bunnei
93eaea109d Merge pull request #2700 from ogniK5377/GetFriendList
IFriendService::GetFriendList
2019-07-10 16:29:48 -04:00
bunnei
463af08bed Merge pull request #2611 from DarkLordZach/pm-info-cmd
pm: Implement various pm commands for finding process and title IDs
2019-07-10 16:28:29 -04:00
bunnei
d707a12b9a Merge pull request #2650 from DarkLordZach/mii-iface-ver
mii: Implement IDatabaseService SetInterfaceVersion
2019-07-10 16:26:23 -04:00
bunnei
206ec29f17 Merge pull request #2691 from lioncash/override
video_core: Add missing override specifiers
2019-07-10 16:25:43 -04:00
Flame Sage
55245b6183 Merge pull request #2706 from DarkLordZach/azure-1
Add Pipeline Definitions for Azure CI
2019-07-09 22:22:21 -04:00
Zach Hilman
f2e5c19520 Add Pipeline Definitions 2019-07-09 22:17:56 -04:00
Flame Sage
05d55b0fd7 Set up CI with Azure Pipelines
[skip ci]
2019-07-09 22:01:46 -04:00
David Marcec
0330f5d6f8 IFriendService::GetFriendList
We don't have any friends implemented in Yuzu yet so it doesn't make sense to return any friends. For now we'll be returning 0 friends however the information provided will allow a proper implementation of this cmd when needed.
2019-07-09 18:20:58 +10:00
Lioncash
c04785c928 gl_rasterizer: Amend documentation comment for ConfigureFramebuffers()
must_reconfigure isn't a parameter for this function any more, so it can
be replaced with current_state.

While we're at it, we can make the parameters of the declaration match
the same name as the ones in the definition.
2019-07-09 02:08:15 -04:00
Zach Hilman
618d8446ab Merge pull request #2661 from ogniK5377/audren-loop
audren: Only manage wave buffers with a size
2019-07-08 09:35:42 -04:00
Zach Hilman
6c3cceafdc Merge pull request #2657 from ogniK5377/npad-assignments
hid:StartLrAssignmentMode, hid:StopLrAssignmentMode, hid:SwapNpadAssignment
2019-07-08 09:35:19 -04:00
David Marcec
5234e08a0d addressed issues 2019-07-08 14:51:40 +10:00
David Marcec
e3d000a7e6 addressed issue 2019-07-08 14:49:16 +10:00
bunnei
7b28f954c9 Merge pull request #2651 from DarkLordZach/apm-boost-mode-1
apm: Initial implementation of performance config and boost mode
2019-07-07 21:40:30 -04:00
bunnei
8f5aae3074 Merge pull request #2642 from DarkLordZach/fsp-log-2
fsp-srv: Implement Access Logging Functionality
2019-07-07 21:39:40 -04:00
Hexagon12
8070cb3f6b Merge pull request #2694 from FearlessTobi/patch-1
Delete decode_integer_set.cpp
2019-07-07 22:43:45 +03:00
Tobias
be020f7621 Delete decode_integer_set.cpp 2019-07-07 21:40:33 +02:00
Lioncash
cbdd6cd1c0 vk_sampler_cache: Remove unused includes
These are no longer used within this header, so they can be removed.
2019-07-07 13:40:36 -04:00
Lioncash
4b27680639 video_core: Add missing override specifiers 2019-07-07 13:38:39 -04:00
ReinUsesLisp
86a874a2fc vk_scheduler: Drop execution context in favor of views
Instead of passing by copy an execution context through out the whole
Vulkan call hierarchy, use a command buffer view and fence view
approach.

This internally dereferences the command buffer or fence forcing the
user to be unable to use an outdated version of it on normal usage.
It is still possible to keep store an outdated if it is casted to
VKFence& or vk::CommandBuffer.

While changing this file, add an extra parameter for Flush and Finish to
allow releasing the fence from this calls.
2019-07-07 03:30:22 -03:00
Zach Hilman
a4ef86a021 mii: Implement IDatabaseService SetInterfaceVersion
Appears to set a member variable used to affect the API that games access, and the method used to store data.
2019-07-06 21:39:12 -04:00
David Marcec
b82b5e46e7 audren: Only manage wave buffers with a size
We shouldn't be incrementing if wave buffers are empty. They are considered invalid/unused wave buffers.

This fixes the issue of certain sounds looping when they shouldn't
2019-07-01 21:20:23 +10:00
David Marcec
472210bf72 hid:StartLrAssignmentMode, hid:StopLrAssignmentMode, hid:SwapNpadAssignment
StartLrAssignmentMode and StopLrAssignmentMode don't require any implementation as it's just used for showing the screen of changing the controller orientation if the user wishes to do so.  Ever since #1634 this has not been needed as users can specify the controller orientation from the config and swap at any time. We store a private member just in case this gets used for anything extra in the future
2019-07-01 15:12:57 +10:00
Zach Hilman
7e5d7773cc am: Implement SetCpuBoostMode in terms of APM 2019-06-28 22:46:51 -04:00
Zach Hilman
e2ad3e1fb0 core: Keep instance of APM Controller 2019-06-28 22:46:31 -04:00
Zach Hilman
e52306ca60 apm: Implement SetCpuBoostMode 2019-06-28 22:46:00 -04:00
Zach Hilman
1c6e6305ea apm: Add getters for performance config and mode 2019-06-28 22:45:31 -04:00
Zach Hilman
9175b00e7d apm: Add apm:am service
8.0.0+ identical version of apm
2019-06-28 22:44:30 -04:00
Zach Hilman
65eb9cbb28 apm: Add Controller class to manage speed data and application 2019-06-28 22:43:51 -04:00
Zach Hilman
d40f38967e fsp-srv: Implement GetAccessLogVersionInfo
Returns some misc. data about logging to help the game determine if it should log.
2019-06-28 21:05:42 -04:00
Zach Hilman
554e2f2f98 reporter: Add report class for filesystem access logs 2019-06-28 21:02:50 -04:00
Zach Hilman
db2fdd0352 fsp-srv: Implement OutputAccessLogToSdCard
Allows games to log data to the SD.
2019-06-28 21:02:34 -04:00
Zach Hilman
bce4bfffb6 pm: Implement pm:shell and pm:dmnt GetApplicationPid
Returns the process ID of the current application or 0 if no app is running.
2019-06-26 19:07:34 -04:00
Zach Hilman
354c254cde pm: Implement pm:dmnt GetTitlePid
Takes a title ID and searches for a matching process, returning error if it doesn't exist, otherwise the process ID.
2019-06-26 19:06:51 -04:00
Zach Hilman
49af3bcdcb pm: Implement pm:info GetTitleId
Searches the process list for a process with the specified ID, returning the title ID if it exists.
2019-06-26 19:05:04 -04:00
55 changed files with 815 additions and 234 deletions

19
.ci/yuzu-mainline.yml Normal file
View File

@@ -0,0 +1,19 @@
# Starter pipeline
# Start with a minimal pipeline that you can customize to build and deploy your code.
# Add steps that build, run tests, deploy, and more:
# https://aka.ms/yaml
trigger:
- master
pool:
vmImage: 'ubuntu-latest'
steps:
- script: echo Hello, world!
displayName: 'Run a one-line script'
- script: |
echo Add other tasks to build, test, and deploy your project.
echo See https://aka.ms/yaml
displayName: 'Run a multi-line script'

19
.ci/yuzu-patreon.yml Normal file
View File

@@ -0,0 +1,19 @@
# Starter pipeline
# Start with a minimal pipeline that you can customize to build and deploy your code.
# Add steps that build, run tests, deploy, and more:
# https://aka.ms/yaml
trigger:
- master
pool:
vmImage: 'ubuntu-latest'
steps:
- script: echo Hello, world!
displayName: 'Run a one-line script'
- script: |
echo Add other tasks to build, test, and deploy your project.
echo See https://aka.ms/yaml
displayName: 'Run a multi-line script'

19
.ci/yuzu-repo-sync.yml Normal file
View File

@@ -0,0 +1,19 @@
trigger:
- master
jobs:
- job: copy
displayName: 'Sync Repository'
pool:
vmImage: 'ubuntu-latest'
steps:
- script: echo 'https://$(GitUsername):$(GitAccessToken)@dev.azure.com' > $HOME/.git-credentials
displayName: 'Load Credentials'
- script: git config --global credential.helper store
displayName: 'Register Credential Helper'
- script: git remote add other $(GitRepoPushChangesURL)
displayName: 'Register Repository'
- script: git push --force other HEAD:$(GitPushBranch)
displayName: 'Update Code'
- script: rm -rf $HOME/.git-credentials
displayName: 'Clear Cached Credentials'

19
.ci/yuzu.yml Normal file
View File

@@ -0,0 +1,19 @@
# Starter pipeline
# Start with a minimal pipeline that you can customize to build and deploy your code.
# Add steps that build, run tests, deploy, and more:
# https://aka.ms/yaml
trigger:
- master
pool:
vmImage: 'ubuntu-latest'
steps:
- script: echo Hello, world!
displayName: 'Run a one-line script'
- script: |
echo Add other tasks to build, test, and deploy your project.
echo See https://aka.ms/yaml
displayName: 'Run a multi-line script'

View File

@@ -217,13 +217,15 @@ std::vector<s16> AudioRenderer::VoiceState::DequeueSamples(std::size_t sample_co
if (offset == samples.size()) {
offset = 0;
if (!wave_buffer.is_looping) {
if (!wave_buffer.is_looping && wave_buffer.buffer_sz) {
SetWaveIndex(wave_index + 1);
}
out_status.wave_buffer_consumed++;
if (wave_buffer.buffer_sz) {
out_status.wave_buffer_consumed++;
}
if (wave_buffer.end_of_stream) {
if (wave_buffer.end_of_stream || wave_buffer.buffer_sz == 0) {
info.play_state = PlayState::Paused;
}
}

View File

@@ -208,6 +208,8 @@ add_library(core STATIC
hle/service/aoc/aoc_u.h
hle/service/apm/apm.cpp
hle/service/apm/apm.h
hle/service/apm/controller.cpp
hle/service/apm/controller.h
hle/service/apm/interface.cpp
hle/service/apm/interface.h
hle/service/audio/audctl.cpp
@@ -293,6 +295,7 @@ add_library(core STATIC
hle/service/hid/irs.h
hle/service/hid/xcd.cpp
hle/service/hid/xcd.h
hle/service/hid/errors.h
hle/service/hid/controllers/controller_base.cpp
hle/service/hid/controllers/controller_base.h
hle/service/hid/controllers/debug_pad.cpp

View File

@@ -25,6 +25,7 @@
#include "core/hle/kernel/scheduler.h"
#include "core/hle/kernel/thread.h"
#include "core/hle/service/am/applets/applets.h"
#include "core/hle/service/apm/controller.h"
#include "core/hle/service/glue/manager.h"
#include "core/hle/service/service.h"
#include "core/hle/service/sm/sm.h"
@@ -143,7 +144,7 @@ struct System::Impl {
telemetry_session = std::make_unique<Core::TelemetrySession>();
service_manager = std::make_shared<Service::SM::ServiceManager>();
Service::Init(service_manager, system, *virtual_filesystem);
Service::Init(service_manager, system);
GDBStub::Init();
renderer = VideoCore::CreateRenderer(emu_window, system);
@@ -306,6 +307,9 @@ struct System::Impl {
/// Frontend applets
Service::AM::Applets::AppletManager applet_manager;
/// APM (Performance) services
Service::APM::Controller apm_controller{core_timing};
/// Glue services
Service::Glue::ARPManager arp_manager;
@@ -568,6 +572,14 @@ const Service::Glue::ARPManager& System::GetARPManager() const {
return impl->arp_manager;
}
Service::APM::Controller& System::GetAPMController() {
return impl->apm_controller;
}
const Service::APM::Controller& System::GetAPMController() const {
return impl->apm_controller;
}
System::ResultStatus System::Init(Frontend::EmuWindow& emu_window) {
return impl->Init(*this, emu_window);
}

View File

@@ -43,6 +43,10 @@ struct AppletFrontendSet;
class AppletManager;
} // namespace AM::Applets
namespace APM {
class Controller;
}
namespace Glue {
class ARPManager;
}
@@ -296,6 +300,10 @@ public:
const Service::Glue::ARPManager& GetARPManager() const;
Service::APM::Controller& GetAPMController();
const Service::APM::Controller& GetAPMController() const;
private:
System();

View File

@@ -24,7 +24,6 @@ const std::array<const char*, 15> LANGUAGE_NAMES{{
"Korean",
"Taiwanese",
"Chinese",
"Czech", //Again not sure
}};
std::string LanguageEntry::GetApplicationName() const {

View File

@@ -88,9 +88,7 @@ enum class Language : u8 {
Korean = 12,
Taiwanese = 13,
Chinese = 14,
Czech = 17, // not sure
Default = 255,
};

View File

@@ -29,7 +29,8 @@
#include "core/hle/service/am/omm.h"
#include "core/hle/service/am/spsm.h"
#include "core/hle/service/am/tcap.h"
#include "core/hle/service/apm/apm.h"
#include "core/hle/service/apm/controller.h"
#include "core/hle/service/apm/interface.h"
#include "core/hle/service/filesystem/filesystem.h"
#include "core/hle/service/ns/ns.h"
#include "core/hle/service/nvflinger/nvflinger.h"
@@ -265,8 +266,8 @@ ISelfController::ISelfController(std::shared_ptr<NVFlinger::NVFlinger> nvflinger
{65, nullptr, "ReportUserIsActive"},
{66, nullptr, "GetCurrentIlluminance"},
{67, nullptr, "IsIlluminanceAvailable"},
{68, nullptr, "SetAutoSleepDisabled"},
{69, nullptr, "IsAutoSleepDisabled"},
{68, &ISelfController::SetAutoSleepDisabled, "SetAutoSleepDisabled"},
{69, &ISelfController::IsAutoSleepDisabled, "IsAutoSleepDisabled"},
{70, nullptr, "ReportMultimediaError"},
{71, nullptr, "GetCurrentIlluminanceEx"},
{80, nullptr, "SetWirelessPriorityMode"},
@@ -453,6 +454,34 @@ void ISelfController::GetIdleTimeDetectionExtension(Kernel::HLERequestContext& c
rb.Push<u32>(idle_time_detection_extension);
}
void ISelfController::SetAutoSleepDisabled(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
is_auto_sleep_disabled = rp.Pop<bool>();
// On the system itself, if the previous state of is_auto_sleep_disabled
// differed from the current value passed in, it'd signify the internal
// window manager to update (and also increment some statistics like update counts)
//
// It'd also indicate this change to an idle handling context.
//
// However, given we're emulating this behavior, most of this can be ignored
// and it's sufficient to simply set the member variable for querying via
// IsAutoSleepDisabled().
LOG_DEBUG(Service_AM, "called. is_auto_sleep_disabled={}", is_auto_sleep_disabled);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
}
void ISelfController::IsAutoSleepDisabled(Kernel::HLERequestContext& ctx) {
LOG_DEBUG(Service_AM, "called.");
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(RESULT_SUCCESS);
rb.Push(is_auto_sleep_disabled);
}
void ISelfController::GetAccumulatedSuspendedTickValue(Kernel::HLERequestContext& ctx) {
LOG_DEBUG(Service_AM, "called.");
@@ -520,8 +549,9 @@ void AppletMessageQueue::OperationModeChanged() {
on_operation_mode_changed.writable->Signal();
}
ICommonStateGetter::ICommonStateGetter(std::shared_ptr<AppletMessageQueue> msg_queue)
: ServiceFramework("ICommonStateGetter"), msg_queue(std::move(msg_queue)) {
ICommonStateGetter::ICommonStateGetter(Core::System& system,
std::shared_ptr<AppletMessageQueue> msg_queue)
: ServiceFramework("ICommonStateGetter"), system(system), msg_queue(std::move(msg_queue)) {
// clang-format off
static const FunctionInfo functions[] = {
{0, &ICommonStateGetter::GetEventHandle, "GetEventHandle"},
@@ -554,7 +584,7 @@ ICommonStateGetter::ICommonStateGetter(std::shared_ptr<AppletMessageQueue> msg_q
{63, nullptr, "GetHdcpAuthenticationStateChangeEvent"},
{64, nullptr, "SetTvPowerStateMatchingMode"},
{65, nullptr, "GetApplicationIdByContentActionName"},
{66, nullptr, "SetCpuBoostMode"},
{66, &ICommonStateGetter::SetCpuBoostMode, "SetCpuBoostMode"},
{80, nullptr, "PerformSystemButtonPressingIfInFocus"},
{90, nullptr, "SetPerformanceConfigurationChangedNotification"},
{91, nullptr, "GetCurrentPerformanceConfiguration"},
@@ -635,6 +665,16 @@ void ICommonStateGetter::GetDefaultDisplayResolution(Kernel::HLERequestContext&
}
}
void ICommonStateGetter::SetCpuBoostMode(Kernel::HLERequestContext& ctx) {
LOG_DEBUG(Service_AM, "called, forwarding to APM:SYS");
const auto& sm = system.ServiceManager();
const auto apm_sys = sm.GetService<APM::APM_Sys>("apm:sys");
ASSERT(apm_sys != nullptr);
apm_sys->SetCpuBoostMode(ctx);
}
IStorage::IStorage(std::vector<u8> buffer)
: ServiceFramework("IStorage"), buffer(std::move(buffer)) {
// clang-format off
@@ -663,13 +703,11 @@ void ICommonStateGetter::GetOperationMode(Kernel::HLERequestContext& ctx) {
}
void ICommonStateGetter::GetPerformanceMode(Kernel::HLERequestContext& ctx) {
const bool use_docked_mode{Settings::values.use_docked_mode};
LOG_DEBUG(Service_AM, "called, use_docked_mode={}", use_docked_mode);
LOG_DEBUG(Service_AM, "called");
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(RESULT_SUCCESS);
rb.Push(static_cast<u32>(use_docked_mode ? APM::PerformanceMode::Docked
: APM::PerformanceMode::Handheld));
rb.PushEnum(system.GetAPMController().GetCurrentPerformanceMode());
}
class ILibraryAppletAccessor final : public ServiceFramework<ILibraryAppletAccessor> {

View File

@@ -36,7 +36,6 @@ enum SystemLanguage {
// 4.0.0+
SimplifiedChinese = 15,
TraditionalChinese = 16,
Czech = 17,//cs-CZ
};
class AppletMessageQueue {
@@ -134,6 +133,8 @@ private:
void SetHandlesRequestToDisplay(Kernel::HLERequestContext& ctx);
void SetIdleTimeDetectionExtension(Kernel::HLERequestContext& ctx);
void GetIdleTimeDetectionExtension(Kernel::HLERequestContext& ctx);
void SetAutoSleepDisabled(Kernel::HLERequestContext& ctx);
void IsAutoSleepDisabled(Kernel::HLERequestContext& ctx);
void GetAccumulatedSuspendedTickValue(Kernel::HLERequestContext& ctx);
void GetAccumulatedSuspendedTickChangedEvent(Kernel::HLERequestContext& ctx);
@@ -143,11 +144,13 @@ private:
u32 idle_time_detection_extension = 0;
u64 num_fatal_sections_entered = 0;
bool is_auto_sleep_disabled = false;
};
class ICommonStateGetter final : public ServiceFramework<ICommonStateGetter> {
public:
explicit ICommonStateGetter(std::shared_ptr<AppletMessageQueue> msg_queue);
explicit ICommonStateGetter(Core::System& system,
std::shared_ptr<AppletMessageQueue> msg_queue);
~ICommonStateGetter() override;
private:
@@ -169,7 +172,9 @@ private:
void GetPerformanceMode(Kernel::HLERequestContext& ctx);
void GetBootMode(Kernel::HLERequestContext& ctx);
void GetDefaultDisplayResolution(Kernel::HLERequestContext& ctx);
void SetCpuBoostMode(Kernel::HLERequestContext& ctx);
Core::System& system;
std::shared_ptr<AppletMessageQueue> msg_queue;
};

View File

@@ -42,7 +42,7 @@ private:
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
rb.PushIpcInterface<ICommonStateGetter>(msg_queue);
rb.PushIpcInterface<ICommonStateGetter>(system, msg_queue);
}
void GetSelfController(Kernel::HLERequestContext& ctx) {
@@ -146,7 +146,7 @@ private:
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
rb.PushIpcInterface<ICommonStateGetter>(msg_queue);
rb.PushIpcInterface<ICommonStateGetter>(system, msg_queue);
}
void GetSelfController(Kernel::HLERequestContext& ctx) {

View File

@@ -80,7 +80,7 @@ private:
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
rb.PushIpcInterface<ICommonStateGetter>(msg_queue);
rb.PushIpcInterface<ICommonStateGetter>(system, msg_queue);
}
void GetLibraryAppletCreator(Kernel::HLERequestContext& ctx) {

View File

@@ -2,7 +2,6 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#include "common/logging/log.h"
#include "core/hle/ipc_helpers.h"
#include "core/hle/service/apm/apm.h"
#include "core/hle/service/apm/interface.h"
@@ -12,11 +11,15 @@ namespace Service::APM {
Module::Module() = default;
Module::~Module() = default;
void InstallInterfaces(SM::ServiceManager& service_manager) {
void InstallInterfaces(Core::System& system) {
auto module_ = std::make_shared<Module>();
std::make_shared<APM>(module_, "apm")->InstallAsService(service_manager);
std::make_shared<APM>(module_, "apm:p")->InstallAsService(service_manager);
std::make_shared<APM_Sys>()->InstallAsService(service_manager);
std::make_shared<APM>(module_, system.GetAPMController(), "apm")
->InstallAsService(system.ServiceManager());
std::make_shared<APM>(module_, system.GetAPMController(), "apm:p")
->InstallAsService(system.ServiceManager());
std::make_shared<APM>(module_, system.GetAPMController(), "apm:am")
->InstallAsService(system.ServiceManager());
std::make_shared<APM_Sys>(system.GetAPMController())->InstallAsService(system.ServiceManager());
}
} // namespace Service::APM

View File

@@ -8,11 +8,6 @@
namespace Service::APM {
enum class PerformanceMode : u8 {
Handheld = 0,
Docked = 1,
};
class Module final {
public:
Module();
@@ -20,6 +15,6 @@ public:
};
/// Registers all AM services with the specified service manager.
void InstallInterfaces(SM::ServiceManager& service_manager);
void InstallInterfaces(Core::System& system);
} // namespace Service::APM

View File

@@ -0,0 +1,68 @@
// Copyright 2019 yuzu emulator team
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#include "common/logging/log.h"
#include "core/core_timing.h"
#include "core/hle/service/apm/controller.h"
#include "core/settings.h"
namespace Service::APM {
constexpr PerformanceConfiguration DEFAULT_PERFORMANCE_CONFIGURATION =
PerformanceConfiguration::Config7;
Controller::Controller(Core::Timing::CoreTiming& core_timing)
: core_timing(core_timing), configs{
{PerformanceMode::Handheld, DEFAULT_PERFORMANCE_CONFIGURATION},
{PerformanceMode::Docked, DEFAULT_PERFORMANCE_CONFIGURATION},
} {}
Controller::~Controller() = default;
void Controller::SetPerformanceConfiguration(PerformanceMode mode,
PerformanceConfiguration config) {
static const std::map<PerformanceConfiguration, u32> PCONFIG_TO_SPEED_MAP{
{PerformanceConfiguration::Config1, 1020}, {PerformanceConfiguration::Config2, 1020},
{PerformanceConfiguration::Config3, 1224}, {PerformanceConfiguration::Config4, 1020},
{PerformanceConfiguration::Config5, 1020}, {PerformanceConfiguration::Config6, 1224},
{PerformanceConfiguration::Config7, 1020}, {PerformanceConfiguration::Config8, 1020},
{PerformanceConfiguration::Config9, 1020}, {PerformanceConfiguration::Config10, 1020},
{PerformanceConfiguration::Config11, 1020}, {PerformanceConfiguration::Config12, 1020},
{PerformanceConfiguration::Config13, 1785}, {PerformanceConfiguration::Config14, 1785},
{PerformanceConfiguration::Config15, 1020}, {PerformanceConfiguration::Config16, 1020},
};
SetClockSpeed(PCONFIG_TO_SPEED_MAP.find(config)->second);
configs.insert_or_assign(mode, config);
}
void Controller::SetFromCpuBoostMode(CpuBoostMode mode) {
constexpr std::array<PerformanceConfiguration, 3> BOOST_MODE_TO_CONFIG_MAP{{
PerformanceConfiguration::Config7,
PerformanceConfiguration::Config13,
PerformanceConfiguration::Config15,
}};
SetPerformanceConfiguration(PerformanceMode::Docked,
BOOST_MODE_TO_CONFIG_MAP.at(static_cast<u32>(mode)));
}
PerformanceMode Controller::GetCurrentPerformanceMode() {
return Settings::values.use_docked_mode ? PerformanceMode::Docked : PerformanceMode::Handheld;
}
PerformanceConfiguration Controller::GetCurrentPerformanceConfiguration(PerformanceMode mode) {
if (configs.find(mode) == configs.end()) {
configs.insert_or_assign(mode, DEFAULT_PERFORMANCE_CONFIGURATION);
}
return configs[mode];
}
void Controller::SetClockSpeed(u32 mhz) {
LOG_INFO(Service_APM, "called, mhz={:08X}", mhz);
// TODO(DarkLordZach): Actually signal core_timing to change clock speed.
}
} // namespace Service::APM

View File

@@ -0,0 +1,70 @@
// Copyright 2019 yuzu emulator team
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#pragma once
#include <map>
#include "common/common_types.h"
namespace Core::Timing {
class CoreTiming;
}
namespace Service::APM {
enum class PerformanceConfiguration : u32 {
Config1 = 0x00010000,
Config2 = 0x00010001,
Config3 = 0x00010002,
Config4 = 0x00020000,
Config5 = 0x00020001,
Config6 = 0x00020002,
Config7 = 0x00020003,
Config8 = 0x00020004,
Config9 = 0x00020005,
Config10 = 0x00020006,
Config11 = 0x92220007,
Config12 = 0x92220008,
Config13 = 0x92220009,
Config14 = 0x9222000A,
Config15 = 0x9222000B,
Config16 = 0x9222000C,
};
enum class CpuBoostMode : u32 {
Disabled = 0,
Full = 1, // CPU + GPU -> Config 13, 14, 15, or 16
Partial = 2, // GPU Only -> Config 15 or 16
};
enum class PerformanceMode : u8 {
Handheld = 0,
Docked = 1,
};
// Class to manage the state and change of the emulated system performance.
// Specifically, this deals with PerformanceMode, which corresponds to the system being docked or
// undocked, and PerformanceConfig which specifies the exact CPU, GPU, and Memory clocks to operate
// at. Additionally, this manages 'Boost Mode', which allows games to temporarily overclock the
// system during times of high load -- this simply maps to different PerformanceConfigs to use.
class Controller {
public:
Controller(Core::Timing::CoreTiming& core_timing);
~Controller();
void SetPerformanceConfiguration(PerformanceMode mode, PerformanceConfiguration config);
void SetFromCpuBoostMode(CpuBoostMode mode);
PerformanceMode GetCurrentPerformanceMode();
PerformanceConfiguration GetCurrentPerformanceConfiguration(PerformanceMode mode);
private:
void SetClockSpeed(u32 mhz);
std::map<PerformanceMode, PerformanceConfiguration> configs;
Core::Timing::CoreTiming& core_timing;
};
} // namespace Service::APM

View File

@@ -5,43 +5,32 @@
#include "common/logging/log.h"
#include "core/hle/ipc_helpers.h"
#include "core/hle/service/apm/apm.h"
#include "core/hle/service/apm/controller.h"
#include "core/hle/service/apm/interface.h"
namespace Service::APM {
class ISession final : public ServiceFramework<ISession> {
public:
ISession() : ServiceFramework("ISession") {
ISession(Controller& controller) : ServiceFramework("ISession"), controller(controller) {
static const FunctionInfo functions[] = {
{0, &ISession::SetPerformanceConfiguration, "SetPerformanceConfiguration"},
{1, &ISession::GetPerformanceConfiguration, "GetPerformanceConfiguration"},
{2, nullptr, "SetCpuOverclockEnabled"},
};
RegisterHandlers(functions);
}
private:
enum class PerformanceConfiguration : u32 {
Config1 = 0x00010000,
Config2 = 0x00010001,
Config3 = 0x00010002,
Config4 = 0x00020000,
Config5 = 0x00020001,
Config6 = 0x00020002,
Config7 = 0x00020003,
Config8 = 0x00020004,
Config9 = 0x00020005,
Config10 = 0x00020006,
Config11 = 0x92220007,
Config12 = 0x92220008,
};
void SetPerformanceConfiguration(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
auto mode = static_cast<PerformanceMode>(rp.Pop<u32>());
u32 config = rp.Pop<u32>();
LOG_WARNING(Service_APM, "(STUBBED) called mode={} config={}", static_cast<u32>(mode),
config);
const auto mode = rp.PopEnum<PerformanceMode>();
const auto config = rp.PopEnum<PerformanceConfiguration>();
LOG_DEBUG(Service_APM, "called mode={} config={}", static_cast<u32>(mode),
static_cast<u32>(config));
controller.SetPerformanceConfiguration(mode, config);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
@@ -50,20 +39,23 @@ private:
void GetPerformanceConfiguration(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
auto mode = static_cast<PerformanceMode>(rp.Pop<u32>());
LOG_WARNING(Service_APM, "(STUBBED) called mode={}", static_cast<u32>(mode));
const auto mode = rp.PopEnum<PerformanceMode>();
LOG_DEBUG(Service_APM, "called mode={}", static_cast<u32>(mode));
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(RESULT_SUCCESS);
rb.Push<u32>(static_cast<u32>(PerformanceConfiguration::Config1));
rb.PushEnum(controller.GetCurrentPerformanceConfiguration(mode));
}
Controller& controller;
};
APM::APM(std::shared_ptr<Module> apm, const char* name)
: ServiceFramework(name), apm(std::move(apm)) {
APM::APM(std::shared_ptr<Module> apm, Controller& controller, const char* name)
: ServiceFramework(name), apm(std::move(apm)), controller(controller) {
static const FunctionInfo functions[] = {
{0, &APM::OpenSession, "OpenSession"},
{1, nullptr, "GetPerformanceMode"},
{1, &APM::GetPerformanceMode, "GetPerformanceMode"},
{6, nullptr, "IsCpuOverclockEnabled"},
};
RegisterHandlers(functions);
}
@@ -75,10 +67,17 @@ void APM::OpenSession(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
rb.PushIpcInterface<ISession>();
rb.PushIpcInterface<ISession>(controller);
}
APM_Sys::APM_Sys() : ServiceFramework{"apm:sys"} {
void APM::GetPerformanceMode(Kernel::HLERequestContext& ctx) {
LOG_DEBUG(Service_APM, "called");
IPC::ResponseBuilder rb{ctx, 2};
rb.PushEnum(controller.GetCurrentPerformanceMode());
}
APM_Sys::APM_Sys(Controller& controller) : ServiceFramework{"apm:sys"}, controller(controller) {
// clang-format off
static const FunctionInfo functions[] = {
{0, nullptr, "RequestPerformanceMode"},
@@ -87,8 +86,8 @@ APM_Sys::APM_Sys() : ServiceFramework{"apm:sys"} {
{3, nullptr, "GetLastThrottlingState"},
{4, nullptr, "ClearLastThrottlingState"},
{5, nullptr, "LoadAndApplySettings"},
{6, nullptr, "SetCpuBoostMode"},
{7, nullptr, "GetCurrentPerformanceConfiguration"},
{6, &APM_Sys::SetCpuBoostMode, "SetCpuBoostMode"},
{7, &APM_Sys::GetCurrentPerformanceConfiguration, "GetCurrentPerformanceConfiguration"},
};
// clang-format on
@@ -102,7 +101,28 @@ void APM_Sys::GetPerformanceEvent(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
rb.PushIpcInterface<ISession>();
rb.PushIpcInterface<ISession>(controller);
}
void APM_Sys::SetCpuBoostMode(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto mode = rp.PopEnum<CpuBoostMode>();
LOG_DEBUG(Service_APM, "called, mode={:08X}", static_cast<u32>(mode));
controller.SetFromCpuBoostMode(mode);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
}
void APM_Sys::GetCurrentPerformanceConfiguration(Kernel::HLERequestContext& ctx) {
LOG_DEBUG(Service_APM, "called");
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(RESULT_SUCCESS);
rb.PushEnum(
controller.GetCurrentPerformanceConfiguration(controller.GetCurrentPerformanceMode()));
}
} // namespace Service::APM

View File

@@ -8,24 +8,34 @@
namespace Service::APM {
class Controller;
class Module;
class APM final : public ServiceFramework<APM> {
public:
explicit APM(std::shared_ptr<Module> apm, const char* name);
explicit APM(std::shared_ptr<Module> apm, Controller& controller, const char* name);
~APM() override;
private:
void OpenSession(Kernel::HLERequestContext& ctx);
void GetPerformanceMode(Kernel::HLERequestContext& ctx);
std::shared_ptr<Module> apm;
Controller& controller;
};
class APM_Sys final : public ServiceFramework<APM_Sys> {
public:
explicit APM_Sys();
explicit APM_Sys(Controller& controller);
~APM_Sys() override;
void SetCpuBoostMode(Kernel::HLERequestContext& ctx);
private:
void GetPerformanceEvent(Kernel::HLERequestContext& ctx);
void GetCurrentPerformanceConfiguration(Kernel::HLERequestContext& ctx);
Controller& controller;
};
} // namespace Service::APM

View File

@@ -472,12 +472,12 @@ void CreateFactories(FileSys::VfsFilesystem& vfs, bool overwrite) {
}
}
void InstallInterfaces(SM::ServiceManager& service_manager, FileSys::VfsFilesystem& vfs) {
void InstallInterfaces(Core::System& system) {
romfs_factory = nullptr;
CreateFactories(vfs, false);
std::make_shared<FSP_LDR>()->InstallAsService(service_manager);
std::make_shared<FSP_PR>()->InstallAsService(service_manager);
std::make_shared<FSP_SRV>()->InstallAsService(service_manager);
CreateFactories(*system.GetFilesystem(), false);
std::make_shared<FSP_LDR>()->InstallAsService(system.ServiceManager());
std::make_shared<FSP_PR>()->InstallAsService(system.ServiceManager());
std::make_shared<FSP_SRV>(system.GetReporter())->InstallAsService(system.ServiceManager());
}
} // namespace Service::FileSystem

View File

@@ -65,7 +65,7 @@ FileSys::VirtualDir GetModificationDumpRoot(u64 title_id);
// above is called.
void CreateFactories(FileSys::VfsFilesystem& vfs, bool overwrite = true);
void InstallInterfaces(SM::ServiceManager& service_manager, FileSys::VfsFilesystem& vfs);
void InstallInterfaces(Core::System& system);
// A class that wraps a VfsDirectory with methods that return ResultVal and ResultCode instead of
// pointers and booleans. This makes using a VfsDirectory with switch services much easier and

View File

@@ -26,6 +26,7 @@
#include "core/hle/kernel/process.h"
#include "core/hle/service/filesystem/filesystem.h"
#include "core/hle/service/filesystem/fsp_srv.h"
#include "core/reporter.h"
namespace Service::FileSystem {
@@ -613,7 +614,7 @@ private:
u64 next_entry_index = 0;
};
FSP_SRV::FSP_SRV() : ServiceFramework("fsp-srv") {
FSP_SRV::FSP_SRV(const Core::Reporter& reporter) : ServiceFramework("fsp-srv"), reporter(reporter) {
// clang-format off
static const FunctionInfo functions[] = {
{0, nullptr, "OpenFileSystem"},
@@ -710,14 +711,14 @@ FSP_SRV::FSP_SRV() : ServiceFramework("fsp-srv") {
{1001, nullptr, "SetSaveDataSize"},
{1002, nullptr, "SetSaveDataRootPath"},
{1003, nullptr, "DisableAutoSaveDataCreation"},
{1004, nullptr, "SetGlobalAccessLogMode"},
{1004, &FSP_SRV::SetGlobalAccessLogMode, "SetGlobalAccessLogMode"},
{1005, &FSP_SRV::GetGlobalAccessLogMode, "GetGlobalAccessLogMode"},
{1006, nullptr, "OutputAccessLogToSdCard"},
{1006, &FSP_SRV::OutputAccessLogToSdCard, "OutputAccessLogToSdCard"},
{1007, nullptr, "RegisterUpdatePartition"},
{1008, nullptr, "OpenRegisteredUpdatePartition"},
{1009, nullptr, "GetAndClearMemoryReportInfo"},
{1010, nullptr, "SetDataStorageRedirectTarget"},
{1011, nullptr, "OutputAccessLogToSdCard2"},
{1011, &FSP_SRV::GetAccessLogVersionInfo, "GetAccessLogVersionInfo"},
{1100, nullptr, "OverrideSaveDataTransferTokenSignVerificationKey"},
{1110, nullptr, "CorruptSaveDataFileSystemBySaveDataSpaceId2"},
{1200, nullptr, "OpenMultiCommitManager"},
@@ -814,21 +815,22 @@ void FSP_SRV::OpenSaveDataInfoReaderBySaveDataSpaceId(Kernel::HLERequestContext&
rb.PushIpcInterface<ISaveDataInfoReader>(std::make_shared<ISaveDataInfoReader>(space));
}
void FSP_SRV::SetGlobalAccessLogMode(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
log_mode = rp.PopEnum<LogMode>();
LOG_DEBUG(Service_FS, "called, log_mode={:08X}", static_cast<u32>(log_mode));
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
}
void FSP_SRV::GetGlobalAccessLogMode(Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service_FS, "(STUBBED) called");
LOG_DEBUG(Service_FS, "called");
enum class LogMode : u32 {
Off,
Log,
RedirectToSdCard,
LogToSdCard = Log | RedirectToSdCard,
};
// Given we always want to receive logging information,
// we always specify logging as enabled.
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(RESULT_SUCCESS);
rb.PushEnum(LogMode::Log);
rb.PushEnum(log_mode);
}
void FSP_SRV::OpenDataStorageByCurrentProcess(Kernel::HLERequestContext& ctx) {
@@ -902,4 +904,26 @@ void FSP_SRV::OpenPatchDataStorageByCurrentProcess(Kernel::HLERequestContext& ct
rb.Push(FileSys::ERROR_ENTITY_NOT_FOUND);
}
void FSP_SRV::OutputAccessLogToSdCard(Kernel::HLERequestContext& ctx) {
const auto raw = ctx.ReadBuffer();
auto log = Common::StringFromFixedZeroTerminatedBuffer(
reinterpret_cast<const char*>(raw.data()), raw.size());
LOG_DEBUG(Service_FS, "called, log='{}'", log);
reporter.SaveFilesystemAccessReport(log_mode, std::move(log));
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
}
void FSP_SRV::GetAccessLogVersionInfo(Kernel::HLERequestContext& ctx) {
LOG_DEBUG(Service_FS, "called");
IPC::ResponseBuilder rb{ctx, 4};
rb.Push(RESULT_SUCCESS);
rb.PushEnum(AccessLogVersion::Latest);
rb.Push(access_log_program_index);
}
} // namespace Service::FileSystem

View File

@@ -7,15 +7,32 @@
#include <memory>
#include "core/hle/service/service.h"
namespace Core {
class Reporter;
}
namespace FileSys {
class FileSystemBackend;
}
namespace Service::FileSystem {
enum class AccessLogVersion : u32 {
V7_0_0 = 2,
Latest = V7_0_0,
};
enum class LogMode : u32 {
Off,
Log,
RedirectToSdCard,
LogToSdCard = Log | RedirectToSdCard,
};
class FSP_SRV final : public ServiceFramework<FSP_SRV> {
public:
explicit FSP_SRV();
explicit FSP_SRV(const Core::Reporter& reporter);
~FSP_SRV() override;
private:
@@ -26,13 +43,20 @@ private:
void OpenSaveDataFileSystem(Kernel::HLERequestContext& ctx);
void OpenReadOnlySaveDataFileSystem(Kernel::HLERequestContext& ctx);
void OpenSaveDataInfoReaderBySaveDataSpaceId(Kernel::HLERequestContext& ctx);
void SetGlobalAccessLogMode(Kernel::HLERequestContext& ctx);
void GetGlobalAccessLogMode(Kernel::HLERequestContext& ctx);
void OpenDataStorageByCurrentProcess(Kernel::HLERequestContext& ctx);
void OpenDataStorageByDataId(Kernel::HLERequestContext& ctx);
void OpenPatchDataStorageByCurrentProcess(Kernel::HLERequestContext& ctx);
void OutputAccessLogToSdCard(Kernel::HLERequestContext& ctx);
void GetAccessLogVersionInfo(Kernel::HLERequestContext& ctx);
FileSys::VirtualFile romfs;
u64 current_process_id = 0;
u32 access_log_program_index = 0;
LogMode log_mode = LogMode::LogToSdCard;
const Core::Reporter& reporter;
};
} // namespace Service::FileSystem

View File

@@ -22,7 +22,7 @@ public:
{0, nullptr, "GetCompletionEvent"},
{1, nullptr, "Cancel"},
{10100, nullptr, "GetFriendListIds"},
{10101, nullptr, "GetFriendList"},
{10101, &IFriendService::GetFriendList, "GetFriendList"},
{10102, nullptr, "UpdateFriendInfo"},
{10110, nullptr, "GetFriendProfileImage"},
{10200, nullptr, "SendFriendRequestForApplication"},
@@ -99,6 +99,23 @@ public:
}
private:
enum class PresenceFilter : u32 {
None = 0,
Online = 1,
OnlinePlay = 2,
OnlineOrOnlinePlay = 3,
};
struct SizedFriendFilter {
PresenceFilter presence;
u8 is_favorite;
u8 same_app;
u8 same_app_played;
u8 arbitary_app_played;
u64 group_id;
};
static_assert(sizeof(SizedFriendFilter) == 0x10, "SizedFriendFilter is an invalid size");
void DeclareCloseOnlinePlaySession(Kernel::HLERequestContext& ctx) {
// Stub used by Splatoon 2
LOG_WARNING(Service_ACC, "(STUBBED) called");
@@ -112,6 +129,22 @@ private:
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
}
void GetFriendList(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto friend_offset = rp.Pop<u32>();
const auto uuid = rp.PopRaw<Common::UUID>();
[[maybe_unused]] const auto filter = rp.PopRaw<SizedFriendFilter>();
const auto pid = rp.Pop<u64>();
LOG_WARNING(Service_ACC, "(STUBBED) called, offset={}, uuid={}, pid={}", friend_offset,
uuid.Format(), pid);
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(RESULT_SUCCESS);
rb.Push<u32>(0); // Friend count
// TODO(ogniK): Return a buffer of u64s which are the "NetworkServiceAccountId"
}
};
class INotificationService final : public ServiceFramework<INotificationService> {

View File

@@ -548,6 +548,37 @@ void Controller_NPad::DisconnectNPad(u32 npad_id) {
connected_controllers[NPadIdToIndex(npad_id)].is_connected = false;
}
void Controller_NPad::StartLRAssignmentMode() {
// Nothing internally is used for lr assignment mode. Since we have the ability to set the
// controller types from boot, it doesn't really matter about showing a selection screen
is_in_lr_assignment_mode = true;
}
void Controller_NPad::StopLRAssignmentMode() {
is_in_lr_assignment_mode = false;
}
bool Controller_NPad::SwapNpadAssignment(u32 npad_id_1, u32 npad_id_2) {
if (npad_id_1 == NPAD_HANDHELD || npad_id_2 == NPAD_HANDHELD || npad_id_1 == NPAD_UNKNOWN ||
npad_id_2 == NPAD_UNKNOWN) {
return true;
}
const auto npad_index_1 = NPadIdToIndex(npad_id_1);
const auto npad_index_2 = NPadIdToIndex(npad_id_2);
if (!IsControllerSupported(connected_controllers[npad_index_1].type) ||
!IsControllerSupported(connected_controllers[npad_index_2].type)) {
return false;
}
std::swap(connected_controllers[npad_index_1].type, connected_controllers[npad_index_2].type);
InitNewlyAddedControler(npad_index_1);
InitNewlyAddedControler(npad_index_2);
return true;
}
bool Controller_NPad::IsControllerSupported(NPadControllerType controller) {
if (controller == NPadControllerType::Handheld) {
// Handheld is not even a supported type, lets stop here

View File

@@ -124,6 +124,10 @@ public:
void ConnectAllDisconnectedControllers();
void ClearAllControllers();
void StartLRAssignmentMode();
void StopLRAssignmentMode();
bool SwapNpadAssignment(u32 npad_id_1, u32 npad_id_2);
// Logical OR for all buttons presses on all controllers
// Specifically for cheat engine and other features.
u32 GetAndResetPressState();
@@ -321,5 +325,6 @@ private:
void RequestPadStateUpdate(u32 npad_id);
std::array<ControllerPad, 10> npad_pad_states{};
bool IsControllerSupported(NPadControllerType controller);
bool is_in_lr_assignment_mode{false};
};
} // namespace Service::HID

View File

@@ -0,0 +1,13 @@
// Copyright 2019 yuzu emulator team
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#pragma once
#include "core/hle/result.h"
namespace Service::HID {
constexpr ResultCode ERR_NPAD_NOT_CONNECTED{ErrorModule::HID, 710};
} // namespace Service::HID

View File

@@ -16,6 +16,7 @@
#include "core/hle/kernel/readable_event.h"
#include "core/hle/kernel/shared_memory.h"
#include "core/hle/kernel/writable_event.h"
#include "core/hle/service/hid/errors.h"
#include "core/hle/service/hid/hid.h"
#include "core/hle/service/hid/irs.h"
#include "core/hle/service/hid/xcd.h"
@@ -202,11 +203,11 @@ Hid::Hid() : ServiceFramework("hid") {
{123, nullptr, "SetNpadJoyAssignmentModeSingleByDefault"},
{124, &Hid::SetNpadJoyAssignmentModeDual, "SetNpadJoyAssignmentModeDual"},
{125, &Hid::MergeSingleJoyAsDualJoy, "MergeSingleJoyAsDualJoy"},
{126, nullptr, "StartLrAssignmentMode"},
{127, nullptr, "StopLrAssignmentMode"},
{126, &Hid::StartLrAssignmentMode, "StartLrAssignmentMode"},
{127, &Hid::StopLrAssignmentMode, "StopLrAssignmentMode"},
{128, &Hid::SetNpadHandheldActivationMode, "SetNpadHandheldActivationMode"},
{129, nullptr, "GetNpadHandheldActivationMode"},
{130, nullptr, "SwapNpadAssignment"},
{130, &Hid::SwapNpadAssignment, "SwapNpadAssignment"},
{131, nullptr, "IsUnintendedHomeButtonInputProtectionEnabled"},
{132, nullptr, "EnableUnintendedHomeButtonInputProtection"},
{133, nullptr, "SetNpadJoyAssignmentModeSingleWithDestination"},
@@ -733,6 +734,49 @@ void Hid::SetPalmaBoostMode(Kernel::HLERequestContext& ctx) {
rb.Push(RESULT_SUCCESS);
}
void Hid::StartLrAssignmentMode(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto applet_resource_user_id{rp.Pop<u64>()};
LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
auto& controller = applet_resource->GetController<Controller_NPad>(HidController::NPad);
controller.StartLRAssignmentMode();
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
}
void Hid::StopLrAssignmentMode(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto applet_resource_user_id{rp.Pop<u64>()};
LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
auto& controller = applet_resource->GetController<Controller_NPad>(HidController::NPad);
controller.StopLRAssignmentMode();
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
}
void Hid::SwapNpadAssignment(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto npad_1{rp.Pop<u32>()};
const auto npad_2{rp.Pop<u32>()};
const auto applet_resource_user_id{rp.Pop<u64>()};
LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}, npad_1={}, npad_2={}",
applet_resource_user_id, npad_1, npad_2);
auto& controller = applet_resource->GetController<Controller_NPad>(HidController::NPad);
IPC::ResponseBuilder rb{ctx, 2};
if (controller.SwapNpadAssignment(npad_1, npad_2)) {
rb.Push(RESULT_SUCCESS);
} else {
LOG_ERROR(Service_HID, "Npads are not connected!");
rb.Push(ERR_NPAD_NOT_CONNECTED);
}
}
class HidDbg final : public ServiceFramework<HidDbg> {
public:
explicit HidDbg() : ServiceFramework{"hid:dbg"} {

View File

@@ -119,6 +119,9 @@ private:
void StopSixAxisSensor(Kernel::HLERequestContext& ctx);
void SetIsPalmaAllConnectable(Kernel::HLERequestContext& ctx);
void SetPalmaBoostMode(Kernel::HLERequestContext& ctx);
void StartLrAssignmentMode(Kernel::HLERequestContext& ctx);
void StopLrAssignmentMode(Kernel::HLERequestContext& ctx);
void SwapNpadAssignment(Kernel::HLERequestContext& ctx);
std::shared_ptr<IAppletResource> applet_resource;
};

View File

@@ -48,7 +48,7 @@ public:
{19, nullptr, "Export"},
{20, nullptr, "IsBrokenDatabaseWithClearFlag"},
{21, &IDatabaseService::GetIndex, "GetIndex"},
{22, nullptr, "SetInterfaceVersion"},
{22, &IDatabaseService::SetInterfaceVersion, "SetInterfaceVersion"},
{23, nullptr, "Convert"},
};
// clang-format on
@@ -350,8 +350,22 @@ private:
rb.Push(index);
}
void SetInterfaceVersion(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
current_interface_version = rp.PopRaw<u32>();
LOG_DEBUG(Service_Mii, "called, interface_version={:08X}", current_interface_version);
UNIMPLEMENTED_IF(current_interface_version != 1);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
}
MiiManager db;
u32 current_interface_version = 0;
// Last read offsets of Get functions
std::array<u32, 4> offsets{};
};

View File

@@ -23,7 +23,6 @@ constexpr ApplicationLanguagePriorityList priority_list_american_english = {{
ApplicationLanguage::SimplifiedChinese,
ApplicationLanguage::TraditionalChinese,
ApplicationLanguage::Korean,
ApplicationLanguage::Czech,
}};
constexpr ApplicationLanguagePriorityList priority_list_british_english = {{
@@ -42,7 +41,6 @@ constexpr ApplicationLanguagePriorityList priority_list_british_english = {{
ApplicationLanguage::SimplifiedChinese,
ApplicationLanguage::TraditionalChinese,
ApplicationLanguage::Korean,
ApplicationLanguage::Czech,
}};
constexpr ApplicationLanguagePriorityList priority_list_japanese = {{
@@ -61,7 +59,6 @@ constexpr ApplicationLanguagePriorityList priority_list_japanese = {{
ApplicationLanguage::SimplifiedChinese,
ApplicationLanguage::TraditionalChinese,
ApplicationLanguage::Korean,
ApplicationLanguage::Czech,
}};
constexpr ApplicationLanguagePriorityList priority_list_french = {{
@@ -80,7 +77,6 @@ constexpr ApplicationLanguagePriorityList priority_list_french = {{
ApplicationLanguage::SimplifiedChinese,
ApplicationLanguage::TraditionalChinese,
ApplicationLanguage::Korean,
ApplicationLanguage::Czech,
}};
constexpr ApplicationLanguagePriorityList priority_list_german = {{
@@ -99,7 +95,6 @@ constexpr ApplicationLanguagePriorityList priority_list_german = {{
ApplicationLanguage::SimplifiedChinese,
ApplicationLanguage::TraditionalChinese,
ApplicationLanguage::Korean,
ApplicationLanguage::Czech,
}};
constexpr ApplicationLanguagePriorityList priority_list_latin_american_spanish = {{
@@ -118,7 +113,6 @@ constexpr ApplicationLanguagePriorityList priority_list_latin_american_spanish =
ApplicationLanguage::SimplifiedChinese,
ApplicationLanguage::TraditionalChinese,
ApplicationLanguage::Korean,
ApplicationLanguage::Czech,
}};
constexpr ApplicationLanguagePriorityList priority_list_spanish = {{
@@ -137,7 +131,6 @@ constexpr ApplicationLanguagePriorityList priority_list_spanish = {{
ApplicationLanguage::SimplifiedChinese,
ApplicationLanguage::TraditionalChinese,
ApplicationLanguage::Korean,
ApplicationLanguage::Czech,
}};
constexpr ApplicationLanguagePriorityList priority_list_italian = {{
@@ -156,7 +149,6 @@ constexpr ApplicationLanguagePriorityList priority_list_italian = {{
ApplicationLanguage::SimplifiedChinese,
ApplicationLanguage::TraditionalChinese,
ApplicationLanguage::Korean,
ApplicationLanguage::Czech,
}};
constexpr ApplicationLanguagePriorityList priority_list_dutch = {{
@@ -175,7 +167,6 @@ constexpr ApplicationLanguagePriorityList priority_list_dutch = {{
ApplicationLanguage::SimplifiedChinese,
ApplicationLanguage::TraditionalChinese,
ApplicationLanguage::Korean,
ApplicationLanguage::Czech,
}};
constexpr ApplicationLanguagePriorityList priority_list_canadian_french = {{
@@ -194,7 +185,6 @@ constexpr ApplicationLanguagePriorityList priority_list_canadian_french = {{
ApplicationLanguage::SimplifiedChinese,
ApplicationLanguage::TraditionalChinese,
ApplicationLanguage::Korean,
ApplicationLanguage::Czech,
}};
constexpr ApplicationLanguagePriorityList priority_list_portuguese = {{
@@ -213,7 +203,6 @@ constexpr ApplicationLanguagePriorityList priority_list_portuguese = {{
ApplicationLanguage::SimplifiedChinese,
ApplicationLanguage::TraditionalChinese,
ApplicationLanguage::Korean,
ApplicationLanguage::Czech,
}};
constexpr ApplicationLanguagePriorityList priority_list_russian = {{
@@ -232,7 +221,6 @@ constexpr ApplicationLanguagePriorityList priority_list_russian = {{
ApplicationLanguage::SimplifiedChinese,
ApplicationLanguage::TraditionalChinese,
ApplicationLanguage::Korean,
ApplicationLanguage::Czech,
}};
constexpr ApplicationLanguagePriorityList priority_list_korean = {{
@@ -251,7 +239,6 @@ constexpr ApplicationLanguagePriorityList priority_list_korean = {{
ApplicationLanguage::Japanese,
ApplicationLanguage::SimplifiedChinese,
ApplicationLanguage::TraditionalChinese,
ApplicationLanguage::Czech,
}};
constexpr ApplicationLanguagePriorityList priority_list_traditional_chinese = {{
@@ -270,7 +257,6 @@ constexpr ApplicationLanguagePriorityList priority_list_traditional_chinese = {{
ApplicationLanguage::Portuguese,
ApplicationLanguage::Russian,
ApplicationLanguage::Korean,
ApplicationLanguage::Czech,
}};
constexpr ApplicationLanguagePriorityList priority_list_simplified_chinese = {{
@@ -289,28 +275,8 @@ constexpr ApplicationLanguagePriorityList priority_list_simplified_chinese = {{
ApplicationLanguage::Portuguese,
ApplicationLanguage::Russian,
ApplicationLanguage::Korean,
ApplicationLanguage::Czech,
}};
constexpr ApplicationLanguagePriorityList priority_list_czech = {{
ApplicationLanguage::Czech,
ApplicationLanguage::AmericanEnglish,
ApplicationLanguage::BritishEnglish,
ApplicationLanguage::LatinAmericanSpanish,
ApplicationLanguage::CanadianFrench,
ApplicationLanguage::French,
ApplicationLanguage::German,
ApplicationLanguage::Spanish,
ApplicationLanguage::Italian,
ApplicationLanguage::Dutch,
ApplicationLanguage::Portuguese,
ApplicationLanguage::Russian,
ApplicationLanguage::Japanese,
ApplicationLanguage::SimplifiedChinese,
ApplicationLanguage::TraditionalChinese,
ApplicationLanguage::Korean,
}};
const ApplicationLanguagePriorityList* GetApplicationLanguagePriorityList(
const ApplicationLanguage lang) {
switch (lang) {
@@ -344,8 +310,6 @@ const ApplicationLanguagePriorityList* GetApplicationLanguagePriorityList(
return &priority_list_traditional_chinese;
case ApplicationLanguage::SimplifiedChinese:
return &priority_list_simplified_chinese;
case ApplicationLanguage::Czech:
return &priority_list_czech;
default:
return nullptr;
}
@@ -384,8 +348,6 @@ std::optional<ApplicationLanguage> ConvertToApplicationLanguage(
return ApplicationLanguage::TraditionalChinese;
case Set::LanguageCode::ZH_HANS:
return ApplicationLanguage::SimplifiedChinese;
case Set::LanguageCode::CZ:
return ApplicationLanguage::Czech;
default:
return std::nullopt;
}
@@ -423,10 +385,8 @@ std::optional<Set::LanguageCode> ConvertToLanguageCode(const ApplicationLanguage
return Set::LanguageCode::ZH_HANT;
case ApplicationLanguage::SimplifiedChinese:
return Set::LanguageCode::ZH_HANS;
case ApplicationLanguage::Czech:
return Set::LanguageCode::CZ;
default:
return std::nullopt;
}
}
} // namespace Service::NS
} // namespace Service::NS

View File

@@ -30,7 +30,6 @@ enum class ApplicationLanguage : u8 {
Korean,
TraditionalChinese,
SimplifiedChinese,
Czech,
Count
};
using ApplicationLanguagePriorityList =
@@ -43,4 +42,4 @@ constexpr u32 GetSupportedLanguageFlag(const ApplicationLanguage lang) {
const ApplicationLanguagePriorityList* GetApplicationLanguagePriorityList(ApplicationLanguage lang);
std::optional<ApplicationLanguage> ConvertToApplicationLanguage(Set::LanguageCode language_code);
std::optional<Set::LanguageCode> ConvertToLanguageCode(ApplicationLanguage lang);
} // namespace Service::NS
} // namespace Service::NS

View File

@@ -26,7 +26,6 @@ enum class ApplicationLanguage : u8 {
Korean,
TraditionalChinese,
SimplifiedChinese,
Czech,
Count
};
using ApplicationLanguagePriorityList =
@@ -40,4 +39,4 @@ const ApplicationLanguagePriorityList* GetApplicationLanguagePriorityList(Applic
std::optional<ApplicationLanguage> ConvertToApplicationLanguage(
Service::Set::LanguageCode language_code);
std::optional<Service::Set::LanguageCode> ConvertToLanguageCode(ApplicationLanguage lang);
} // namespace Service::NS
} // namespace Service::NS

View File

@@ -3,11 +3,44 @@
// Refer to the license.txt file included.
#include "core/hle/ipc_helpers.h"
#include "core/hle/kernel/kernel.h"
#include "core/hle/kernel/process.h"
#include "core/hle/service/pm/pm.h"
#include "core/hle/service/service.h"
namespace Service::PM {
namespace {
constexpr ResultCode ERROR_PROCESS_NOT_FOUND{ErrorModule::PM, 1};
constexpr u64 NO_PROCESS_FOUND_PID{0};
std::optional<Kernel::SharedPtr<Kernel::Process>> SearchProcessList(
const std::vector<Kernel::SharedPtr<Kernel::Process>>& process_list,
std::function<bool(const Kernel::SharedPtr<Kernel::Process>&)> predicate) {
const auto iter = std::find_if(process_list.begin(), process_list.end(), predicate);
if (iter == process_list.end()) {
return std::nullopt;
}
return *iter;
}
void GetApplicationPidGeneric(Kernel::HLERequestContext& ctx,
const std::vector<Kernel::SharedPtr<Kernel::Process>>& process_list) {
const auto process = SearchProcessList(process_list, [](const auto& process) {
return process->GetProcessID() == Kernel::Process::ProcessIDMin;
});
IPC::ResponseBuilder rb{ctx, 4};
rb.Push(RESULT_SUCCESS);
rb.Push(process.has_value() ? (*process)->GetProcessID() : NO_PROCESS_FOUND_PID);
}
} // Anonymous namespace
class BootMode final : public ServiceFramework<BootMode> {
public:
explicit BootMode() : ServiceFramework{"pm:bm"} {
@@ -41,14 +74,15 @@ private:
class DebugMonitor final : public ServiceFramework<DebugMonitor> {
public:
explicit DebugMonitor() : ServiceFramework{"pm:dmnt"} {
explicit DebugMonitor(const Kernel::KernelCore& kernel)
: ServiceFramework{"pm:dmnt"}, kernel(kernel) {
// clang-format off
static const FunctionInfo functions[] = {
{0, nullptr, "GetDebugProcesses"},
{1, nullptr, "StartDebugProcess"},
{2, nullptr, "GetTitlePid"},
{2, &DebugMonitor::GetTitlePid, "GetTitlePid"},
{3, nullptr, "EnableDebugForTitleId"},
{4, nullptr, "GetApplicationPid"},
{4, &DebugMonitor::GetApplicationPid, "GetApplicationPid"},
{5, nullptr, "EnableDebugForApplication"},
{6, nullptr, "DisableDebug"},
};
@@ -56,21 +90,77 @@ public:
RegisterHandlers(functions);
}
private:
void GetTitlePid(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto title_id = rp.PopRaw<u64>();
LOG_DEBUG(Service_PM, "called, title_id={:016X}", title_id);
const auto process =
SearchProcessList(kernel.GetProcessList(), [title_id](const auto& process) {
return process->GetTitleID() == title_id;
});
if (!process.has_value()) {
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ERROR_PROCESS_NOT_FOUND);
return;
}
IPC::ResponseBuilder rb{ctx, 4};
rb.Push(RESULT_SUCCESS);
rb.Push((*process)->GetProcessID());
}
void GetApplicationPid(Kernel::HLERequestContext& ctx) {
LOG_DEBUG(Service_PM, "called");
GetApplicationPidGeneric(ctx, kernel.GetProcessList());
}
const Kernel::KernelCore& kernel;
};
class Info final : public ServiceFramework<Info> {
public:
explicit Info() : ServiceFramework{"pm:info"} {
explicit Info(const std::vector<Kernel::SharedPtr<Kernel::Process>>& process_list)
: ServiceFramework{"pm:info"}, process_list(process_list) {
static const FunctionInfo functions[] = {
{0, nullptr, "GetTitleId"},
{0, &Info::GetTitleId, "GetTitleId"},
};
RegisterHandlers(functions);
}
private:
void GetTitleId(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto process_id = rp.PopRaw<u64>();
LOG_DEBUG(Service_PM, "called, process_id={:016X}", process_id);
const auto process = SearchProcessList(process_list, [process_id](const auto& process) {
return process->GetProcessID() == process_id;
});
if (!process.has_value()) {
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ERROR_PROCESS_NOT_FOUND);
return;
}
IPC::ResponseBuilder rb{ctx, 4};
rb.Push(RESULT_SUCCESS);
rb.Push((*process)->GetTitleID());
}
const std::vector<Kernel::SharedPtr<Kernel::Process>>& process_list;
};
class Shell final : public ServiceFramework<Shell> {
public:
explicit Shell() : ServiceFramework{"pm:shell"} {
explicit Shell(const Kernel::KernelCore& kernel)
: ServiceFramework{"pm:shell"}, kernel(kernel) {
// clang-format off
static const FunctionInfo functions[] = {
{0, nullptr, "LaunchProcess"},
@@ -79,21 +169,31 @@ public:
{3, nullptr, "GetProcessEventWaiter"},
{4, nullptr, "GetProcessEventType"},
{5, nullptr, "NotifyBootFinished"},
{6, nullptr, "GetApplicationPid"},
{6, &Shell::GetApplicationPid, "GetApplicationPid"},
{7, nullptr, "BoostSystemMemoryResourceLimit"},
{8, nullptr, "EnableAdditionalSystemThreads"},
{9, nullptr, "GetUnimplementedEventHandle"},
};
// clang-format on
RegisterHandlers(functions);
}
private:
void GetApplicationPid(Kernel::HLERequestContext& ctx) {
LOG_DEBUG(Service_PM, "called");
GetApplicationPidGeneric(ctx, kernel.GetProcessList());
}
const Kernel::KernelCore& kernel;
};
void InstallInterfaces(SM::ServiceManager& sm) {
std::make_shared<BootMode>()->InstallAsService(sm);
std::make_shared<DebugMonitor>()->InstallAsService(sm);
std::make_shared<Info>()->InstallAsService(sm);
std::make_shared<Shell>()->InstallAsService(sm);
void InstallInterfaces(Core::System& system) {
std::make_shared<BootMode>()->InstallAsService(system.ServiceManager());
std::make_shared<DebugMonitor>(system.Kernel())->InstallAsService(system.ServiceManager());
std::make_shared<Info>(system.Kernel().GetProcessList())
->InstallAsService(system.ServiceManager());
std::make_shared<Shell>(system.Kernel())->InstallAsService(system.ServiceManager());
}
} // namespace Service::PM

View File

@@ -4,8 +4,8 @@
#pragma once
namespace Service::SM {
class ServiceManager;
namespace Core {
class System;
}
namespace Service::PM {
@@ -16,6 +16,6 @@ enum class SystemBootMode {
};
/// Registers all PM services with the specified service manager.
void InstallInterfaces(SM::ServiceManager& service_manager);
void InstallInterfaces(Core::System& system);
} // namespace Service::PM

View File

@@ -195,8 +195,7 @@ ResultCode ServiceFrameworkBase::HandleSyncRequest(Kernel::HLERequestContext& co
// Module interface
/// Initialize ServiceManager
void Init(std::shared_ptr<SM::ServiceManager>& sm, Core::System& system,
FileSys::VfsFilesystem& vfs) {
void Init(std::shared_ptr<SM::ServiceManager>& sm, Core::System& system) {
// NVFlinger needs to be accessed by several services like Vi and AppletOE so we instantiate it
// here and pass it into the respective InstallInterfaces functions.
auto nv_flinger = std::make_shared<NVFlinger::NVFlinger>(system.CoreTiming());
@@ -206,7 +205,7 @@ void Init(std::shared_ptr<SM::ServiceManager>& sm, Core::System& system,
Account::InstallInterfaces(system);
AM::InstallInterfaces(*sm, nv_flinger, system);
AOC::InstallInterfaces(*sm);
APM::InstallInterfaces(*sm);
APM::InstallInterfaces(system);
Audio::InstallInterfaces(*sm);
BCAT::InstallInterfaces(*sm);
BPC::InstallInterfaces(*sm);
@@ -218,7 +217,7 @@ void Init(std::shared_ptr<SM::ServiceManager>& sm, Core::System& system,
EUPLD::InstallInterfaces(*sm);
Fatal::InstallInterfaces(*sm);
FGM::InstallInterfaces(*sm);
FileSystem::InstallInterfaces(*sm, vfs);
FileSystem::InstallInterfaces(system);
Friend::InstallInterfaces(*sm);
Glue::InstallInterfaces(system);
GRC::InstallInterfaces(*sm);
@@ -242,7 +241,7 @@ void Init(std::shared_ptr<SM::ServiceManager>& sm, Core::System& system,
PCTL::InstallInterfaces(*sm);
PCV::InstallInterfaces(*sm);
PlayReport::InstallInterfaces(*sm);
PM::InstallInterfaces(*sm);
PM::InstallInterfaces(system);
PSC::InstallInterfaces(*sm);
PSM::InstallInterfaces(*sm);
Set::InstallInterfaces(*sm);

View File

@@ -182,8 +182,7 @@ private:
};
/// Initialize ServiceManager
void Init(std::shared_ptr<SM::ServiceManager>& sm, Core::System& system,
FileSys::VfsFilesystem& vfs);
void Init(std::shared_ptr<SM::ServiceManager>& sm, Core::System& system);
/// Shutdown ServiceManager
void Shutdown();

View File

@@ -29,7 +29,6 @@ constexpr std::array<LanguageCode, 17> available_language_codes = {{
LanguageCode::ES_419,
LanguageCode::ZH_HANS,
LanguageCode::ZH_HANT,
LanguageCode::CZ,
}};
constexpr std::size_t pre4_0_0_max_entries = 15;

View File

@@ -27,7 +27,6 @@ enum class LanguageCode : u64 {
ES_419 = 0x00003931342D7365,
ZH_HANS = 0x00736E61482D687A,
ZH_HANT = 0x00746E61482D687A,
CZ = 0x0000000000007a63,
};
LanguageCode GetLanguageCodeFromIndex(std::size_t idx);

View File

@@ -350,6 +350,24 @@ void Reporter::SaveErrorReport(u64 title_id, ResultCode result,
SaveToFile(std::move(out), GetPath("error_report", title_id, timestamp));
}
void Reporter::SaveFilesystemAccessReport(Service::FileSystem::LogMode log_mode,
std::string log_message) const {
if (!IsReportingEnabled())
return;
const auto timestamp = GetTimestamp();
const auto title_id = system.CurrentProcess()->GetTitleID();
json out;
out["yuzu_version"] = GetYuzuVersionData();
out["report_common"] = GetReportCommonData(title_id, RESULT_SUCCESS, timestamp);
out["log_mode"] = fmt::format("{:08X}", static_cast<u32>(log_mode));
out["log_message"] = std::move(log_message);
SaveToFile(std::move(out), GetPath("filesystem_access_report", title_id, timestamp));
}
void Reporter::SaveUserReport() const {
if (!IsReportingEnabled()) {
return;

View File

@@ -16,6 +16,10 @@ namespace Kernel {
class HLERequestContext;
} // namespace Kernel
namespace Service::FileSystem {
enum class LogMode : u32;
}
namespace Core {
class System;
@@ -49,6 +53,9 @@ public:
std::optional<std::string> custom_text_main = {},
std::optional<std::string> custom_text_detail = {}) const;
void SaveFilesystemAccessReport(Service::FileSystem::LogMode log_mode,
std::string log_message) const;
void SaveUserReport() const;
private:

View File

@@ -98,17 +98,19 @@ private:
/**
* Configures the color and depth framebuffer states.
* @param must_reconfigure If true, tells the framebuffer to skip the cache and reconfigure
* again. Used by the texture cache to solve texception conflicts
* @param use_color_fb If true, configure color framebuffers.
* @param using_depth_fb If true, configure the depth/stencil framebuffer.
* @param preserve_contents If true, tries to preserve data from a previously used framebuffer.
*
* @param current_state The current OpenGL state.
* @param using_color_fb If true, configure color framebuffers.
* @param using_depth_fb If true, configure the depth/stencil framebuffer.
* @param preserve_contents If true, tries to preserve data from a previously used
* framebuffer.
* @param single_color_target Specifies if a single color buffer target should be used.
*
* @returns If depth (first) or stencil (second) are being stored in the bound zeta texture
* (requires using_depth_fb to be true)
* (requires using_depth_fb to be true)
*/
std::pair<bool, bool> ConfigureFramebuffers(
OpenGLState& current_state, bool use_color_fb = true, bool using_depth_fb = true,
OpenGLState& current_state, bool using_color_fb = true, bool using_depth_fb = true,
bool preserve_contents = true, std::optional<std::size_t> single_color_target = {});
/// Configures the current constbuffers to use for the draw command.

View File

@@ -17,9 +17,9 @@ public:
~SamplerCacheOpenGL();
protected:
OGLSampler CreateSampler(const Tegra::Texture::TSCEntry& tsc) const;
OGLSampler CreateSampler(const Tegra::Texture::TSCEntry& tsc) const override;
GLuint ToSamplerType(const OGLSampler& sampler) const;
GLuint ToSamplerType(const OGLSampler& sampler) const override;
};
} // namespace OpenGL

View File

@@ -109,8 +109,8 @@ void VKBufferCache::Reserve(std::size_t max_size) {
}
}
VKExecutionContext VKBufferCache::Send(VKExecutionContext exctx) {
return stream_buffer->Send(exctx, buffer_offset - buffer_offset_base);
void VKBufferCache::Send() {
stream_buffer->Send(buffer_offset - buffer_offset_base);
}
void VKBufferCache::AlignBuffer(std::size_t alignment) {

View File

@@ -77,7 +77,7 @@ public:
void Reserve(std::size_t max_size);
/// Ensures that the set data is sent to the device.
[[nodiscard]] VKExecutionContext Send(VKExecutionContext exctx);
void Send();
/// Returns the buffer cache handle.
vk::Buffer GetBuffer() const {

View File

@@ -4,9 +4,6 @@
#pragma once
#include <unordered_map>
#include "common/common_types.h"
#include "video_core/renderer_vulkan/declarations.h"
#include "video_core/sampler_cache.h"
#include "video_core/textures/texture.h"
@@ -21,9 +18,9 @@ public:
~VKSamplerCache();
protected:
UniqueSampler CreateSampler(const Tegra::Texture::TSCEntry& tsc) const;
UniqueSampler CreateSampler(const Tegra::Texture::TSCEntry& tsc) const override;
vk::Sampler ToSamplerType(const UniqueSampler& sampler) const;
vk::Sampler ToSamplerType(const UniqueSampler& sampler) const override;
private:
const VKDevice& device;

View File

@@ -19,23 +19,19 @@ VKScheduler::VKScheduler(const VKDevice& device, VKResourceManager& resource_man
VKScheduler::~VKScheduler() = default;
VKExecutionContext VKScheduler::GetExecutionContext() const {
return VKExecutionContext(current_fence, current_cmdbuf);
}
VKExecutionContext VKScheduler::Flush(vk::Semaphore semaphore) {
void VKScheduler::Flush(bool release_fence, vk::Semaphore semaphore) {
SubmitExecution(semaphore);
current_fence->Release();
if (release_fence)
current_fence->Release();
AllocateNewContext();
return GetExecutionContext();
}
VKExecutionContext VKScheduler::Finish(vk::Semaphore semaphore) {
void VKScheduler::Finish(bool release_fence, vk::Semaphore semaphore) {
SubmitExecution(semaphore);
current_fence->Wait();
current_fence->Release();
if (release_fence)
current_fence->Release();
AllocateNewContext();
return GetExecutionContext();
}
void VKScheduler::SubmitExecution(vk::Semaphore semaphore) {

View File

@@ -10,10 +10,43 @@
namespace Vulkan {
class VKDevice;
class VKExecutionContext;
class VKFence;
class VKResourceManager;
class VKFenceView {
public:
VKFenceView() = default;
VKFenceView(VKFence* const& fence) : fence{fence} {}
VKFence* operator->() const noexcept {
return fence;
}
operator VKFence&() const noexcept {
return *fence;
}
private:
VKFence* const& fence;
};
class VKCommandBufferView {
public:
VKCommandBufferView() = default;
VKCommandBufferView(const vk::CommandBuffer& cmdbuf) : cmdbuf{cmdbuf} {}
const vk::CommandBuffer* operator->() const noexcept {
return &cmdbuf;
}
operator vk::CommandBuffer() const noexcept {
return cmdbuf;
}
private:
const vk::CommandBuffer& cmdbuf;
};
/// The scheduler abstracts command buffer and fence management with an interface that's able to do
/// OpenGL-like operations on Vulkan command buffers.
class VKScheduler {
@@ -21,16 +54,21 @@ public:
explicit VKScheduler(const VKDevice& device, VKResourceManager& resource_manager);
~VKScheduler();
/// Gets the current execution context.
[[nodiscard]] VKExecutionContext GetExecutionContext() const;
/// Gets a reference to the current fence.
VKFenceView GetFence() const {
return current_fence;
}
/// Sends the current execution context to the GPU. It invalidates the current execution context
/// and returns a new one.
VKExecutionContext Flush(vk::Semaphore semaphore = nullptr);
/// Gets a reference to the current command buffer.
VKCommandBufferView GetCommandBuffer() const {
return current_cmdbuf;
}
/// Sends the current execution context to the GPU and waits for it to complete. It invalidates
/// the current execution context and returns a new one.
VKExecutionContext Finish(vk::Semaphore semaphore = nullptr);
/// Sends the current execution context to the GPU.
void Flush(bool release_fence = true, vk::Semaphore semaphore = nullptr);
/// Sends the current execution context to the GPU and waits for it to complete.
void Finish(bool release_fence = true, vk::Semaphore semaphore = nullptr);
private:
void SubmitExecution(vk::Semaphore semaphore);
@@ -44,26 +82,4 @@ private:
VKFence* next_fence = nullptr;
};
class VKExecutionContext {
friend class VKScheduler;
public:
VKExecutionContext() = default;
VKFence& GetFence() const {
return *fence;
}
vk::CommandBuffer GetCommandBuffer() const {
return cmdbuf;
}
private:
explicit VKExecutionContext(VKFence* fence, vk::CommandBuffer cmdbuf)
: fence{fence}, cmdbuf{cmdbuf} {}
VKFence* fence{};
vk::CommandBuffer cmdbuf;
};
} // namespace Vulkan

View File

@@ -46,12 +46,12 @@ std::tuple<u8*, u64, bool> VKStreamBuffer::Reserve(u64 size) {
return {mapped_pointer + offset, offset, invalidation_mark.has_value()};
}
VKExecutionContext VKStreamBuffer::Send(VKExecutionContext exctx, u64 size) {
void VKStreamBuffer::Send(u64 size) {
ASSERT_MSG(size <= mapped_size, "Reserved size is too small");
if (invalidation_mark) {
// TODO(Rodrigo): Find a better way to invalidate than waiting for all watches to finish.
exctx = scheduler.Flush();
scheduler.Flush();
std::for_each(watches.begin(), watches.begin() + *invalidation_mark,
[&](auto& resource) { resource->Wait(); });
invalidation_mark = std::nullopt;
@@ -62,11 +62,9 @@ VKExecutionContext VKStreamBuffer::Send(VKExecutionContext exctx, u64 size) {
ReserveWatches(WATCHES_RESERVE_CHUNK);
}
// Add a watch for this allocation.
watches[used_watches++]->Watch(exctx.GetFence());
watches[used_watches++]->Watch(scheduler.GetFence());
offset += size;
return exctx;
}
void VKStreamBuffer::CreateBuffers(VKMemoryManager& memory_manager, vk::BufferUsageFlags usage) {

View File

@@ -37,7 +37,7 @@ public:
std::tuple<u8*, u64, bool> Reserve(u64 size);
/// Ensures that "size" bytes of memory are available to the GPU, potentially recording a copy.
[[nodiscard]] VKExecutionContext Send(VKExecutionContext exctx, u64 size);
void Send(u64 size);
vk::Buffer GetBuffer() const {
return *buffer;

View File

@@ -126,11 +126,6 @@
<string>Traditional Chinese (正體中文)</string>
</property>
</item>
<item>
<property name="text">
<string>Czech (Čeština)</string>
</property>
</item>
</widget>
</item>
<item row="4" column="0">

View File

@@ -204,7 +204,7 @@ username = yuzu
# Sets the systems language index
# 0: Japanese, 1: English (default), 2: French, 3: German, 4: Italian, 5: Spanish, 6: Chinese,
# 7: Korean, 8: Dutch, 9: Portuguese, 10: Russian, 11: Taiwanese, 12: British English, 13: Canadian French,
# 14: Latin American Spanish, 15: Simplified Chinese, 16: Traditional Chinese, 17: Czech
# 14: Latin American Spanish, 15: Simplified Chinese, 16: Traditional Chinese
language_index =
# The system region that yuzu will use during emulation

View File

@@ -109,7 +109,7 @@ username = yuzu
# Sets the systems language index
# 0: Japanese, 1: English (default), 2: French, 3: German, 4: Italian, 5: Spanish, 6: Chinese,
# 7: Korean, 8: Dutch, 9: Portuguese, 10: Russian, 11: Taiwanese, 12: British English, 13: Canadian French,
# 14: Latin American Spanish, 15: Simplified Chinese, 16: Traditional Chinese, 17: Czech
# 14: Latin American Spanish, 15: Simplified Chinese, 16: Traditional Chinese
language_index =
# The system region that yuzu will use during emulation