summaryrefslogtreecommitdiffstats
path: root/src/core
diff options
context:
space:
mode:
Diffstat (limited to 'src/core')
-rw-r--r--src/core/core.cpp29
-rw-r--r--src/core/hle/service/am/am.cpp5
-rw-r--r--src/core/hle/service/apm/controller.cpp50
-rw-r--r--src/core/hle/service/apm/controller.h2
-rw-r--r--src/core/hle/service/bcat/backend/backend.cpp4
-rw-r--r--src/core/hle/service/bcat/backend/backend.h12
-rw-r--r--src/core/hle/service/bcat/backend/boxcat.cpp29
-rw-r--r--src/core/hle/service/bcat/backend/boxcat.h10
-rw-r--r--src/core/hle/service/bcat/module.cpp24
-rw-r--r--src/core/hle/service/hid/controllers/npad.cpp64
-rw-r--r--src/core/hle/service/hid/controllers/npad.h10
-rw-r--r--src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp4
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp33
-rw-r--r--src/core/hle/service/nvdrv/interface.cpp4
-rw-r--r--src/core/hle/service/nvdrv/nvdrv.cpp4
-rw-r--r--src/core/hle/service/nvflinger/buffer_queue.cpp4
-rw-r--r--src/core/hle/service/nvflinger/buffer_queue.h6
-rw-r--r--src/core/hle/service/nvflinger/nvflinger.cpp12
-rw-r--r--src/core/memory/cheat_engine.cpp7
-rw-r--r--src/core/memory/dmnt_cheat_vm.cpp4
20 files changed, 171 insertions, 146 deletions
diff --git a/src/core/core.cpp b/src/core/core.cpp
index d79045eea..eba17218a 100644
--- a/src/core/core.cpp
+++ b/src/core/core.cpp
@@ -112,8 +112,8 @@ FileSys::VirtualFile GetGameFileFromPath(const FileSys::VirtualFilesystem& vfs,
}
struct System::Impl {
explicit Impl(System& system)
- : kernel{system}, fs_controller{system}, cpu_core_manager{system},
- applet_manager{system}, reporter{system} {}
+ : kernel{system}, fs_controller{system}, cpu_core_manager{system}, reporter{system},
+ applet_manager{system} {}
Cpu& CurrentCpuCore() {
return cpu_core_manager.GetCurrentCore();
@@ -240,22 +240,27 @@ struct System::Impl {
}
void Shutdown() {
- // Log last frame performance stats
- const auto perf_results = GetAndResetPerfStats();
- telemetry_session->AddField(Telemetry::FieldType::Performance, "Shutdown_EmulationSpeed",
- perf_results.emulation_speed * 100.0);
- telemetry_session->AddField(Telemetry::FieldType::Performance, "Shutdown_Framerate",
- perf_results.game_fps);
- telemetry_session->AddField(Telemetry::FieldType::Performance, "Shutdown_Frametime",
- perf_results.frametime * 1000.0);
- telemetry_session->AddField(Telemetry::FieldType::Performance, "Mean_Frametime_MS",
- perf_stats->GetMeanFrametime());
+ // Log last frame performance stats if game was loded
+ if (perf_stats) {
+ const auto perf_results = GetAndResetPerfStats();
+ telemetry_session->AddField(Telemetry::FieldType::Performance,
+ "Shutdown_EmulationSpeed",
+ perf_results.emulation_speed * 100.0);
+ telemetry_session->AddField(Telemetry::FieldType::Performance, "Shutdown_Framerate",
+ perf_results.game_fps);
+ telemetry_session->AddField(Telemetry::FieldType::Performance, "Shutdown_Frametime",
+ perf_results.frametime * 1000.0);
+ telemetry_session->AddField(Telemetry::FieldType::Performance, "Mean_Frametime_MS",
+ perf_stats->GetMeanFrametime());
+ }
lm_manager.Flush();
is_powered_on = false;
exit_lock = false;
+ gpu_core->WaitIdle();
+
// Shutdown emulation session
renderer.reset();
GDBStub::Shutdown();
diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp
index 941ebc93a..3a32d5b41 100644
--- a/src/core/hle/service/am/am.cpp
+++ b/src/core/hle/service/am/am.cpp
@@ -1140,8 +1140,9 @@ void IApplicationFunctions::PopLaunchParameter(Kernel::HLERequestContext& ctx) {
LOG_DEBUG(Service_AM, "called, kind={:08X}", static_cast<u8>(kind));
if (kind == LaunchParameterKind::ApplicationSpecific && !launch_popped_application_specific) {
- const auto backend = BCAT::CreateBackendFromSettings(
- [this](u64 tid) { return system.GetFileSystemController().GetBCATDirectory(tid); });
+ const auto backend = BCAT::CreateBackendFromSettings(system, [this](u64 tid) {
+ return system.GetFileSystemController().GetBCATDirectory(tid);
+ });
const auto build_id_full = system.GetCurrentProcessBuildID();
u64 build_id{};
std::memcpy(&build_id, build_id_full.data(), sizeof(u64));
diff --git a/src/core/hle/service/apm/controller.cpp b/src/core/hle/service/apm/controller.cpp
index 073d0f6fa..25a886238 100644
--- a/src/core/hle/service/apm/controller.cpp
+++ b/src/core/hle/service/apm/controller.cpp
@@ -2,6 +2,10 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
+#include <algorithm>
+#include <array>
+#include <utility>
+
#include "common/logging/log.h"
#include "core/core_timing.h"
#include "core/hle/service/apm/controller.h"
@@ -9,8 +13,7 @@
namespace Service::APM {
-constexpr PerformanceConfiguration DEFAULT_PERFORMANCE_CONFIGURATION =
- PerformanceConfiguration::Config7;
+constexpr auto DEFAULT_PERFORMANCE_CONFIGURATION = PerformanceConfiguration::Config7;
Controller::Controller(Core::Timing::CoreTiming& core_timing)
: core_timing{core_timing}, configs{
@@ -22,18 +25,35 @@ 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);
+ static constexpr std::array<std::pair<PerformanceConfiguration, u32>, 16> config_to_speed{{
+ {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},
+ }};
+
+ const auto iter = std::find_if(config_to_speed.cbegin(), config_to_speed.cend(),
+ [config](const auto& entry) { return entry.first == config; });
+
+ if (iter == config_to_speed.cend()) {
+ LOG_ERROR(Service_APM, "Invalid performance configuration value provided: {}",
+ static_cast<u32>(config));
+ return;
+ }
+
+ SetClockSpeed(iter->second);
configs.insert_or_assign(mode, config);
}
@@ -48,7 +68,7 @@ void Controller::SetFromCpuBoostMode(CpuBoostMode mode) {
BOOST_MODE_TO_CONFIG_MAP.at(static_cast<u32>(mode)));
}
-PerformanceMode Controller::GetCurrentPerformanceMode() {
+PerformanceMode Controller::GetCurrentPerformanceMode() const {
return Settings::values.use_docked_mode ? PerformanceMode::Docked : PerformanceMode::Handheld;
}
diff --git a/src/core/hle/service/apm/controller.h b/src/core/hle/service/apm/controller.h
index 454caa6eb..af0c4cd34 100644
--- a/src/core/hle/service/apm/controller.h
+++ b/src/core/hle/service/apm/controller.h
@@ -56,7 +56,7 @@ public:
void SetPerformanceConfiguration(PerformanceMode mode, PerformanceConfiguration config);
void SetFromCpuBoostMode(CpuBoostMode mode);
- PerformanceMode GetCurrentPerformanceMode();
+ PerformanceMode GetCurrentPerformanceMode() const;
PerformanceConfiguration GetCurrentPerformanceConfiguration(PerformanceMode mode);
private:
diff --git a/src/core/hle/service/bcat/backend/backend.cpp b/src/core/hle/service/bcat/backend/backend.cpp
index 9d6946bc5..b86fda29a 100644
--- a/src/core/hle/service/bcat/backend/backend.cpp
+++ b/src/core/hle/service/bcat/backend/backend.cpp
@@ -10,8 +10,8 @@
namespace Service::BCAT {
-ProgressServiceBackend::ProgressServiceBackend(std::string_view event_name) {
- auto& kernel{Core::System::GetInstance().Kernel()};
+ProgressServiceBackend::ProgressServiceBackend(Kernel::KernelCore& kernel,
+ std::string_view event_name) {
event = Kernel::WritableEvent::CreateEventPair(
kernel, Kernel::ResetType::Automatic,
std::string("ProgressServiceBackend:UpdateEvent:").append(event_name));
diff --git a/src/core/hle/service/bcat/backend/backend.h b/src/core/hle/service/bcat/backend/backend.h
index 51dbd3316..ea4b16ad0 100644
--- a/src/core/hle/service/bcat/backend/backend.h
+++ b/src/core/hle/service/bcat/backend/backend.h
@@ -15,6 +15,14 @@
#include "core/hle/kernel/writable_event.h"
#include "core/hle/result.h"
+namespace Core {
+class System;
+}
+
+namespace Kernel {
+class KernelCore;
+}
+
namespace Service::BCAT {
struct DeliveryCacheProgressImpl;
@@ -88,7 +96,7 @@ public:
void FinishDownload(ResultCode result);
private:
- explicit ProgressServiceBackend(std::string_view event_name);
+ explicit ProgressServiceBackend(Kernel::KernelCore& kernel, std::string_view event_name);
Kernel::SharedPtr<Kernel::ReadableEvent> GetEvent() const;
DeliveryCacheProgressImpl& GetImpl();
@@ -145,6 +153,6 @@ public:
std::optional<std::vector<u8>> GetLaunchParameter(TitleIDVersion title) override;
};
-std::unique_ptr<Backend> CreateBackendFromSettings(DirectoryGetter getter);
+std::unique_ptr<Backend> CreateBackendFromSettings(Core::System& system, DirectoryGetter getter);
} // namespace Service::BCAT
diff --git a/src/core/hle/service/bcat/backend/boxcat.cpp b/src/core/hle/service/bcat/backend/boxcat.cpp
index 64022982b..918159e11 100644
--- a/src/core/hle/service/bcat/backend/boxcat.cpp
+++ b/src/core/hle/service/bcat/backend/boxcat.cpp
@@ -104,14 +104,15 @@ std::string GetZIPFilePath(u64 title_id) {
// If the error is something the user should know about (build ID mismatch, bad client version),
// display an error.
-void HandleDownloadDisplayResult(DownloadResult res) {
+void HandleDownloadDisplayResult(const AM::Applets::AppletManager& applet_manager,
+ DownloadResult res) {
if (res == DownloadResult::Success || res == DownloadResult::NoResponse ||
res == DownloadResult::GeneralWebError || res == DownloadResult::GeneralFSError ||
res == DownloadResult::NoMatchTitleId || res == DownloadResult::InvalidContentType) {
return;
}
- const auto& frontend{Core::System::GetInstance().GetAppletManager().GetAppletFrontendSet()};
+ const auto& frontend{applet_manager.GetAppletFrontendSet()};
frontend.error->ShowCustomErrorText(
ResultCode(-1), "There was an error while attempting to use Boxcat.",
DOWNLOAD_RESULT_LOG_MESSAGES[static_cast<std::size_t>(res)], [] {});
@@ -264,12 +265,13 @@ private:
u64 build_id;
};
-Boxcat::Boxcat(DirectoryGetter getter) : Backend(std::move(getter)) {}
+Boxcat::Boxcat(AM::Applets::AppletManager& applet_manager_, DirectoryGetter getter)
+ : Backend(std::move(getter)), applet_manager{applet_manager_} {}
Boxcat::~Boxcat() = default;
-void SynchronizeInternal(DirectoryGetter dir_getter, TitleIDVersion title,
- ProgressServiceBackend& progress,
+void SynchronizeInternal(AM::Applets::AppletManager& applet_manager, DirectoryGetter dir_getter,
+ TitleIDVersion title, ProgressServiceBackend& progress,
std::optional<std::string> dir_name = {}) {
progress.SetNeedHLELock(true);
@@ -295,7 +297,7 @@ void SynchronizeInternal(DirectoryGetter dir_getter, TitleIDVersion title,
FileUtil::Delete(zip_path);
}
- HandleDownloadDisplayResult(res);
+ HandleDownloadDisplayResult(applet_manager, res);
progress.FinishDownload(ERROR_GENERAL_BCAT_FAILURE);
return;
}
@@ -364,17 +366,24 @@ void SynchronizeInternal(DirectoryGetter dir_getter, TitleIDVersion title,
bool Boxcat::Synchronize(TitleIDVersion title, ProgressServiceBackend& progress) {
is_syncing.exchange(true);
- std::thread([this, title, &progress] { SynchronizeInternal(dir_getter, title, progress); })
+
+ std::thread([this, title, &progress] {
+ SynchronizeInternal(applet_manager, dir_getter, title, progress);
+ })
.detach();
+
return true;
}
bool Boxcat::SynchronizeDirectory(TitleIDVersion title, std::string name,
ProgressServiceBackend& progress) {
is_syncing.exchange(true);
- std::thread(
- [this, title, name, &progress] { SynchronizeInternal(dir_getter, title, progress, name); })
+
+ std::thread([this, title, name, &progress] {
+ SynchronizeInternal(applet_manager, dir_getter, title, progress, name);
+ })
.detach();
+
return true;
}
@@ -420,7 +429,7 @@ std::optional<std::vector<u8>> Boxcat::GetLaunchParameter(TitleIDVersion title)
FileUtil::Delete(path);
}
- HandleDownloadDisplayResult(res);
+ HandleDownloadDisplayResult(applet_manager, res);
return std::nullopt;
}
}
diff --git a/src/core/hle/service/bcat/backend/boxcat.h b/src/core/hle/service/bcat/backend/boxcat.h
index 601151189..d65b42e58 100644
--- a/src/core/hle/service/bcat/backend/boxcat.h
+++ b/src/core/hle/service/bcat/backend/boxcat.h
@@ -9,6 +9,10 @@
#include <optional>
#include "core/hle/service/bcat/backend/backend.h"
+namespace Service::AM::Applets {
+class AppletManager;
+}
+
namespace Service::BCAT {
struct EventStatus {
@@ -20,12 +24,13 @@ struct EventStatus {
/// Boxcat is yuzu's custom backend implementation of Nintendo's BCAT service. It is free to use and
/// doesn't require a switch or nintendo account. The content is controlled by the yuzu team.
class Boxcat final : public Backend {
- friend void SynchronizeInternal(DirectoryGetter dir_getter, TitleIDVersion title,
+ friend void SynchronizeInternal(AM::Applets::AppletManager& applet_manager,
+ DirectoryGetter dir_getter, TitleIDVersion title,
ProgressServiceBackend& progress,
std::optional<std::string> dir_name);
public:
- explicit Boxcat(DirectoryGetter getter);
+ explicit Boxcat(AM::Applets::AppletManager& applet_manager_, DirectoryGetter getter);
~Boxcat() override;
bool Synchronize(TitleIDVersion title, ProgressServiceBackend& progress) override;
@@ -53,6 +58,7 @@ private:
class Client;
std::unique_ptr<Client> client;
+ AM::Applets::AppletManager& applet_manager;
};
} // namespace Service::BCAT
diff --git a/src/core/hle/service/bcat/module.cpp b/src/core/hle/service/bcat/module.cpp
index 4e4aa758b..6d9d1527d 100644
--- a/src/core/hle/service/bcat/module.cpp
+++ b/src/core/hle/service/bcat/module.cpp
@@ -125,7 +125,11 @@ private:
class IBcatService final : public ServiceFramework<IBcatService> {
public:
explicit IBcatService(Core::System& system_, Backend& backend_)
- : ServiceFramework("IBcatService"), system{system_}, backend{backend_} {
+ : ServiceFramework("IBcatService"), system{system_}, backend{backend_},
+ progress{{
+ ProgressServiceBackend{system_.Kernel(), "Normal"},
+ ProgressServiceBackend{system_.Kernel(), "Directory"},
+ }} {
// clang-format off
static const FunctionInfo functions[] = {
{10100, &IBcatService::RequestSyncDeliveryCache, "RequestSyncDeliveryCache"},
@@ -249,10 +253,7 @@ private:
Core::System& system;
Backend& backend;
- std::array<ProgressServiceBackend, static_cast<std::size_t>(SyncType::Count)> progress{
- ProgressServiceBackend{"Normal"},
- ProgressServiceBackend{"Directory"},
- };
+ std::array<ProgressServiceBackend, static_cast<std::size_t>(SyncType::Count)> progress;
};
void Module::Interface::CreateBcatService(Kernel::HLERequestContext& ctx) {
@@ -557,12 +558,12 @@ void Module::Interface::CreateDeliveryCacheStorageServiceWithApplicationId(
rb.PushIpcInterface<IDeliveryCacheStorageService>(fsc.GetBCATDirectory(title_id));
}
-std::unique_ptr<Backend> CreateBackendFromSettings(DirectoryGetter getter) {
- const auto backend = Settings::values.bcat_backend;
-
+std::unique_ptr<Backend> CreateBackendFromSettings([[maybe_unused]] Core::System& system,
+ DirectoryGetter getter) {
#ifdef YUZU_ENABLE_BOXCAT
- if (backend == "boxcat")
- return std::make_unique<Boxcat>(std::move(getter));
+ if (Settings::values.bcat_backend == "boxcat") {
+ return std::make_unique<Boxcat>(system.GetAppletManager(), std::move(getter));
+ }
#endif
return std::make_unique<NullBackend>(std::move(getter));
@@ -571,7 +572,8 @@ std::unique_ptr<Backend> CreateBackendFromSettings(DirectoryGetter getter) {
Module::Interface::Interface(Core::System& system_, std::shared_ptr<Module> module_,
FileSystem::FileSystemController& fsc_, const char* name)
: ServiceFramework(name), fsc{fsc_}, module{std::move(module_)},
- backend{CreateBackendFromSettings([&fsc_](u64 tid) { return fsc_.GetBCATDirectory(tid); })},
+ backend{CreateBackendFromSettings(system_,
+ [&fsc_](u64 tid) { return fsc_.GetBCATDirectory(tid); })},
system{system_} {}
Module::Interface::~Interface() = default;
diff --git a/src/core/hle/service/hid/controllers/npad.cpp b/src/core/hle/service/hid/controllers/npad.cpp
index a2b25a796..81bd2f3cb 100644
--- a/src/core/hle/service/hid/controllers/npad.cpp
+++ b/src/core/hle/service/hid/controllers/npad.cpp
@@ -583,36 +583,6 @@ bool Controller_NPad::SwapNpadAssignment(u32 npad_id_1, u32 npad_id_2) {
return true;
}
-bool Controller_NPad::IsControllerSupported(NPadControllerType controller) {
- if (controller == NPadControllerType::Handheld) {
- // Handheld is not even a supported type, lets stop here
- if (std::find(supported_npad_id_types.begin(), supported_npad_id_types.end(),
- NPAD_HANDHELD) == supported_npad_id_types.end()) {
- return false;
- }
- // Handheld should not be supported in docked mode
- if (Settings::values.use_docked_mode) {
- return false;
- }
- }
- switch (controller) {
- case NPadControllerType::ProController:
- return style.pro_controller;
- case NPadControllerType::Handheld:
- return style.handheld;
- case NPadControllerType::JoyDual:
- return style.joycon_dual;
- case NPadControllerType::JoyLeft:
- return style.joycon_left;
- case NPadControllerType::JoyRight:
- return style.joycon_right;
- case NPadControllerType::Pokeball:
- return style.pokeball;
- default:
- return false;
- }
-}
-
Controller_NPad::LedPattern Controller_NPad::GetLedPattern(u32 npad_id) {
if (npad_id == npad_id_list.back() || npad_id == npad_id_list[npad_id_list.size() - 2]) {
// These are controllers without led patterns
@@ -659,25 +629,24 @@ void Controller_NPad::ClearAllConnectedControllers() {
}
void Controller_NPad::DisconnectAllConnectedControllers() {
- std::for_each(connected_controllers.begin(), connected_controllers.end(),
- [](ControllerHolder& controller) { controller.is_connected = false; });
+ for (ControllerHolder& controller : connected_controllers) {
+ controller.is_connected = false;
+ }
}
void Controller_NPad::ConnectAllDisconnectedControllers() {
- std::for_each(connected_controllers.begin(), connected_controllers.end(),
- [](ControllerHolder& controller) {
- if (controller.type != NPadControllerType::None && !controller.is_connected) {
- controller.is_connected = false;
- }
- });
+ for (ControllerHolder& controller : connected_controllers) {
+ if (controller.type != NPadControllerType::None && !controller.is_connected) {
+ controller.is_connected = true;
+ }
+ }
}
void Controller_NPad::ClearAllControllers() {
- std::for_each(connected_controllers.begin(), connected_controllers.end(),
- [](ControllerHolder& controller) {
- controller.type = NPadControllerType::None;
- controller.is_connected = false;
- });
+ for (ControllerHolder& controller : connected_controllers) {
+ controller.type = NPadControllerType::None;
+ controller.is_connected = false;
+ }
}
u32 Controller_NPad::GetAndResetPressState() {
@@ -685,10 +654,10 @@ u32 Controller_NPad::GetAndResetPressState() {
}
bool Controller_NPad::IsControllerSupported(NPadControllerType controller) const {
- const bool support_handheld =
- std::find(supported_npad_id_types.begin(), supported_npad_id_types.end(), NPAD_HANDHELD) !=
- supported_npad_id_types.end();
if (controller == NPadControllerType::Handheld) {
+ const bool support_handheld =
+ std::find(supported_npad_id_types.begin(), supported_npad_id_types.end(),
+ NPAD_HANDHELD) != supported_npad_id_types.end();
// Handheld is not even a supported type, lets stop here
if (!support_handheld) {
return false;
@@ -700,6 +669,7 @@ bool Controller_NPad::IsControllerSupported(NPadControllerType controller) const
return true;
}
+
if (std::any_of(supported_npad_id_types.begin(), supported_npad_id_types.end(),
[](u32 npad_id) { return npad_id <= MAX_NPAD_ID; })) {
switch (controller) {
@@ -717,6 +687,7 @@ bool Controller_NPad::IsControllerSupported(NPadControllerType controller) const
return false;
}
}
+
return false;
}
@@ -795,6 +766,7 @@ Controller_NPad::NPadControllerType Controller_NPad::DecideBestController(
priority_list.push_back(NPadControllerType::JoyLeft);
priority_list.push_back(NPadControllerType::JoyRight);
priority_list.push_back(NPadControllerType::JoyDual);
+ break;
}
const auto iter = std::find_if(priority_list.begin(), priority_list.end(),
diff --git a/src/core/hle/service/hid/controllers/npad.h b/src/core/hle/service/hid/controllers/npad.h
index 1bc3d55d6..16c4caa1f 100644
--- a/src/core/hle/service/hid/controllers/npad.h
+++ b/src/core/hle/service/hid/controllers/npad.h
@@ -301,6 +301,11 @@ private:
bool is_connected;
};
+ void InitNewlyAddedControler(std::size_t controller_idx);
+ bool IsControllerSupported(NPadControllerType controller) const;
+ NPadControllerType DecideBestController(NPadControllerType priority) const;
+ void RequestPadStateUpdate(u32 npad_id);
+
u32 press_state{};
NPadType style{};
@@ -321,12 +326,7 @@ private:
std::array<ControllerHolder, 10> connected_controllers{};
bool can_controllers_vibrate{true};
- void InitNewlyAddedControler(std::size_t controller_idx);
- bool IsControllerSupported(NPadControllerType controller) const;
- NPadControllerType DecideBestController(NPadControllerType priority) const;
- void RequestPadStateUpdate(u32 npad_id);
std::array<ControllerPad, 10> npad_pad_states{};
- bool IsControllerSupported(NPadControllerType controller);
bool is_in_lr_assignment_mode{false};
Core::System& system;
};
diff --git a/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp b/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp
index f764388bc..3f7b8e670 100644
--- a/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp
@@ -5,6 +5,7 @@
#include "common/assert.h"
#include "common/logging/log.h"
#include "core/core.h"
+#include "core/core_timing.h"
#include "core/hle/service/nvdrv/devices/nvdisp_disp0.h"
#include "core/hle/service/nvdrv/devices/nvmap.h"
#include "core/perf_stats.h"
@@ -38,7 +39,10 @@ void nvdisp_disp0::flip(u32 buffer_handle, u32 offset, u32 format, u32 width, u3
transform, crop_rect};
system.GetPerfStats().EndGameFrame();
+ system.GetPerfStats().EndSystemFrame();
system.GPU().SwapBuffers(&framebuffer);
+ system.FrameLimiter().DoFrameLimiting(system.CoreTiming().GetGlobalTimeUs());
+ system.GetPerfStats().BeginSystemFrame();
}
} // namespace Service::Nvidia::Devices
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp
index eb88fee1b..b27ee0502 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp
@@ -63,16 +63,26 @@ u32 nvhost_ctrl::IocCtrlEventWait(const std::vector<u8>& input, std::vector<u8>&
return NvResult::BadParameter;
}
+ u32 event_id = params.value & 0x00FF;
+
+ if (event_id >= MaxNvEvents) {
+ std::memcpy(output.data(), &params, sizeof(params));
+ return NvResult::BadParameter;
+ }
+
+ auto event = events_interface.events[event_id];
auto& gpu = system.GPU();
// This is mostly to take into account unimplemented features. As synced
// gpu is always synced.
if (!gpu.IsAsync()) {
+ event.writable->Signal();
return NvResult::Success;
}
auto lock = gpu.LockSync();
const u32 current_syncpoint_value = gpu.GetSyncpointValue(params.syncpt_id);
const s32 diff = current_syncpoint_value - params.threshold;
if (diff >= 0) {
+ event.writable->Signal();
params.value = current_syncpoint_value;
std::memcpy(output.data(), &params, sizeof(params));
return NvResult::Success;
@@ -88,27 +98,6 @@ u32 nvhost_ctrl::IocCtrlEventWait(const std::vector<u8>& input, std::vector<u8>&
return NvResult::Timeout;
}
- u32 event_id;
- if (is_async) {
- event_id = params.value & 0x00FF;
- if (event_id >= MaxNvEvents) {
- std::memcpy(output.data(), &params, sizeof(params));
- return NvResult::BadParameter;
- }
- } else {
- if (ctrl.fresh_call) {
- const auto result = events_interface.GetFreeEvent();
- if (result) {
- event_id = *result;
- } else {
- LOG_CRITICAL(Service_NVDRV, "No Free Events available!");
- event_id = params.value & 0x00FF;
- }
- } else {
- event_id = ctrl.event_id;
- }
- }
-
EventState status = events_interface.status[event_id];
if (event_id < MaxNvEvents || status == EventState::Free || status == EventState::Registered) {
events_interface.SetEventStatus(event_id, EventState::Waiting);
@@ -120,7 +109,7 @@ u32 nvhost_ctrl::IocCtrlEventWait(const std::vector<u8>& input, std::vector<u8>&
params.value = ((params.syncpt_id & 0xfff) << 16) | 0x10000000;
}
params.value |= event_id;
- events_interface.events[event_id].writable->Clear();
+ event.writable->Clear();
gpu.RegisterSyncptInterrupt(params.syncpt_id, target_value);
if (!is_async && ctrl.fresh_call) {
ctrl.must_delay = true;
diff --git a/src/core/hle/service/nvdrv/interface.cpp b/src/core/hle/service/nvdrv/interface.cpp
index 5e0c23602..68d139cfb 100644
--- a/src/core/hle/service/nvdrv/interface.cpp
+++ b/src/core/hle/service/nvdrv/interface.cpp
@@ -134,7 +134,9 @@ void NVDRV::QueryEvent(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 3, 1};
rb.Push(RESULT_SUCCESS);
if (event_id < MaxNvEvents) {
- rb.PushCopyObjects(nvdrv->GetEvent(event_id));
+ auto event = nvdrv->GetEvent(event_id);
+ event->Clear();
+ rb.PushCopyObjects(event);
rb.Push<u32>(NvResult::Success);
} else {
rb.Push<u32>(0);
diff --git a/src/core/hle/service/nvdrv/nvdrv.cpp b/src/core/hle/service/nvdrv/nvdrv.cpp
index 307a7e928..7bfb99e34 100644
--- a/src/core/hle/service/nvdrv/nvdrv.cpp
+++ b/src/core/hle/service/nvdrv/nvdrv.cpp
@@ -40,8 +40,8 @@ Module::Module(Core::System& system) {
auto& kernel = system.Kernel();
for (u32 i = 0; i < MaxNvEvents; i++) {
std::string event_label = fmt::format("NVDRV::NvEvent_{}", i);
- events_interface.events[i] = Kernel::WritableEvent::CreateEventPair(
- kernel, Kernel::ResetType::Automatic, event_label);
+ events_interface.events[i] =
+ Kernel::WritableEvent::CreateEventPair(kernel, Kernel::ResetType::Manual, event_label);
events_interface.status[i] = EventState::Free;
events_interface.registered[i] = false;
}
diff --git a/src/core/hle/service/nvflinger/buffer_queue.cpp b/src/core/hle/service/nvflinger/buffer_queue.cpp
index e1a07d3ee..55b68eb0c 100644
--- a/src/core/hle/service/nvflinger/buffer_queue.cpp
+++ b/src/core/hle/service/nvflinger/buffer_queue.cpp
@@ -14,8 +14,8 @@
namespace Service::NVFlinger {
-BufferQueue::BufferQueue(u32 id, u64 layer_id) : id(id), layer_id(layer_id) {
- auto& kernel = Core::System::GetInstance().Kernel();
+BufferQueue::BufferQueue(Kernel::KernelCore& kernel, u32 id, u64 layer_id)
+ : id(id), layer_id(layer_id) {
buffer_wait_event = Kernel::WritableEvent::CreateEventPair(kernel, Kernel::ResetType::Manual,
"BufferQueue NativeHandle");
}
diff --git a/src/core/hle/service/nvflinger/buffer_queue.h b/src/core/hle/service/nvflinger/buffer_queue.h
index 356bedb81..8f9b18547 100644
--- a/src/core/hle/service/nvflinger/buffer_queue.h
+++ b/src/core/hle/service/nvflinger/buffer_queue.h
@@ -15,6 +15,10 @@
#include "core/hle/kernel/writable_event.h"
#include "core/hle/service/nvdrv/nvdata.h"
+namespace Kernel {
+class KernelCore;
+}
+
namespace Service::NVFlinger {
struct IGBPBuffer {
@@ -44,7 +48,7 @@ public:
NativeWindowFormat = 2,
};
- BufferQueue(u32 id, u64 layer_id);
+ explicit BufferQueue(Kernel::KernelCore& kernel, u32 id, u64 layer_id);
~BufferQueue();
enum class BufferTransformFlags : u32 {
diff --git a/src/core/hle/service/nvflinger/nvflinger.cpp b/src/core/hle/service/nvflinger/nvflinger.cpp
index 2e4d707b9..cc9522aad 100644
--- a/src/core/hle/service/nvflinger/nvflinger.cpp
+++ b/src/core/hle/service/nvflinger/nvflinger.cpp
@@ -83,7 +83,7 @@ std::optional<u64> NVFlinger::CreateLayer(u64 display_id) {
const u64 layer_id = next_layer_id++;
const u32 buffer_queue_id = next_buffer_queue_id++;
- buffer_queues.emplace_back(buffer_queue_id, layer_id);
+ buffer_queues.emplace_back(system.Kernel(), buffer_queue_id, layer_id);
display->CreateLayer(layer_id, buffer_queues.back());
return layer_id;
}
@@ -187,14 +187,18 @@ void NVFlinger::Compose() {
MicroProfileFlip();
if (!buffer) {
- // There was no queued buffer to draw, render previous frame
- system.GetPerfStats().EndGameFrame();
- system.GPU().SwapBuffers({});
continue;
}
const auto& igbp_buffer = buffer->get().igbp_buffer;
+ const auto& gpu = system.GPU();
+ const auto& multi_fence = buffer->get().multi_fence;
+ for (u32 fence_id = 0; fence_id < multi_fence.num_fences; fence_id++) {
+ const auto& fence = multi_fence.fences[fence_id];
+ gpu.WaitFence(fence.id, fence.value);
+ }
+
// Now send the buffer to the GPU for drawing.
// TODO(Subv): Support more than just disp0. The display device selection is probably based
// on which display we're drawing (Default, Internal, External, etc)
diff --git a/src/core/memory/cheat_engine.cpp b/src/core/memory/cheat_engine.cpp
index b56cb0627..10821d452 100644
--- a/src/core/memory/cheat_engine.cpp
+++ b/src/core/memory/cheat_engine.cpp
@@ -22,7 +22,7 @@ constexpr u32 KEYPAD_BITMASK = 0x3FFFFFF;
StandardVmCallbacks::StandardVmCallbacks(const Core::System& system,
const CheatProcessMetadata& metadata)
- : system(system), metadata(metadata) {}
+ : metadata(metadata), system(system) {}
StandardVmCallbacks::~StandardVmCallbacks() = default;
@@ -176,9 +176,8 @@ std::vector<CheatEntry> TextCheatParser::Parse(const Core::System& system,
CheatEngine::CheatEngine(Core::System& system, std::vector<CheatEntry> cheats,
const std::array<u8, 0x20>& build_id)
- : system{system}, core_timing{system.CoreTiming()}, vm{std::make_unique<StandardVmCallbacks>(
- system, metadata)},
- cheats(std::move(cheats)) {
+ : vm{std::make_unique<StandardVmCallbacks>(system, metadata)},
+ cheats(std::move(cheats)), core_timing{system.CoreTiming()}, system{system} {
metadata.main_nso_build_id = build_id;
}
diff --git a/src/core/memory/dmnt_cheat_vm.cpp b/src/core/memory/dmnt_cheat_vm.cpp
index cc16d15a4..4f4fa5099 100644
--- a/src/core/memory/dmnt_cheat_vm.cpp
+++ b/src/core/memory/dmnt_cheat_vm.cpp
@@ -1133,8 +1133,8 @@ void DmntCheatVm::Execute(const CheatProcessMetadata& metadata) {
case SaveRestoreRegisterOpType::ClearRegs:
case SaveRestoreRegisterOpType::Restore:
default:
- src = registers.data();
- dst = saved_values.data();
+ src = saved_values.data();
+ dst = registers.data();
break;
}
for (std::size_t i = 0; i < NumRegisters; i++) {