summaryrefslogtreecommitdiffstats
path: root/src/core
diff options
context:
space:
mode:
Diffstat (limited to 'src/core')
-rw-r--r--src/core/core.cpp30
-rw-r--r--src/core/core.h31
-rw-r--r--src/core/crypto/key_manager.cpp44
-rw-r--r--src/core/crypto/key_manager.h9
-rw-r--r--src/core/file_sys/content_archive.cpp33
-rw-r--r--src/core/file_sys/content_archive.h7
-rw-r--r--src/core/file_sys/fsmitm_romfsbuild.h1
-rw-r--r--src/core/file_sys/ips_layer.cpp4
-rw-r--r--src/core/file_sys/patch_manager.cpp9
-rw-r--r--src/core/file_sys/registered_cache.cpp62
-rw-r--r--src/core/file_sys/registered_cache.h23
-rw-r--r--src/core/file_sys/vfs.cpp4
-rw-r--r--src/core/file_sys/vfs.h8
-rw-r--r--src/core/file_sys/vfs_offset.cpp4
-rw-r--r--src/core/file_sys/vfs_offset.h2
-rw-r--r--src/core/file_sys/vfs_static.h4
-rw-r--r--src/core/hle/ipc_helpers.h3
-rw-r--r--src/core/hle/kernel/hle_ipc.h8
-rw-r--r--src/core/hle/kernel/kernel.cpp4
-rw-r--r--src/core/hle/kernel/mutex.cpp2
-rw-r--r--src/core/hle/kernel/server_session.cpp4
-rw-r--r--src/core/hle/kernel/svc.cpp33
-rw-r--r--src/core/hle/kernel/thread.cpp8
-rw-r--r--src/core/hle/service/acc/acc.cpp22
-rw-r--r--src/core/hle/service/acc/acc.h1
-rw-r--r--src/core/hle/service/acc/acc_su.cpp2
-rw-r--r--src/core/hle/service/acc/acc_u0.cpp2
-rw-r--r--src/core/hle/service/acc/acc_u1.cpp2
-rw-r--r--src/core/hle/service/acc/profile_manager.cpp2
-rw-r--r--src/core/hle/service/acc/profile_manager.h3
-rw-r--r--src/core/hle/service/am/am.cpp79
-rw-r--r--src/core/hle/service/am/am.h29
-rw-r--r--src/core/hle/service/am/applet_ae.cpp34
-rw-r--r--src/core/hle/service/am/applet_ae.h6
-rw-r--r--src/core/hle/service/am/applet_oe.cpp21
-rw-r--r--src/core/hle/service/am/applet_oe.h6
-rw-r--r--src/core/hle/service/audio/hwopus.cpp2
-rw-r--r--src/core/hle/service/hid/controllers/npad.cpp5
-rw-r--r--src/core/hle/service/hid/hid.cpp2
-rw-r--r--src/core/hle/service/nvflinger/buffer_queue.cpp8
-rw-r--r--src/core/hle/service/nvflinger/buffer_queue.h11
-rw-r--r--src/core/hle/service/nvflinger/nvflinger.cpp12
-rw-r--r--src/core/hle/service/spl/module.cpp9
-rw-r--r--src/core/hle/service/spl/module.h4
-rw-r--r--src/core/hle/service/time/interface.cpp2
-rw-r--r--src/core/hle/service/time/time.cpp132
-rw-r--r--src/core/hle/service/time/time.h19
-rw-r--r--src/core/hle/service/usb/usb.cpp6
-rw-r--r--src/core/hle/service/vi/vi.cpp9
-rw-r--r--src/core/loader/loader.h5
-rw-r--r--src/core/memory.cpp2
-rw-r--r--src/core/memory_hook.h15
-rw-r--r--src/core/settings.h6
-rw-r--r--src/core/telemetry_session.cpp9
-rw-r--r--src/core/telemetry_session.h6
55 files changed, 573 insertions, 237 deletions
diff --git a/src/core/core.cpp b/src/core/core.cpp
index 7cb86ed92..6d5b5a2d0 100644
--- a/src/core/core.cpp
+++ b/src/core/core.cpp
@@ -185,7 +185,7 @@ struct System::Impl {
LOG_CRITICAL(Core, "Failed to obtain loader for {}!", filepath);
return ResultStatus::ErrorGetLoader;
}
- std::pair<boost::optional<u32>, Loader::ResultStatus> system_mode =
+ std::pair<std::optional<u32>, Loader::ResultStatus> system_mode =
app_loader->LoadKernelSystemMode();
if (system_mode.second != Loader::ResultStatus::Success) {
@@ -312,6 +312,10 @@ Cpu& System::CurrentCpuCore() {
return impl->CurrentCpuCore();
}
+const Cpu& System::CurrentCpuCore() const {
+ return impl->CurrentCpuCore();
+}
+
System::ResultStatus System::RunLoop(bool tight_loop) {
return impl->RunLoop(tight_loop);
}
@@ -342,7 +346,11 @@ PerfStatsResults System::GetAndResetPerfStats() {
return impl->GetAndResetPerfStats();
}
-Core::TelemetrySession& System::TelemetrySession() const {
+TelemetrySession& System::TelemetrySession() {
+ return *impl->telemetry_session;
+}
+
+const TelemetrySession& System::TelemetrySession() const {
return *impl->telemetry_session;
}
@@ -350,7 +358,11 @@ ARM_Interface& System::CurrentArmInterface() {
return CurrentCpuCore().ArmInterface();
}
-std::size_t System::CurrentCoreIndex() {
+const ARM_Interface& System::CurrentArmInterface() const {
+ return CurrentCpuCore().ArmInterface();
+}
+
+std::size_t System::CurrentCoreIndex() const {
return CurrentCpuCore().CoreIndex();
}
@@ -358,6 +370,10 @@ Kernel::Scheduler& System::CurrentScheduler() {
return CurrentCpuCore().Scheduler();
}
+const Kernel::Scheduler& System::CurrentScheduler() const {
+ return CurrentCpuCore().Scheduler();
+}
+
Kernel::Scheduler& System::Scheduler(std::size_t core_index) {
return CpuCore(core_index).Scheduler();
}
@@ -378,6 +394,10 @@ ARM_Interface& System::ArmInterface(std::size_t core_index) {
return CpuCore(core_index).ArmInterface();
}
+const ARM_Interface& System::ArmInterface(std::size_t core_index) const {
+ return CpuCore(core_index).ArmInterface();
+}
+
Cpu& System::CpuCore(std::size_t core_index) {
ASSERT(core_index < NUM_CPU_CORES);
return *impl->cpu_cores[core_index];
@@ -392,6 +412,10 @@ ExclusiveMonitor& System::Monitor() {
return *impl->cpu_exclusive_monitor;
}
+const ExclusiveMonitor& System::Monitor() const {
+ return *impl->cpu_exclusive_monitor;
+}
+
Tegra::GPU& System::GPU() {
return *impl->gpu_core;
}
diff --git a/src/core/core.h b/src/core/core.h
index 173be45f8..cfacceb81 100644
--- a/src/core/core.h
+++ b/src/core/core.h
@@ -129,11 +129,11 @@ public:
*/
bool IsPoweredOn() const;
- /**
- * Returns a reference to the telemetry session for this emulation session.
- * @returns Reference to the telemetry session.
- */
- Core::TelemetrySession& TelemetrySession() const;
+ /// Gets a reference to the telemetry session for this emulation session.
+ Core::TelemetrySession& TelemetrySession();
+
+ /// Gets a reference to the telemetry session for this emulation session.
+ const Core::TelemetrySession& TelemetrySession() const;
/// Prepare the core emulation for a reschedule
void PrepareReschedule();
@@ -144,24 +144,36 @@ public:
/// Gets an ARM interface to the CPU core that is currently running
ARM_Interface& CurrentArmInterface();
+ /// Gets an ARM interface to the CPU core that is currently running
+ const ARM_Interface& CurrentArmInterface() const;
+
/// Gets the index of the currently running CPU core
- std::size_t CurrentCoreIndex();
+ std::size_t CurrentCoreIndex() const;
/// Gets the scheduler for the CPU core that is currently running
Kernel::Scheduler& CurrentScheduler();
- /// Gets an ARM interface to the CPU core with the specified index
+ /// Gets the scheduler for the CPU core that is currently running
+ const Kernel::Scheduler& CurrentScheduler() const;
+
+ /// Gets a reference to an ARM interface for the CPU core with the specified index
ARM_Interface& ArmInterface(std::size_t core_index);
+ /// Gets a const reference to an ARM interface from the CPU core with the specified index
+ const ARM_Interface& ArmInterface(std::size_t core_index) const;
+
/// Gets a CPU interface to the CPU core with the specified index
Cpu& CpuCore(std::size_t core_index);
/// Gets a CPU interface to the CPU core with the specified index
const Cpu& CpuCore(std::size_t core_index) const;
- /// Gets the exclusive monitor
+ /// Gets a reference to the exclusive monitor
ExclusiveMonitor& Monitor();
+ /// Gets a constant reference to the exclusive monitor
+ const ExclusiveMonitor& Monitor() const;
+
/// Gets a mutable reference to the GPU interface
Tegra::GPU& GPU();
@@ -230,6 +242,9 @@ private:
/// Returns the currently running CPU core
Cpu& CurrentCpuCore();
+ /// Returns the currently running CPU core
+ const Cpu& CurrentCpuCore() const;
+
/**
* Initialize the emulated system.
* @param emu_window Reference to the host-system window used for video output and keyboard
diff --git a/src/core/crypto/key_manager.cpp b/src/core/crypto/key_manager.cpp
index 89ae79eb3..904afa039 100644
--- a/src/core/crypto/key_manager.cpp
+++ b/src/core/crypto/key_manager.cpp
@@ -141,28 +141,28 @@ Key128 DeriveKeyblobMACKey(const Key128& keyblob_key, const Key128& mac_source)
return mac_key;
}
-boost::optional<Key128> DeriveSDSeed() {
+std::optional<Key128> DeriveSDSeed() {
const FileUtil::IOFile save_43(FileUtil::GetUserPath(FileUtil::UserPath::NANDDir) +
"/system/save/8000000000000043",
"rb+");
if (!save_43.IsOpen())
- return boost::none;
+ return {};
const FileUtil::IOFile sd_private(
FileUtil::GetUserPath(FileUtil::UserPath::SDMCDir) + "/Nintendo/Contents/private", "rb+");
if (!sd_private.IsOpen())
- return boost::none;
+ return {};
std::array<u8, 0x10> private_seed{};
if (sd_private.ReadBytes(private_seed.data(), private_seed.size()) != private_seed.size()) {
- return boost::none;
+ return {};
}
std::array<u8, 0x10> buffer{};
std::size_t offset = 0;
for (; offset + 0x10 < save_43.GetSize(); ++offset) {
if (!save_43.Seek(offset, SEEK_SET)) {
- return boost::none;
+ return {};
}
save_43.ReadBytes(buffer.data(), buffer.size());
@@ -172,12 +172,12 @@ boost::optional<Key128> DeriveSDSeed() {
}
if (!save_43.Seek(offset + 0x10, SEEK_SET)) {
- return boost::none;
+ return {};
}
Key128 seed{};
if (save_43.ReadBytes(seed.data(), seed.size()) != seed.size()) {
- return boost::none;
+ return {};
}
return seed;
}
@@ -291,26 +291,26 @@ static std::array<u8, target_size> MGF1(const std::array<u8, in_size>& seed) {
}
template <size_t size>
-static boost::optional<u64> FindTicketOffset(const std::array<u8, size>& data) {
+static std::optional<u64> FindTicketOffset(const std::array<u8, size>& data) {
u64 offset = 0;
for (size_t i = 0x20; i < data.size() - 0x10; ++i) {
if (data[i] == 0x1) {
offset = i + 1;
break;
} else if (data[i] != 0x0) {
- return boost::none;
+ return {};
}
}
return offset;
}
-boost::optional<std::pair<Key128, Key128>> ParseTicket(const TicketRaw& ticket,
- const RSAKeyPair<2048>& key) {
+std::optional<std::pair<Key128, Key128>> ParseTicket(const TicketRaw& ticket,
+ const RSAKeyPair<2048>& key) {
u32 cert_authority;
std::memcpy(&cert_authority, ticket.data() + 0x140, sizeof(cert_authority));
if (cert_authority == 0)
- return boost::none;
+ return {};
if (cert_authority != Common::MakeMagic('R', 'o', 'o', 't')) {
LOG_INFO(Crypto,
"Attempting to parse ticket with non-standard certificate authority {:08X}.",
@@ -321,7 +321,7 @@ boost::optional<std::pair<Key128, Key128>> ParseTicket(const TicketRaw& ticket,
std::memcpy(rights_id.data(), ticket.data() + 0x2A0, sizeof(Key128));
if (rights_id == Key128{})
- return boost::none;
+ return {};
Key128 key_temp{};
@@ -356,17 +356,17 @@ boost::optional<std::pair<Key128, Key128>> ParseTicket(const TicketRaw& ticket,
std::memcpy(m_2.data(), rsa_step.data() + 0x21, m_2.size());
if (m_0 != 0)
- return boost::none;
+ return {};
m_1 = m_1 ^ MGF1<0x20>(m_2);
m_2 = m_2 ^ MGF1<0xDF>(m_1);
const auto offset = FindTicketOffset(m_2);
- if (offset == boost::none)
- return boost::none;
- ASSERT(offset.get() > 0);
+ if (!offset)
+ return {};
+ ASSERT(*offset > 0);
- std::memcpy(key_temp.data(), m_2.data() + offset.get(), key_temp.size());
+ std::memcpy(key_temp.data(), m_2.data() + *offset, key_temp.size());
return std::make_pair(rights_id, key_temp);
}
@@ -661,8 +661,8 @@ void KeyManager::DeriveSDSeedLazy() {
return;
const auto res = DeriveSDSeed();
- if (res != boost::none)
- SetKey(S128KeyType::SDSeed, res.get());
+ if (res)
+ SetKey(S128KeyType::SDSeed, *res);
}
static Key128 CalculateCMAC(const u8* source, size_t size, const Key128& key) {
@@ -889,9 +889,9 @@ void KeyManager::DeriveETicket(PartitionDataManager& data) {
for (const auto& raw : res) {
const auto pair = ParseTicket(raw, rsa_key);
- if (pair == boost::none)
+ if (!pair)
continue;
- const auto& [rid, key] = pair.value();
+ const auto& [rid, key] = *pair;
u128 rights_id;
std::memcpy(rights_id.data(), rid.data(), rid.size());
SetKey(S128KeyType::Titlekey, key, rights_id[1], rights_id[0]);
diff --git a/src/core/crypto/key_manager.h b/src/core/crypto/key_manager.h
index cccb3c0ae..22f268c65 100644
--- a/src/core/crypto/key_manager.h
+++ b/src/core/crypto/key_manager.h
@@ -6,9 +6,10 @@
#include <array>
#include <map>
+#include <optional>
#include <string>
+
#include <boost/container/flat_map.hpp>
-#include <boost/optional.hpp>
#include <fmt/format.h>
#include "common/common_types.h"
#include "core/crypto/partition_data_manager.h"
@@ -191,14 +192,14 @@ Key128 DeriveMasterKey(const std::array<u8, 0x90>& keyblob, const Key128& master
std::array<u8, 0x90> DecryptKeyblob(const std::array<u8, 0xB0>& encrypted_keyblob,
const Key128& key);
-boost::optional<Key128> DeriveSDSeed();
+std::optional<Key128> DeriveSDSeed();
Loader::ResultStatus DeriveSDKeys(std::array<Key256, 2>& sd_keys, KeyManager& keys);
std::vector<TicketRaw> GetTicketblob(const FileUtil::IOFile& ticket_save);
// Returns a pair of {rights_id, titlekey}. Fails if the ticket has no certificate authority (offset
// 0x140-0x144 is zero)
-boost::optional<std::pair<Key128, Key128>> ParseTicket(
- const TicketRaw& ticket, const RSAKeyPair<2048>& eticket_extended_key);
+std::optional<std::pair<Key128, Key128>> ParseTicket(const TicketRaw& ticket,
+ const RSAKeyPair<2048>& eticket_extended_key);
} // namespace Core::Crypto
diff --git a/src/core/file_sys/content_archive.cpp b/src/core/file_sys/content_archive.cpp
index 77e04704e..b46fe893c 100644
--- a/src/core/file_sys/content_archive.cpp
+++ b/src/core/file_sys/content_archive.cpp
@@ -4,10 +4,9 @@
#include <algorithm>
#include <cstring>
+#include <optional>
#include <utility>
-#include <boost/optional.hpp>
-
#include "common/logging/log.h"
#include "core/crypto/aes_util.h"
#include "core/crypto/ctr_encryption_layer.h"
@@ -306,18 +305,18 @@ bool NCA::ReadRomFSSection(const NCASectionHeader& section, const NCASectionTabl
subsection_buckets.back().entries.push_back({section.bktr.relocation.offset, {0}, ctr_low});
subsection_buckets.back().entries.push_back({size, {0}, 0});
- boost::optional<Core::Crypto::Key128> key = boost::none;
+ std::optional<Core::Crypto::Key128> key = {};
if (encrypted) {
if (has_rights_id) {
status = Loader::ResultStatus::Success;
key = GetTitlekey();
- if (key == boost::none) {
+ if (!key) {
status = Loader::ResultStatus::ErrorMissingTitlekey;
return false;
}
} else {
key = GetKeyAreaKey(NCASectionCryptoType::BKTR);
- if (key == boost::none) {
+ if (!key) {
status = Loader::ResultStatus::ErrorMissingKeyAreaKey;
return false;
}
@@ -332,7 +331,7 @@ bool NCA::ReadRomFSSection(const NCASectionHeader& section, const NCASectionTabl
auto bktr = std::make_shared<BKTR>(
bktr_base_romfs, std::make_shared<OffsetVfsFile>(file, romfs_size, base_offset),
relocation_block, relocation_buckets, subsection_block, subsection_buckets, encrypted,
- encrypted ? key.get() : Core::Crypto::Key128{}, base_offset, bktr_base_ivfc_offset,
+ encrypted ? *key : Core::Crypto::Key128{}, base_offset, bktr_base_ivfc_offset,
section.raw.section_ctr);
// BKTR applies to entire IVFC, so make an offset version to level 6
@@ -388,11 +387,11 @@ u8 NCA::GetCryptoRevision() const {
return master_key_id;
}
-boost::optional<Core::Crypto::Key128> NCA::GetKeyAreaKey(NCASectionCryptoType type) const {
+std::optional<Core::Crypto::Key128> NCA::GetKeyAreaKey(NCASectionCryptoType type) const {
const auto master_key_id = GetCryptoRevision();
if (!keys.HasKey(Core::Crypto::S128KeyType::KeyArea, master_key_id, header.key_index))
- return boost::none;
+ return {};
std::vector<u8> key_area(header.key_area.begin(), header.key_area.end());
Core::Crypto::AESCipher<Core::Crypto::Key128> cipher(
@@ -416,25 +415,25 @@ boost::optional<Core::Crypto::Key128> NCA::GetKeyAreaKey(NCASectionCryptoType ty
return out;
}
-boost::optional<Core::Crypto::Key128> NCA::GetTitlekey() {
+std::optional<Core::Crypto::Key128> NCA::GetTitlekey() {
const auto master_key_id = GetCryptoRevision();
u128 rights_id{};
memcpy(rights_id.data(), header.rights_id.data(), 16);
if (rights_id == u128{}) {
status = Loader::ResultStatus::ErrorInvalidRightsID;
- return boost::none;
+ return {};
}
auto titlekey = keys.GetKey(Core::Crypto::S128KeyType::Titlekey, rights_id[1], rights_id[0]);
if (titlekey == Core::Crypto::Key128{}) {
status = Loader::ResultStatus::ErrorMissingTitlekey;
- return boost::none;
+ return {};
}
if (!keys.HasKey(Core::Crypto::S128KeyType::Titlekek, master_key_id)) {
status = Loader::ResultStatus::ErrorMissingTitlekek;
- return boost::none;
+ return {};
}
Core::Crypto::AESCipher<Core::Crypto::Key128> cipher(
@@ -458,25 +457,25 @@ VirtualFile NCA::Decrypt(const NCASectionHeader& s_header, VirtualFile in, u64 s
case NCASectionCryptoType::BKTR:
LOG_DEBUG(Crypto, "called with mode=CTR, starting_offset={:016X}", starting_offset);
{
- boost::optional<Core::Crypto::Key128> key = boost::none;
+ std::optional<Core::Crypto::Key128> key = {};
if (has_rights_id) {
status = Loader::ResultStatus::Success;
key = GetTitlekey();
- if (key == boost::none) {
+ if (!key) {
if (status == Loader::ResultStatus::Success)
status = Loader::ResultStatus::ErrorMissingTitlekey;
return nullptr;
}
} else {
key = GetKeyAreaKey(NCASectionCryptoType::CTR);
- if (key == boost::none) {
+ if (!key) {
status = Loader::ResultStatus::ErrorMissingKeyAreaKey;
return nullptr;
}
}
- auto out = std::make_shared<Core::Crypto::CTREncryptionLayer>(
- std::move(in), key.value(), starting_offset);
+ auto out = std::make_shared<Core::Crypto::CTREncryptionLayer>(std::move(in), *key,
+ starting_offset);
std::vector<u8> iv(16);
for (u8 i = 0; i < 8; ++i)
iv[i] = s_header.raw.section_ctr[0x8 - i - 1];
diff --git a/src/core/file_sys/content_archive.h b/src/core/file_sys/content_archive.h
index 211946686..4bba55607 100644
--- a/src/core/file_sys/content_archive.h
+++ b/src/core/file_sys/content_archive.h
@@ -6,9 +6,10 @@
#include <array>
#include <memory>
+#include <optional>
#include <string>
#include <vector>
-#include <boost/optional.hpp>
+
#include "common/common_funcs.h"
#include "common/common_types.h"
#include "common/swap.h"
@@ -111,8 +112,8 @@ private:
bool ReadPFS0Section(const NCASectionHeader& section, const NCASectionTableEntry& entry);
u8 GetCryptoRevision() const;
- boost::optional<Core::Crypto::Key128> GetKeyAreaKey(NCASectionCryptoType type) const;
- boost::optional<Core::Crypto::Key128> GetTitlekey();
+ std::optional<Core::Crypto::Key128> GetKeyAreaKey(NCASectionCryptoType type) const;
+ std::optional<Core::Crypto::Key128> GetTitlekey();
VirtualFile Decrypt(const NCASectionHeader& header, VirtualFile in, u64 starting_offset);
std::vector<VirtualDir> dirs;
diff --git a/src/core/file_sys/fsmitm_romfsbuild.h b/src/core/file_sys/fsmitm_romfsbuild.h
index 3d377b0af..a62502193 100644
--- a/src/core/file_sys/fsmitm_romfsbuild.h
+++ b/src/core/file_sys/fsmitm_romfsbuild.h
@@ -27,7 +27,6 @@
#include <map>
#include <memory>
#include <string>
-#include <boost/detail/container_fwd.hpp>
#include "common/common_types.h"
#include "core/file_sys/vfs.h"
diff --git a/src/core/file_sys/ips_layer.cpp b/src/core/file_sys/ips_layer.cpp
index 999939d5a..485c4913a 100644
--- a/src/core/file_sys/ips_layer.cpp
+++ b/src/core/file_sys/ips_layer.cpp
@@ -103,12 +103,12 @@ VirtualFile PatchIPS(const VirtualFile& in, const VirtualFile& ips) {
offset += sizeof(u16);
const auto data = ips->ReadByte(offset++);
- if (data == boost::none)
+ if (!data)
return nullptr;
if (real_offset + rle_size > in_data.size())
rle_size = static_cast<u16>(in_data.size() - real_offset);
- std::memset(in_data.data() + real_offset, data.get(), rle_size);
+ std::memset(in_data.data() + real_offset, *data, rle_size);
} else { // Standard Patch
auto read = data_size;
if (real_offset + read > in_data.size())
diff --git a/src/core/file_sys/patch_manager.cpp b/src/core/file_sys/patch_manager.cpp
index cb457b987..0c1156989 100644
--- a/src/core/file_sys/patch_manager.cpp
+++ b/src/core/file_sys/patch_manager.cpp
@@ -65,7 +65,7 @@ VirtualDir PatchManager::PatchExeFS(VirtualDir exefs) const {
if (update != nullptr && update->GetExeFS() != nullptr &&
update->GetStatus() == Loader::ResultStatus::ErrorMissingBKTRBaseRomFS) {
LOG_INFO(Loader, " ExeFS: Update ({}) applied successfully",
- FormatTitleVersion(installed->GetEntryVersion(update_tid).get_value_or(0)));
+ FormatTitleVersion(installed->GetEntryVersion(update_tid).value_or(0)));
exefs = update->GetExeFS();
}
@@ -236,7 +236,7 @@ VirtualFile PatchManager::PatchRomFS(VirtualFile romfs, u64 ivfc_offset, Content
if (new_nca->GetStatus() == Loader::ResultStatus::Success &&
new_nca->GetRomFS() != nullptr) {
LOG_INFO(Loader, " RomFS: Update ({}) applied successfully",
- FormatTitleVersion(installed->GetEntryVersion(update_tid).get_value_or(0)));
+ FormatTitleVersion(installed->GetEntryVersion(update_tid).value_or(0)));
romfs = new_nca->GetRomFS();
}
} else if (update_raw != nullptr) {
@@ -280,12 +280,11 @@ std::map<std::string, std::string, std::less<>> PatchManager::GetPatchVersionNam
} else {
if (installed->HasEntry(update_tid, ContentRecordType::Program)) {
const auto meta_ver = installed->GetEntryVersion(update_tid);
- if (meta_ver == boost::none || meta_ver.get() == 0) {
+ if (meta_ver.value_or(0) == 0) {
out.insert_or_assign("Update", "");
} else {
out.insert_or_assign(
- "Update",
- FormatTitleVersion(meta_ver.get(), TitleVersionFormat::ThreeElements));
+ "Update", FormatTitleVersion(*meta_ver, TitleVersionFormat::ThreeElements));
}
} else if (update_raw != nullptr) {
out.insert_or_assign("Update", "PACKED");
diff --git a/src/core/file_sys/registered_cache.cpp b/src/core/file_sys/registered_cache.cpp
index 29b100414..96302a241 100644
--- a/src/core/file_sys/registered_cache.cpp
+++ b/src/core/file_sys/registered_cache.cpp
@@ -159,28 +159,28 @@ VirtualFile RegisteredCache::GetFileAtID(NcaID id) const {
return file;
}
-static boost::optional<NcaID> CheckMapForContentRecord(
+static std::optional<NcaID> CheckMapForContentRecord(
const boost::container::flat_map<u64, CNMT>& map, u64 title_id, ContentRecordType type) {
if (map.find(title_id) == map.end())
- return boost::none;
+ return {};
const auto& cnmt = map.at(title_id);
const auto iter = std::find_if(cnmt.GetContentRecords().begin(), cnmt.GetContentRecords().end(),
[type](const ContentRecord& rec) { return rec.type == type; });
if (iter == cnmt.GetContentRecords().end())
- return boost::none;
+ return {};
- return boost::make_optional(iter->nca_id);
+ return std::make_optional(iter->nca_id);
}
-boost::optional<NcaID> RegisteredCache::GetNcaIDFromMetadata(u64 title_id,
- ContentRecordType type) const {
+std::optional<NcaID> RegisteredCache::GetNcaIDFromMetadata(u64 title_id,
+ ContentRecordType type) const {
if (type == ContentRecordType::Meta && meta_id.find(title_id) != meta_id.end())
return meta_id.at(title_id);
const auto res1 = CheckMapForContentRecord(yuzu_meta, title_id, type);
- if (res1 != boost::none)
+ if (res1)
return res1;
return CheckMapForContentRecord(meta, title_id, type);
}
@@ -283,17 +283,14 @@ bool RegisteredCache::HasEntry(RegisteredCacheEntry entry) const {
VirtualFile RegisteredCache::GetEntryUnparsed(u64 title_id, ContentRecordType type) const {
const auto id = GetNcaIDFromMetadata(title_id, type);
- if (id == boost::none)
- return nullptr;
-
- return GetFileAtID(id.get());
+ return id ? GetFileAtID(*id) : nullptr;
}
VirtualFile RegisteredCache::GetEntryUnparsed(RegisteredCacheEntry entry) const {
return GetEntryUnparsed(entry.title_id, entry.type);
}
-boost::optional<u32> RegisteredCache::GetEntryVersion(u64 title_id) const {
+std::optional<u32> RegisteredCache::GetEntryVersion(u64 title_id) const {
const auto meta_iter = meta.find(title_id);
if (meta_iter != meta.end())
return meta_iter->second.GetTitleVersion();
@@ -302,15 +299,12 @@ boost::optional<u32> RegisteredCache::GetEntryVersion(u64 title_id) const {
if (yuzu_meta_iter != yuzu_meta.end())
return yuzu_meta_iter->second.GetTitleVersion();
- return boost::none;
+ return {};
}
VirtualFile RegisteredCache::GetEntryRaw(u64 title_id, ContentRecordType type) const {
const auto id = GetNcaIDFromMetadata(title_id, type);
- if (id == boost::none)
- return nullptr;
-
- return parser(GetFileAtID(id.get()), id.get());
+ return id ? parser(GetFileAtID(*id), *id) : nullptr;
}
VirtualFile RegisteredCache::GetEntryRaw(RegisteredCacheEntry entry) const {
@@ -364,8 +358,8 @@ std::vector<RegisteredCacheEntry> RegisteredCache::ListEntries() const {
}
std::vector<RegisteredCacheEntry> RegisteredCache::ListEntriesFilter(
- boost::optional<TitleType> title_type, boost::optional<ContentRecordType> record_type,
- boost::optional<u64> title_id) const {
+ std::optional<TitleType> title_type, std::optional<ContentRecordType> record_type,
+ std::optional<u64> title_id) const {
std::vector<RegisteredCacheEntry> out;
IterateAllMetadata<RegisteredCacheEntry>(
out,
@@ -373,11 +367,11 @@ std::vector<RegisteredCacheEntry> RegisteredCache::ListEntriesFilter(
return RegisteredCacheEntry{c.GetTitleID(), r.type};
},
[&title_type, &record_type, &title_id](const CNMT& c, const ContentRecord& r) {
- if (title_type != boost::none && title_type.get() != c.GetType())
+ if (title_type && *title_type != c.GetType())
return false;
- if (record_type != boost::none && record_type.get() != r.type)
+ if (record_type && *record_type != r.type)
return false;
- if (title_id != boost::none && title_id.get() != c.GetTitleID())
+ if (title_id && *title_id != c.GetTitleID())
return false;
return true;
});
@@ -459,7 +453,7 @@ InstallResult RegisteredCache::InstallEntry(std::shared_ptr<NCA> nca, TitleType
InstallResult RegisteredCache::RawInstallNCA(std::shared_ptr<NCA> nca, const VfsCopyFunction& copy,
bool overwrite_if_exists,
- boost::optional<NcaID> override_id) {
+ std::optional<NcaID> override_id) {
const auto in = nca->GetBaseFile();
Core::Crypto::SHA256Hash hash{};
@@ -468,12 +462,12 @@ InstallResult RegisteredCache::RawInstallNCA(std::shared_ptr<NCA> nca, const Vfs
// game is massive), we're going to cheat and only hash the first MB of the NCA.
// Also, for XCIs the NcaID matters, so if the override id isn't none, use that.
NcaID id{};
- if (override_id == boost::none) {
+ if (override_id) {
+ id = *override_id;
+ } else {
const auto& data = in->ReadBytes(0x100000);
mbedtls_sha256(data.data(), data.size(), hash.data(), 0);
memcpy(id.data(), hash.data(), 16);
- } else {
- id = override_id.get();
}
std::string path = GetRelativePathFromNcaID(id, false, true);
@@ -543,14 +537,14 @@ bool RegisteredCacheUnion::HasEntry(RegisteredCacheEntry entry) const {
return HasEntry(entry.title_id, entry.type);
}
-boost::optional<u32> RegisteredCacheUnion::GetEntryVersion(u64 title_id) const {
+std::optional<u32> RegisteredCacheUnion::GetEntryVersion(u64 title_id) const {
for (const auto& c : caches) {
const auto res = c->GetEntryVersion(title_id);
- if (res != boost::none)
+ if (res)
return res;
}
- return boost::none;
+ return {};
}
VirtualFile RegisteredCacheUnion::GetEntryUnparsed(u64 title_id, ContentRecordType type) const {
@@ -609,8 +603,8 @@ std::vector<RegisteredCacheEntry> RegisteredCacheUnion::ListEntries() const {
}
std::vector<RegisteredCacheEntry> RegisteredCacheUnion::ListEntriesFilter(
- boost::optional<TitleType> title_type, boost::optional<ContentRecordType> record_type,
- boost::optional<u64> title_id) const {
+ std::optional<TitleType> title_type, std::optional<ContentRecordType> record_type,
+ std::optional<u64> title_id) const {
std::vector<RegisteredCacheEntry> out;
for (const auto& c : caches) {
c->IterateAllMetadata<RegisteredCacheEntry>(
@@ -619,11 +613,11 @@ std::vector<RegisteredCacheEntry> RegisteredCacheUnion::ListEntriesFilter(
return RegisteredCacheEntry{c.GetTitleID(), r.type};
},
[&title_type, &record_type, &title_id](const CNMT& c, const ContentRecord& r) {
- if (title_type != boost::none && title_type.get() != c.GetType())
+ if (title_type && *title_type != c.GetType())
return false;
- if (record_type != boost::none && record_type.get() != r.type)
+ if (record_type && *record_type != r.type)
return false;
- if (title_id != boost::none && title_id.get() != c.GetTitleID())
+ if (title_id && *title_id != c.GetTitleID())
return false;
return true;
});
diff --git a/src/core/file_sys/registered_cache.h b/src/core/file_sys/registered_cache.h
index 5beceffb3..6cfb16017 100644
--- a/src/core/file_sys/registered_cache.h
+++ b/src/core/file_sys/registered_cache.h
@@ -84,7 +84,7 @@ public:
bool HasEntry(u64 title_id, ContentRecordType type) const;
bool HasEntry(RegisteredCacheEntry entry) const;
- boost::optional<u32> GetEntryVersion(u64 title_id) const;
+ std::optional<u32> GetEntryVersion(u64 title_id) const;
VirtualFile GetEntryUnparsed(u64 title_id, ContentRecordType type) const;
VirtualFile GetEntryUnparsed(RegisteredCacheEntry entry) const;
@@ -96,11 +96,10 @@ public:
std::unique_ptr<NCA> GetEntry(RegisteredCacheEntry entry) const;
std::vector<RegisteredCacheEntry> ListEntries() const;
- // If a parameter is not boost::none, it will be filtered for from all entries.
+ // If a parameter is not std::nullopt, it will be filtered for from all entries.
std::vector<RegisteredCacheEntry> ListEntriesFilter(
- boost::optional<TitleType> title_type = boost::none,
- boost::optional<ContentRecordType> record_type = boost::none,
- boost::optional<u64> title_id = boost::none) const;
+ std::optional<TitleType> title_type = {}, std::optional<ContentRecordType> record_type = {},
+ std::optional<u64> title_id = {}) const;
// Raw copies all the ncas from the xci/nsp to the csache. Does some quick checks to make sure
// there is a meta NCA and all of them are accessible.
@@ -125,12 +124,11 @@ private:
std::vector<NcaID> AccumulateFiles() const;
void ProcessFiles(const std::vector<NcaID>& ids);
void AccumulateYuzuMeta();
- boost::optional<NcaID> GetNcaIDFromMetadata(u64 title_id, ContentRecordType type) const;
+ std::optional<NcaID> GetNcaIDFromMetadata(u64 title_id, ContentRecordType type) const;
VirtualFile GetFileAtID(NcaID id) const;
VirtualFile OpenFileOrDirectoryConcat(const VirtualDir& dir, std::string_view path) const;
InstallResult RawInstallNCA(std::shared_ptr<NCA> nca, const VfsCopyFunction& copy,
- bool overwrite_if_exists,
- boost::optional<NcaID> override_id = boost::none);
+ bool overwrite_if_exists, std::optional<NcaID> override_id = {});
bool RawInstallYuzuMeta(const CNMT& cnmt);
VirtualDir dir;
@@ -153,7 +151,7 @@ public:
bool HasEntry(u64 title_id, ContentRecordType type) const;
bool HasEntry(RegisteredCacheEntry entry) const;
- boost::optional<u32> GetEntryVersion(u64 title_id) const;
+ std::optional<u32> GetEntryVersion(u64 title_id) const;
VirtualFile GetEntryUnparsed(u64 title_id, ContentRecordType type) const;
VirtualFile GetEntryUnparsed(RegisteredCacheEntry entry) const;
@@ -165,11 +163,10 @@ public:
std::unique_ptr<NCA> GetEntry(RegisteredCacheEntry entry) const;
std::vector<RegisteredCacheEntry> ListEntries() const;
- // If a parameter is not boost::none, it will be filtered for from all entries.
+ // If a parameter is not std::nullopt, it will be filtered for from all entries.
std::vector<RegisteredCacheEntry> ListEntriesFilter(
- boost::optional<TitleType> title_type = boost::none,
- boost::optional<ContentRecordType> record_type = boost::none,
- boost::optional<u64> title_id = boost::none) const;
+ std::optional<TitleType> title_type = {}, std::optional<ContentRecordType> record_type = {},
+ std::optional<u64> title_id = {}) const;
private:
std::vector<RegisteredCache*> caches;
diff --git a/src/core/file_sys/vfs.cpp b/src/core/file_sys/vfs.cpp
index 3824c74e0..7b584de7f 100644
--- a/src/core/file_sys/vfs.cpp
+++ b/src/core/file_sys/vfs.cpp
@@ -167,13 +167,13 @@ std::string VfsFile::GetExtension() const {
VfsDirectory::~VfsDirectory() = default;
-boost::optional<u8> VfsFile::ReadByte(std::size_t offset) const {
+std::optional<u8> VfsFile::ReadByte(std::size_t offset) const {
u8 out{};
std::size_t size = Read(&out, 1, offset);
if (size == 1)
return out;
- return boost::none;
+ return {};
}
std::vector<u8> VfsFile::ReadBytes(std::size_t size, std::size_t offset) const {
diff --git a/src/core/file_sys/vfs.h b/src/core/file_sys/vfs.h
index 09dc9f288..002f99d4e 100644
--- a/src/core/file_sys/vfs.h
+++ b/src/core/file_sys/vfs.h
@@ -4,13 +4,15 @@
#pragma once
+#include <functional>
#include <map>
#include <memory>
+#include <optional>
#include <string>
#include <string_view>
#include <type_traits>
#include <vector>
-#include <boost/optional.hpp>
+
#include "common/common_types.h"
#include "core/file_sys/vfs_types.h"
@@ -103,8 +105,8 @@ public:
// into file. Returns number of bytes successfully written.
virtual std::size_t Write(const u8* data, std::size_t length, std::size_t offset = 0) = 0;
- // Reads exactly one byte at the offset provided, returning boost::none on error.
- virtual boost::optional<u8> ReadByte(std::size_t offset = 0) const;
+ // Reads exactly one byte at the offset provided, returning std::nullopt on error.
+ virtual std::optional<u8> ReadByte(std::size_t offset = 0) const;
// Reads size bytes starting at offset in file into a vector.
virtual std::vector<u8> ReadBytes(std::size_t size, std::size_t offset = 0) const;
// Reads all the bytes from the file into a vector. Equivalent to 'file->Read(file->GetSize(),
diff --git a/src/core/file_sys/vfs_offset.cpp b/src/core/file_sys/vfs_offset.cpp
index a4c6719a0..c96f88488 100644
--- a/src/core/file_sys/vfs_offset.cpp
+++ b/src/core/file_sys/vfs_offset.cpp
@@ -57,11 +57,11 @@ std::size_t OffsetVfsFile::Write(const u8* data, std::size_t length, std::size_t
return file->Write(data, TrimToFit(length, r_offset), offset + r_offset);
}
-boost::optional<u8> OffsetVfsFile::ReadByte(std::size_t r_offset) const {
+std::optional<u8> OffsetVfsFile::ReadByte(std::size_t r_offset) const {
if (r_offset < size)
return file->ReadByte(offset + r_offset);
- return boost::none;
+ return {};
}
std::vector<u8> OffsetVfsFile::ReadBytes(std::size_t r_size, std::size_t r_offset) const {
diff --git a/src/core/file_sys/vfs_offset.h b/src/core/file_sys/vfs_offset.h
index 8062702a7..f7b7a3256 100644
--- a/src/core/file_sys/vfs_offset.h
+++ b/src/core/file_sys/vfs_offset.h
@@ -29,7 +29,7 @@ public:
bool IsReadable() const override;
std::size_t Read(u8* data, std::size_t length, std::size_t offset) const override;
std::size_t Write(const u8* data, std::size_t length, std::size_t offset) override;
- boost::optional<u8> ReadByte(std::size_t offset) const override;
+ std::optional<u8> ReadByte(std::size_t offset) const override;
std::vector<u8> ReadBytes(std::size_t size, std::size_t offset) const override;
std::vector<u8> ReadAllBytes() const override;
bool WriteByte(u8 data, std::size_t offset) override;
diff --git a/src/core/file_sys/vfs_static.h b/src/core/file_sys/vfs_static.h
index 44fab51d1..9f5a90b1b 100644
--- a/src/core/file_sys/vfs_static.h
+++ b/src/core/file_sys/vfs_static.h
@@ -53,10 +53,10 @@ public:
return 0;
}
- boost::optional<u8> ReadByte(std::size_t offset) const override {
+ std::optional<u8> ReadByte(std::size_t offset) const override {
if (offset < size)
return value;
- return boost::none;
+ return {};
}
std::vector<u8> ReadBytes(std::size_t length, std::size_t offset) const override {
diff --git a/src/core/hle/ipc_helpers.h b/src/core/hle/ipc_helpers.h
index a4bfe2eb0..0a7142ada 100644
--- a/src/core/hle/ipc_helpers.h
+++ b/src/core/hle/ipc_helpers.h
@@ -117,8 +117,7 @@ public:
AlignWithPadding();
- const bool request_has_domain_header{context.GetDomainMessageHeader() != nullptr};
- if (context.Session()->IsDomain() && request_has_domain_header) {
+ if (context.Session()->IsDomain() && context.HasDomainMessageHeader()) {
IPC::DomainMessageHeader domain_header{};
domain_header.num_objects = num_domain_objects;
PushRaw(domain_header);
diff --git a/src/core/hle/kernel/hle_ipc.h b/src/core/hle/kernel/hle_ipc.h
index f01491daa..a38e34b74 100644
--- a/src/core/hle/kernel/hle_ipc.h
+++ b/src/core/hle/kernel/hle_ipc.h
@@ -161,8 +161,12 @@ public:
return buffer_c_desciptors;
}
- const std::shared_ptr<IPC::DomainMessageHeader>& GetDomainMessageHeader() const {
- return domain_message_header;
+ const IPC::DomainMessageHeader* GetDomainMessageHeader() const {
+ return domain_message_header.get();
+ }
+
+ bool HasDomainMessageHeader() const {
+ return domain_message_header != nullptr;
}
/// Helper function to read a buffer using the appropriate buffer descriptor
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp
index 4b6b32dd5..1fd4ba5d2 100644
--- a/src/core/hle/kernel/kernel.cpp
+++ b/src/core/hle/kernel/kernel.cpp
@@ -32,7 +32,7 @@ namespace Kernel {
*/
static void ThreadWakeupCallback(u64 thread_handle, [[maybe_unused]] int cycles_late) {
const auto proper_handle = static_cast<Handle>(thread_handle);
- auto& system = Core::System::GetInstance();
+ const auto& system = Core::System::GetInstance();
// Lock the global kernel mutex when we enter the kernel HLE.
std::lock_guard<std::recursive_mutex> lock(HLE::g_hle_lock);
@@ -90,7 +90,7 @@ static void ThreadWakeupCallback(u64 thread_handle, [[maybe_unused]] int cycles_
/// The timer callback event, called when a timer is fired
static void TimerCallback(u64 timer_handle, int cycles_late) {
const auto proper_handle = static_cast<Handle>(timer_handle);
- auto& system = Core::System::GetInstance();
+ const auto& system = Core::System::GetInstance();
SharedPtr<Timer> timer = system.Kernel().RetrieveTimerFromCallbackHandleTable(proper_handle);
if (timer == nullptr) {
diff --git a/src/core/hle/kernel/mutex.cpp b/src/core/hle/kernel/mutex.cpp
index dd541ffcc..0743670ad 100644
--- a/src/core/hle/kernel/mutex.cpp
+++ b/src/core/hle/kernel/mutex.cpp
@@ -6,8 +6,6 @@
#include <utility>
#include <vector>
-#include <boost/range/algorithm_ext/erase.hpp>
-
#include "common/assert.h"
#include "core/core.h"
#include "core/hle/kernel/errors.h"
diff --git a/src/core/hle/kernel/server_session.cpp b/src/core/hle/kernel/server_session.cpp
index 5fc320403..80897f3a4 100644
--- a/src/core/hle/kernel/server_session.cpp
+++ b/src/core/hle/kernel/server_session.cpp
@@ -63,7 +63,7 @@ void ServerSession::Acquire(Thread* thread) {
}
ResultCode ServerSession::HandleDomainSyncRequest(Kernel::HLERequestContext& context) {
- auto& domain_message_header = context.GetDomainMessageHeader();
+ auto* const domain_message_header = context.GetDomainMessageHeader();
if (domain_message_header) {
// Set domain handlers in HLE context, used for domain objects (IPC interfaces) as inputs
context.SetDomainRequestHandlers(domain_request_handlers);
@@ -111,7 +111,7 @@ ResultCode ServerSession::HandleSyncRequest(SharedPtr<Thread> thread) {
ResultCode result = RESULT_SUCCESS;
// If the session has been converted to a domain, handle the domain request
- if (IsDomain() && context.GetDomainMessageHeader()) {
+ if (IsDomain() && context.HasDomainMessageHeader()) {
result = HandleDomainSyncRequest(context);
// If there is no domain header, the regular session handler is used
} else if (hle_handler != nullptr) {
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp
index 4e490e2b5..0bfe1e3be 100644
--- a/src/core/hle/kernel/svc.cpp
+++ b/src/core/hle/kernel/svc.cpp
@@ -34,6 +34,7 @@
#include "core/hle/lock.h"
#include "core/hle/result.h"
#include "core/hle/service/service.h"
+#include "core/settings.h"
namespace Kernel {
namespace {
@@ -395,16 +396,42 @@ struct BreakReason {
/// Break program execution
static void Break(u32 reason, u64 info1, u64 info2) {
BreakReason break_reason{reason};
+ bool has_dumped_buffer{};
+ const auto handle_debug_buffer = [&](VAddr addr, u64 sz) {
+ if (sz == 0 || addr == 0 || has_dumped_buffer) {
+ return;
+ }
+
+ // This typically is an error code so we're going to assume this is the case
+ if (sz == sizeof(u32)) {
+ LOG_CRITICAL(Debug_Emulated, "debug_buffer_err_code={:X}", Memory::Read32(addr));
+ } else {
+ // We don't know what's in here so we'll hexdump it
+ std::vector<u8> debug_buffer(sz);
+ Memory::ReadBlock(addr, debug_buffer.data(), sz);
+ std::string hexdump;
+ for (std::size_t i = 0; i < debug_buffer.size(); i++) {
+ hexdump += fmt::format("{:02X} ", debug_buffer[i]);
+ if (i != 0 && i % 16 == 0) {
+ hexdump += '\n';
+ }
+ }
+ LOG_CRITICAL(Debug_Emulated, "debug_buffer=\n{}", hexdump);
+ }
+ has_dumped_buffer = true;
+ };
switch (break_reason.break_type) {
case BreakType::Panic:
LOG_CRITICAL(Debug_Emulated, "Signalling debugger, PANIC! info1=0x{:016X}, info2=0x{:016X}",
info1, info2);
+ handle_debug_buffer(info1, info2);
break;
case BreakType::AssertionFailed:
LOG_CRITICAL(Debug_Emulated,
"Signalling debugger, Assertion failed! info1=0x{:016X}, info2=0x{:016X}",
info1, info2);
+ handle_debug_buffer(info1, info2);
break;
case BreakType::PreNROLoad:
LOG_WARNING(
@@ -433,6 +460,7 @@ static void Break(u32 reason, u64 info1, u64 info2) {
Debug_Emulated,
"Signalling debugger, Unknown break reason {}, info1=0x{:016X}, info2=0x{:016X}",
static_cast<u32>(break_reason.break_type.Value()), info1, info2);
+ handle_debug_buffer(info1, info2);
break;
}
@@ -441,6 +469,7 @@ static void Break(u32 reason, u64 info1, u64 info2) {
Debug_Emulated,
"Emulated program broke execution! reason=0x{:016X}, info1=0x{:016X}, info2=0x{:016X}",
reason, info1, info2);
+ handle_debug_buffer(info1, info2);
ASSERT(false);
Core::CurrentProcess()->PrepareForTermination();
@@ -530,7 +559,7 @@ static ResultCode GetInfo(u64* result, u64 info_id, u64 handle, u64 info_sub_id)
*result = 0;
break;
case GetInfoType::RandomEntropy:
- *result = 0;
+ *result = Settings::values.rng_seed.value_or(0);
break;
case GetInfoType::ASLRRegionBaseAddr:
*result = vm_manager.GetASLRRegionBaseAddress();
@@ -572,7 +601,7 @@ static ResultCode GetInfo(u64* result, u64 info_id, u64 handle, u64 info_sub_id)
return ERR_INVALID_HANDLE;
}
- auto& system = Core::System::GetInstance();
+ const auto& system = Core::System::GetInstance();
const auto& scheduler = system.CurrentScheduler();
const auto* const current_thread = scheduler.GetCurrentThread();
const bool same_thread = current_thread == thread;
diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp
index 59bc9e0af..dd5cd9ced 100644
--- a/src/core/hle/kernel/thread.cpp
+++ b/src/core/hle/kernel/thread.cpp
@@ -4,9 +4,9 @@
#include <algorithm>
#include <cinttypes>
+#include <optional>
#include <vector>
-#include <boost/optional.hpp>
#include <boost/range/algorithm_ext/erase.hpp>
#include "common/assert.h"
@@ -94,7 +94,7 @@ void Thread::CancelWakeupTimer() {
CoreTiming::UnscheduleEventThreadsafe(kernel.ThreadWakeupCallbackEventType(), callback_handle);
}
-static boost::optional<s32> GetNextProcessorId(u64 mask) {
+static std::optional<s32> GetNextProcessorId(u64 mask) {
for (s32 index = 0; index < Core::NUM_CPU_CORES; ++index) {
if (mask & (1ULL << index)) {
if (!Core::System::GetInstance().Scheduler(index).GetCurrentThread()) {
@@ -142,7 +142,7 @@ void Thread::ResumeFromWait() {
status = ThreadStatus::Ready;
- boost::optional<s32> new_processor_id = GetNextProcessorId(affinity_mask);
+ std::optional<s32> new_processor_id = GetNextProcessorId(affinity_mask);
if (!new_processor_id) {
new_processor_id = processor_id;
}
@@ -369,7 +369,7 @@ void Thread::ChangeCore(u32 core, u64 mask) {
return;
}
- boost::optional<s32> new_processor_id{GetNextProcessorId(affinity_mask)};
+ std::optional<s32> new_processor_id{GetNextProcessorId(affinity_mask)};
if (!new_processor_id) {
new_processor_id = processor_id;
diff --git a/src/core/hle/service/acc/acc.cpp b/src/core/hle/service/acc/acc.cpp
index c6437a671..8318eff5f 100644
--- a/src/core/hle/service/acc/acc.cpp
+++ b/src/core/hle/service/acc/acc.cpp
@@ -242,6 +242,28 @@ void Module::Interface::GetBaasAccountManagerForApplication(Kernel::HLERequestCo
LOG_DEBUG(Service_ACC, "called");
}
+void Module::Interface::TrySelectUserWithoutInteraction(Kernel::HLERequestContext& ctx) {
+ LOG_DEBUG(Service_ACC, "called");
+ // A u8 is passed into this function which we can safely ignore. It's to determine if we have
+ // access to use the network or not by the looks of it
+ IPC::ResponseBuilder rb{ctx, 6};
+ if (profile_manager->GetUserCount() != 1) {
+ rb.Push(RESULT_SUCCESS);
+ rb.PushRaw<u128>(INVALID_UUID);
+ return;
+ }
+ auto user_list = profile_manager->GetAllUsers();
+ if (user_list.empty()) {
+ rb.Push(ResultCode(-1)); // TODO(ogniK): Find the correct error code
+ rb.PushRaw<u128>(INVALID_UUID);
+ return;
+ }
+
+ // Select the first user we have
+ rb.Push(RESULT_SUCCESS);
+ rb.PushRaw<u128>(profile_manager->GetUser(0)->uuid);
+}
+
Module::Interface::Interface(std::shared_ptr<Module> module,
std::shared_ptr<ProfileManager> profile_manager, const char* name)
: ServiceFramework(name), module(std::move(module)),
diff --git a/src/core/hle/service/acc/acc.h b/src/core/hle/service/acc/acc.h
index c7ed74351..89b2104fa 100644
--- a/src/core/hle/service/acc/acc.h
+++ b/src/core/hle/service/acc/acc.h
@@ -27,6 +27,7 @@ public:
void InitializeApplicationInfo(Kernel::HLERequestContext& ctx);
void GetBaasAccountManagerForApplication(Kernel::HLERequestContext& ctx);
void IsUserRegistrationRequestPermitted(Kernel::HLERequestContext& ctx);
+ void TrySelectUserWithoutInteraction(Kernel::HLERequestContext& ctx);
protected:
std::shared_ptr<Module> module;
diff --git a/src/core/hle/service/acc/acc_su.cpp b/src/core/hle/service/acc/acc_su.cpp
index ad455c3a7..5e2030355 100644
--- a/src/core/hle/service/acc/acc_su.cpp
+++ b/src/core/hle/service/acc/acc_su.cpp
@@ -17,7 +17,7 @@ ACC_SU::ACC_SU(std::shared_ptr<Module> module, std::shared_ptr<ProfileManager> p
{5, &ACC_SU::GetProfile, "GetProfile"},
{6, nullptr, "GetProfileDigest"},
{50, &ACC_SU::IsUserRegistrationRequestPermitted, "IsUserRegistrationRequestPermitted"},
- {51, nullptr, "TrySelectUserWithoutInteraction"},
+ {51, &ACC_SU::TrySelectUserWithoutInteraction, "TrySelectUserWithoutInteraction"},
{60, nullptr, "ListOpenContextStoredUsers"},
{100, nullptr, "GetUserRegistrationNotifier"},
{101, nullptr, "GetUserStateChangeNotifier"},
diff --git a/src/core/hle/service/acc/acc_u0.cpp b/src/core/hle/service/acc/acc_u0.cpp
index 72d4adf35..a4d705b45 100644
--- a/src/core/hle/service/acc/acc_u0.cpp
+++ b/src/core/hle/service/acc/acc_u0.cpp
@@ -17,7 +17,7 @@ ACC_U0::ACC_U0(std::shared_ptr<Module> module, std::shared_ptr<ProfileManager> p
{5, &ACC_U0::GetProfile, "GetProfile"},
{6, nullptr, "GetProfileDigest"},
{50, &ACC_U0::IsUserRegistrationRequestPermitted, "IsUserRegistrationRequestPermitted"},
- {51, nullptr, "TrySelectUserWithoutInteraction"},
+ {51, &ACC_U0::TrySelectUserWithoutInteraction, "TrySelectUserWithoutInteraction"},
{60, nullptr, "ListOpenContextStoredUsers"},
{100, &ACC_U0::InitializeApplicationInfo, "InitializeApplicationInfo"},
{101, &ACC_U0::GetBaasAccountManagerForApplication, "GetBaasAccountManagerForApplication"},
diff --git a/src/core/hle/service/acc/acc_u1.cpp b/src/core/hle/service/acc/acc_u1.cpp
index d480f08e5..8fffc93b5 100644
--- a/src/core/hle/service/acc/acc_u1.cpp
+++ b/src/core/hle/service/acc/acc_u1.cpp
@@ -17,7 +17,7 @@ ACC_U1::ACC_U1(std::shared_ptr<Module> module, std::shared_ptr<ProfileManager> p
{5, &ACC_U1::GetProfile, "GetProfile"},
{6, nullptr, "GetProfileDigest"},
{50, &ACC_U1::IsUserRegistrationRequestPermitted, "IsUserRegistrationRequestPermitted"},
- {51, nullptr, "TrySelectUserWithoutInteraction"},
+ {51, &ACC_U1::TrySelectUserWithoutInteraction, "TrySelectUserWithoutInteraction"},
{60, nullptr, "ListOpenContextStoredUsers"},
{100, nullptr, "GetUserRegistrationNotifier"},
{101, nullptr, "GetUserStateChangeNotifier"},
diff --git a/src/core/hle/service/acc/profile_manager.cpp b/src/core/hle/service/acc/profile_manager.cpp
index 3cac1b4ff..c08394e4c 100644
--- a/src/core/hle/service/acc/profile_manager.cpp
+++ b/src/core/hle/service/acc/profile_manager.cpp
@@ -195,7 +195,7 @@ std::size_t ProfileManager::GetOpenUserCount() const {
/// Checks if a user id exists in our profile manager
bool ProfileManager::UserExists(UUID uuid) const {
- return GetUserIndex(uuid) != std::nullopt;
+ return GetUserIndex(uuid).has_value();
}
bool ProfileManager::UserExistsIndex(std::size_t index) const {
diff --git a/src/core/hle/service/acc/profile_manager.h b/src/core/hle/service/acc/profile_manager.h
index 1cd2e51b2..747c46c20 100644
--- a/src/core/hle/service/acc/profile_manager.h
+++ b/src/core/hle/service/acc/profile_manager.h
@@ -57,7 +57,8 @@ struct UUID {
};
static_assert(sizeof(UUID) == 16, "UUID is an invalid size!");
-using ProfileUsername = std::array<u8, 0x20>;
+constexpr std::size_t profile_username_size = 32;
+using ProfileUsername = std::array<u8, profile_username_size>;
using ProfileData = std::array<u8, MAX_DATA>;
using UserIDArray = std::array<UUID, MAX_USERS>;
diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp
index 59aafd616..0477ce66e 100644
--- a/src/core/hle/service/am/am.cpp
+++ b/src/core/hle/service/am/am.cpp
@@ -338,7 +338,54 @@ void ISelfController::GetIdleTimeDetectionExtension(Kernel::HLERequestContext& c
LOG_WARNING(Service_AM, "(STUBBED) called");
}
-ICommonStateGetter::ICommonStateGetter() : ServiceFramework("ICommonStateGetter") {
+AppletMessageQueue::AppletMessageQueue() {
+ auto& kernel = Core::System::GetInstance().Kernel();
+ on_new_message = Kernel::Event::Create(kernel, Kernel::ResetType::Sticky,
+ "AMMessageQueue:OnMessageRecieved");
+ on_operation_mode_changed = Kernel::Event::Create(kernel, Kernel::ResetType::OneShot,
+ "AMMessageQueue:OperationModeChanged");
+}
+
+AppletMessageQueue::~AppletMessageQueue() = default;
+
+const Kernel::SharedPtr<Kernel::Event>& AppletMessageQueue::GetMesssageRecieveEvent() const {
+ return on_new_message;
+}
+
+const Kernel::SharedPtr<Kernel::Event>& AppletMessageQueue::GetOperationModeChangedEvent() const {
+ return on_operation_mode_changed;
+}
+
+void AppletMessageQueue::PushMessage(AppletMessage msg) {
+ messages.push(msg);
+ on_new_message->Signal();
+}
+
+AppletMessageQueue::AppletMessage AppletMessageQueue::PopMessage() {
+ if (messages.empty()) {
+ on_new_message->Clear();
+ return AppletMessage::NoMessage;
+ }
+ auto msg = messages.front();
+ messages.pop();
+ if (messages.empty()) {
+ on_new_message->Clear();
+ }
+ return msg;
+}
+
+std::size_t AppletMessageQueue::GetMessageCount() const {
+ return messages.size();
+}
+
+void AppletMessageQueue::OperationModeChanged() {
+ PushMessage(AppletMessage::OperationModeChanged);
+ PushMessage(AppletMessage::PerformanceModeChanged);
+ on_operation_mode_changed->Signal();
+}
+
+ICommonStateGetter::ICommonStateGetter(std::shared_ptr<AppletMessageQueue> msg_queue)
+ : ServiceFramework("ICommonStateGetter"), msg_queue(std::move(msg_queue)) {
// clang-format off
static const FunctionInfo functions[] = {
{0, &ICommonStateGetter::GetEventHandle, "GetEventHandle"},
@@ -388,21 +435,19 @@ void ICommonStateGetter::GetBootMode(Kernel::HLERequestContext& ctx) {
}
void ICommonStateGetter::GetEventHandle(Kernel::HLERequestContext& ctx) {
- event->Signal();
-
IPC::ResponseBuilder rb{ctx, 2, 1};
rb.Push(RESULT_SUCCESS);
- rb.PushCopyObjects(event);
+ rb.PushCopyObjects(msg_queue->GetMesssageRecieveEvent());
- LOG_WARNING(Service_AM, "(STUBBED) called");
+ LOG_DEBUG(Service_AM, "called");
}
void ICommonStateGetter::ReceiveMessage(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(RESULT_SUCCESS);
- rb.Push<u32>(15);
+ rb.PushEnum<AppletMessageQueue::AppletMessage>(msg_queue->PopMessage());
- LOG_WARNING(Service_AM, "(STUBBED) called");
+ LOG_DEBUG(Service_AM, "called");
}
void ICommonStateGetter::GetCurrentFocusState(Kernel::HLERequestContext& ctx) {
@@ -414,13 +459,11 @@ void ICommonStateGetter::GetCurrentFocusState(Kernel::HLERequestContext& ctx) {
}
void ICommonStateGetter::GetDefaultDisplayResolutionChangeEvent(Kernel::HLERequestContext& ctx) {
- event->Signal();
-
IPC::ResponseBuilder rb{ctx, 2, 1};
rb.Push(RESULT_SUCCESS);
- rb.PushCopyObjects(event);
+ rb.PushCopyObjects(msg_queue->GetOperationModeChangedEvent());
- LOG_WARNING(Service_AM, "(STUBBED) called");
+ LOG_DEBUG(Service_AM, "called");
}
void ICommonStateGetter::GetDefaultDisplayResolution(Kernel::HLERequestContext& ctx) {
@@ -444,7 +487,7 @@ void ICommonStateGetter::GetOperationMode(Kernel::HLERequestContext& ctx) {
rb.Push(RESULT_SUCCESS);
rb.Push(static_cast<u8>(use_docked_mode ? OperationMode::Docked : OperationMode::Handheld));
- LOG_WARNING(Service_AM, "(STUBBED) called");
+ LOG_DEBUG(Service_AM, "called");
}
void ICommonStateGetter::GetPerformanceMode(Kernel::HLERequestContext& ctx) {
@@ -454,7 +497,7 @@ void ICommonStateGetter::GetPerformanceMode(Kernel::HLERequestContext& ctx) {
rb.Push(static_cast<u32>(use_docked_mode ? APM::PerformanceMode::Docked
: APM::PerformanceMode::Handheld));
- LOG_WARNING(Service_AM, "(STUBBED) called");
+ LOG_DEBUG(Service_AM, "called");
}
class IStorageAccessor final : public ServiceFramework<IStorageAccessor> {
@@ -743,7 +786,7 @@ void IApplicationFunctions::PopLaunchParameter(Kernel::HLERequestContext& ctx) {
Account::ProfileManager profile_manager{};
const auto uuid = profile_manager.GetUser(Settings::values.current_user);
- ASSERT(uuid != std::nullopt);
+ ASSERT(uuid);
params.current_user = uuid->uuid;
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
@@ -840,8 +883,12 @@ void IApplicationFunctions::GetPseudoDeviceId(Kernel::HLERequestContext& ctx) {
void InstallInterfaces(SM::ServiceManager& service_manager,
std::shared_ptr<NVFlinger::NVFlinger> nvflinger) {
- std::make_shared<AppletAE>(nvflinger)->InstallAsService(service_manager);
- std::make_shared<AppletOE>(nvflinger)->InstallAsService(service_manager);
+ auto message_queue = std::make_shared<AppletMessageQueue>();
+ message_queue->PushMessage(
+ AppletMessageQueue::AppletMessage::FocusStateChanged); // Needed on game boot
+
+ std::make_shared<AppletAE>(nvflinger, message_queue)->InstallAsService(service_manager);
+ std::make_shared<AppletOE>(nvflinger, message_queue)->InstallAsService(service_manager);
std::make_shared<IdleSys>()->InstallAsService(service_manager);
std::make_shared<OMM>()->InstallAsService(service_manager);
std::make_shared<SPSM>()->InstallAsService(service_manager);
diff --git a/src/core/hle/service/am/am.h b/src/core/hle/service/am/am.h
index 095f94851..2f1c20bce 100644
--- a/src/core/hle/service/am/am.h
+++ b/src/core/hle/service/am/am.h
@@ -5,6 +5,7 @@
#pragma once
#include <memory>
+#include <queue>
#include "core/hle/service/service.h"
namespace Kernel {
@@ -39,6 +40,31 @@ enum SystemLanguage {
TraditionalChinese = 16,
};
+class AppletMessageQueue {
+public:
+ enum class AppletMessage : u32 {
+ NoMessage = 0,
+ FocusStateChanged = 15,
+ OperationModeChanged = 30,
+ PerformanceModeChanged = 31,
+ };
+
+ AppletMessageQueue();
+ ~AppletMessageQueue();
+
+ const Kernel::SharedPtr<Kernel::Event>& GetMesssageRecieveEvent() const;
+ const Kernel::SharedPtr<Kernel::Event>& GetOperationModeChangedEvent() const;
+ void PushMessage(AppletMessage msg);
+ AppletMessage PopMessage();
+ std::size_t GetMessageCount() const;
+ void OperationModeChanged();
+
+private:
+ std::queue<AppletMessage> messages;
+ Kernel::SharedPtr<Kernel::Event> on_new_message;
+ Kernel::SharedPtr<Kernel::Event> on_operation_mode_changed;
+};
+
class IWindowController final : public ServiceFramework<IWindowController> {
public:
IWindowController();
@@ -102,7 +128,7 @@ private:
class ICommonStateGetter final : public ServiceFramework<ICommonStateGetter> {
public:
- ICommonStateGetter();
+ explicit ICommonStateGetter(std::shared_ptr<AppletMessageQueue> msg_queue);
~ICommonStateGetter() override;
private:
@@ -126,6 +152,7 @@ private:
void GetDefaultDisplayResolution(Kernel::HLERequestContext& ctx);
Kernel::SharedPtr<Kernel::Event> event;
+ std::shared_ptr<AppletMessageQueue> msg_queue;
};
class ILibraryAppletCreator final : public ServiceFramework<ILibraryAppletCreator> {
diff --git a/src/core/hle/service/am/applet_ae.cpp b/src/core/hle/service/am/applet_ae.cpp
index 68ea778e8..ec93e3529 100644
--- a/src/core/hle/service/am/applet_ae.cpp
+++ b/src/core/hle/service/am/applet_ae.cpp
@@ -12,8 +12,10 @@ namespace Service::AM {
class ILibraryAppletProxy final : public ServiceFramework<ILibraryAppletProxy> {
public:
- explicit ILibraryAppletProxy(std::shared_ptr<NVFlinger::NVFlinger> nvflinger)
- : ServiceFramework("ILibraryAppletProxy"), nvflinger(std::move(nvflinger)) {
+ explicit ILibraryAppletProxy(std::shared_ptr<NVFlinger::NVFlinger> nvflinger,
+ std::shared_ptr<AppletMessageQueue> msg_queue)
+ : ServiceFramework("ILibraryAppletProxy"), nvflinger(std::move(nvflinger)),
+ msg_queue(std::move(msg_queue)) {
static const FunctionInfo functions[] = {
{0, &ILibraryAppletProxy::GetCommonStateGetter, "GetCommonStateGetter"},
{1, &ILibraryAppletProxy::GetSelfController, "GetSelfController"},
@@ -32,7 +34,7 @@ private:
void GetCommonStateGetter(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
- rb.PushIpcInterface<ICommonStateGetter>();
+ rb.PushIpcInterface<ICommonStateGetter>(msg_queue);
LOG_DEBUG(Service_AM, "called");
}
@@ -93,12 +95,15 @@ private:
}
std::shared_ptr<NVFlinger::NVFlinger> nvflinger;
+ std::shared_ptr<AppletMessageQueue> msg_queue;
};
class ISystemAppletProxy final : public ServiceFramework<ISystemAppletProxy> {
public:
- explicit ISystemAppletProxy(std::shared_ptr<NVFlinger::NVFlinger> nvflinger)
- : ServiceFramework("ISystemAppletProxy"), nvflinger(std::move(nvflinger)) {
+ explicit ISystemAppletProxy(std::shared_ptr<NVFlinger::NVFlinger> nvflinger,
+ std::shared_ptr<AppletMessageQueue> msg_queue)
+ : ServiceFramework("ISystemAppletProxy"), nvflinger(std::move(nvflinger)),
+ msg_queue(std::move(msg_queue)) {
static const FunctionInfo functions[] = {
{0, &ISystemAppletProxy::GetCommonStateGetter, "GetCommonStateGetter"},
{1, &ISystemAppletProxy::GetSelfController, "GetSelfController"},
@@ -119,7 +124,7 @@ private:
void GetCommonStateGetter(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
- rb.PushIpcInterface<ICommonStateGetter>();
+ rb.PushIpcInterface<ICommonStateGetter>(msg_queue);
LOG_DEBUG(Service_AM, "called");
}
@@ -186,31 +191,34 @@ private:
LOG_DEBUG(Service_AM, "called");
}
std::shared_ptr<NVFlinger::NVFlinger> nvflinger;
+ std::shared_ptr<AppletMessageQueue> msg_queue;
};
void AppletAE::OpenSystemAppletProxy(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
- rb.PushIpcInterface<ISystemAppletProxy>(nvflinger);
+ rb.PushIpcInterface<ISystemAppletProxy>(nvflinger, msg_queue);
LOG_DEBUG(Service_AM, "called");
}
void AppletAE::OpenLibraryAppletProxy(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
- rb.PushIpcInterface<ILibraryAppletProxy>(nvflinger);
+ rb.PushIpcInterface<ILibraryAppletProxy>(nvflinger, msg_queue);
LOG_DEBUG(Service_AM, "called");
}
void AppletAE::OpenLibraryAppletProxyOld(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
- rb.PushIpcInterface<ILibraryAppletProxy>(nvflinger);
+ rb.PushIpcInterface<ILibraryAppletProxy>(nvflinger, msg_queue);
LOG_DEBUG(Service_AM, "called");
}
-AppletAE::AppletAE(std::shared_ptr<NVFlinger::NVFlinger> nvflinger)
- : ServiceFramework("appletAE"), nvflinger(std::move(nvflinger)) {
+AppletAE::AppletAE(std::shared_ptr<NVFlinger::NVFlinger> nvflinger,
+ std::shared_ptr<AppletMessageQueue> msg_queue)
+ : ServiceFramework("appletAE"), nvflinger(std::move(nvflinger)),
+ msg_queue(std::move(msg_queue)) {
// clang-format off
static const FunctionInfo functions[] = {
{100, &AppletAE::OpenSystemAppletProxy, "OpenSystemAppletProxy"},
@@ -228,4 +236,8 @@ AppletAE::AppletAE(std::shared_ptr<NVFlinger::NVFlinger> nvflinger)
AppletAE::~AppletAE() = default;
+const std::shared_ptr<AppletMessageQueue>& AppletAE::GetMessageQueue() const {
+ return msg_queue;
+}
+
} // namespace Service::AM
diff --git a/src/core/hle/service/am/applet_ae.h b/src/core/hle/service/am/applet_ae.h
index 1ed77baa4..902db2665 100644
--- a/src/core/hle/service/am/applet_ae.h
+++ b/src/core/hle/service/am/applet_ae.h
@@ -17,15 +17,19 @@ namespace AM {
class AppletAE final : public ServiceFramework<AppletAE> {
public:
- explicit AppletAE(std::shared_ptr<NVFlinger::NVFlinger> nvflinger);
+ explicit AppletAE(std::shared_ptr<NVFlinger::NVFlinger> nvflinger,
+ std::shared_ptr<AppletMessageQueue> msg_queue);
~AppletAE() override;
+ const std::shared_ptr<AppletMessageQueue>& GetMessageQueue() const;
+
private:
void OpenSystemAppletProxy(Kernel::HLERequestContext& ctx);
void OpenLibraryAppletProxy(Kernel::HLERequestContext& ctx);
void OpenLibraryAppletProxyOld(Kernel::HLERequestContext& ctx);
std::shared_ptr<NVFlinger::NVFlinger> nvflinger;
+ std::shared_ptr<AppletMessageQueue> msg_queue;
};
} // namespace AM
diff --git a/src/core/hle/service/am/applet_oe.cpp b/src/core/hle/service/am/applet_oe.cpp
index 60717afd9..20c8d5fff 100644
--- a/src/core/hle/service/am/applet_oe.cpp
+++ b/src/core/hle/service/am/applet_oe.cpp
@@ -12,8 +12,10 @@ namespace Service::AM {
class IApplicationProxy final : public ServiceFramework<IApplicationProxy> {
public:
- explicit IApplicationProxy(std::shared_ptr<NVFlinger::NVFlinger> nvflinger)
- : ServiceFramework("IApplicationProxy"), nvflinger(std::move(nvflinger)) {
+ explicit IApplicationProxy(std::shared_ptr<NVFlinger::NVFlinger> nvflinger,
+ std::shared_ptr<AppletMessageQueue> msg_queue)
+ : ServiceFramework("IApplicationProxy"), nvflinger(std::move(nvflinger)),
+ msg_queue(std::move(msg_queue)) {
// clang-format off
static const FunctionInfo functions[] = {
{0, &IApplicationProxy::GetCommonStateGetter, "GetCommonStateGetter"},
@@ -70,7 +72,7 @@ private:
void GetCommonStateGetter(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
- rb.PushIpcInterface<ICommonStateGetter>();
+ rb.PushIpcInterface<ICommonStateGetter>(msg_queue);
LOG_DEBUG(Service_AM, "called");
}
@@ -89,17 +91,20 @@ private:
}
std::shared_ptr<NVFlinger::NVFlinger> nvflinger;
+ std::shared_ptr<AppletMessageQueue> msg_queue;
};
void AppletOE::OpenApplicationProxy(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
- rb.PushIpcInterface<IApplicationProxy>(nvflinger);
+ rb.PushIpcInterface<IApplicationProxy>(nvflinger, msg_queue);
LOG_DEBUG(Service_AM, "called");
}
-AppletOE::AppletOE(std::shared_ptr<NVFlinger::NVFlinger> nvflinger)
- : ServiceFramework("appletOE"), nvflinger(std::move(nvflinger)) {
+AppletOE::AppletOE(std::shared_ptr<NVFlinger::NVFlinger> nvflinger,
+ std::shared_ptr<AppletMessageQueue> msg_queue)
+ : ServiceFramework("appletOE"), nvflinger(std::move(nvflinger)),
+ msg_queue(std::move(msg_queue)) {
static const FunctionInfo functions[] = {
{0, &AppletOE::OpenApplicationProxy, "OpenApplicationProxy"},
};
@@ -108,4 +113,8 @@ AppletOE::AppletOE(std::shared_ptr<NVFlinger::NVFlinger> nvflinger)
AppletOE::~AppletOE() = default;
+const std::shared_ptr<AppletMessageQueue>& AppletOE::GetMessageQueue() const {
+ return msg_queue;
+}
+
} // namespace Service::AM
diff --git a/src/core/hle/service/am/applet_oe.h b/src/core/hle/service/am/applet_oe.h
index 60cfdfd9d..bbd0108ef 100644
--- a/src/core/hle/service/am/applet_oe.h
+++ b/src/core/hle/service/am/applet_oe.h
@@ -17,13 +17,17 @@ namespace AM {
class AppletOE final : public ServiceFramework<AppletOE> {
public:
- explicit AppletOE(std::shared_ptr<NVFlinger::NVFlinger> nvflinger);
+ explicit AppletOE(std::shared_ptr<NVFlinger::NVFlinger> nvflinger,
+ std::shared_ptr<AppletMessageQueue> msg_queue);
~AppletOE() override;
+ const std::shared_ptr<AppletMessageQueue>& GetMessageQueue() const;
+
private:
void OpenApplicationProxy(Kernel::HLERequestContext& ctx);
std::shared_ptr<NVFlinger::NVFlinger> nvflinger;
+ std::shared_ptr<AppletMessageQueue> msg_queue;
};
} // namespace AM
diff --git a/src/core/hle/service/audio/hwopus.cpp b/src/core/hle/service/audio/hwopus.cpp
index 7168c6a10..783c39503 100644
--- a/src/core/hle/service/audio/hwopus.cpp
+++ b/src/core/hle/service/audio/hwopus.cpp
@@ -161,7 +161,7 @@ void HwOpus::OpenOpusDecoder(Kernel::HLERequestContext& ctx) {
ASSERT_MSG(channel_count == 1 || channel_count == 2, "Invalid channel count");
std::size_t worker_sz = WorkerBufferSize(channel_count);
- ASSERT_MSG(buffer_sz < worker_sz, "Worker buffer too large");
+ ASSERT_MSG(buffer_sz >= worker_sz, "Worker buffer too large");
std::unique_ptr<OpusDecoder, OpusDeleter> decoder{
static_cast<OpusDecoder*>(operator new(worker_sz))};
if (opus_decoder_init(decoder.get(), sample_rate, channel_count)) {
diff --git a/src/core/hle/service/hid/controllers/npad.cpp b/src/core/hle/service/hid/controllers/npad.cpp
index 4b4d1324f..ff9b64be4 100644
--- a/src/core/hle/service/hid/controllers/npad.cpp
+++ b/src/core/hle/service/hid/controllers/npad.cpp
@@ -392,8 +392,10 @@ std::size_t Controller_NPad::GetSupportedNPadIdTypesSize() const {
}
void Controller_NPad::SetHoldType(NpadHoldType joy_hold_type) {
+ styleset_changed_event->Signal();
hold_type = joy_hold_type;
}
+
Controller_NPad::NpadHoldType Controller_NPad::GetHoldType() const {
return hold_type;
}
@@ -427,6 +429,9 @@ void Controller_NPad::VibrateController(const std::vector<u32>& controller_ids,
}
Kernel::SharedPtr<Kernel::Event> Controller_NPad::GetStyleSetChangedEvent() const {
+ // TODO(ogniK): Figure out the best time to signal this event. This event seems that it should
+ // be signalled at least once, and signaled after a new controller is connected?
+ styleset_changed_event->Signal();
return styleset_changed_event;
}
diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp
index a9aa9ec78..a45fd4954 100644
--- a/src/core/hle/service/hid/hid.cpp
+++ b/src/core/hle/service/hid/hid.cpp
@@ -96,6 +96,8 @@ public:
// TODO(shinyquagsire23): Other update callbacks? (accel, gyro?)
CoreTiming::ScheduleEvent(pad_update_ticks, pad_update_event);
+
+ ReloadInputDevices();
}
void ActivateController(HidController controller) {
diff --git a/src/core/hle/service/nvflinger/buffer_queue.cpp b/src/core/hle/service/nvflinger/buffer_queue.cpp
index fd98d541d..630ebbfc7 100644
--- a/src/core/hle/service/nvflinger/buffer_queue.cpp
+++ b/src/core/hle/service/nvflinger/buffer_queue.cpp
@@ -31,7 +31,7 @@ void BufferQueue::SetPreallocatedBuffer(u32 slot, const IGBPBuffer& igbp_buffer)
buffer_wait_event->Signal();
}
-boost::optional<u32> BufferQueue::DequeueBuffer(u32 width, u32 height) {
+std::optional<u32> BufferQueue::DequeueBuffer(u32 width, u32 height) {
auto itr = std::find_if(queue.begin(), queue.end(), [&](const Buffer& buffer) {
// Only consider free buffers. Buffers become free once again after they've been Acquired
// and Released by the compositor, see the NVFlinger::Compose method.
@@ -44,7 +44,7 @@ boost::optional<u32> BufferQueue::DequeueBuffer(u32 width, u32 height) {
});
if (itr == queue.end()) {
- return boost::none;
+ return {};
}
itr->status = Buffer::Status::Dequeued;
@@ -70,12 +70,12 @@ void BufferQueue::QueueBuffer(u32 slot, BufferTransformFlags transform,
itr->crop_rect = crop_rect;
}
-boost::optional<const BufferQueue::Buffer&> BufferQueue::AcquireBuffer() {
+std::optional<std::reference_wrapper<const BufferQueue::Buffer>> BufferQueue::AcquireBuffer() {
auto itr = std::find_if(queue.begin(), queue.end(), [](const Buffer& buffer) {
return buffer.status == Buffer::Status::Queued;
});
if (itr == queue.end())
- return boost::none;
+ return {};
itr->status = Buffer::Status::Acquired;
return *itr;
}
diff --git a/src/core/hle/service/nvflinger/buffer_queue.h b/src/core/hle/service/nvflinger/buffer_queue.h
index 50b767732..8cff5eb71 100644
--- a/src/core/hle/service/nvflinger/buffer_queue.h
+++ b/src/core/hle/service/nvflinger/buffer_queue.h
@@ -4,8 +4,9 @@
#pragma once
+#include <optional>
#include <vector>
-#include <boost/optional.hpp>
+
#include "common/common_funcs.h"
#include "common/math_util.h"
#include "common/swap.h"
@@ -57,9 +58,9 @@ public:
/// Rotate source image 90 degrees clockwise
Rotate90 = 0x04,
/// Rotate source image 180 degrees
- Roate180 = 0x03,
+ Rotate180 = 0x03,
/// Rotate source image 270 degrees clockwise
- Roate270 = 0x07,
+ Rotate270 = 0x07,
};
struct Buffer {
@@ -73,11 +74,11 @@ public:
};
void SetPreallocatedBuffer(u32 slot, const IGBPBuffer& igbp_buffer);
- boost::optional<u32> DequeueBuffer(u32 width, u32 height);
+ std::optional<u32> DequeueBuffer(u32 width, u32 height);
const IGBPBuffer& RequestBuffer(u32 slot) const;
void QueueBuffer(u32 slot, BufferTransformFlags transform,
const MathUtil::Rectangle<int>& crop_rect);
- boost::optional<const Buffer&> AcquireBuffer();
+ std::optional<std::reference_wrapper<const Buffer>> AcquireBuffer();
void ReleaseBuffer(u32 slot);
u32 Query(QueryType type);
diff --git a/src/core/hle/service/nvflinger/nvflinger.cpp b/src/core/hle/service/nvflinger/nvflinger.cpp
index d47b6f659..214e6d1b3 100644
--- a/src/core/hle/service/nvflinger/nvflinger.cpp
+++ b/src/core/hle/service/nvflinger/nvflinger.cpp
@@ -3,7 +3,7 @@
// Refer to the license.txt file included.
#include <algorithm>
-#include <boost/optional.hpp>
+#include <optional>
#include "common/alignment.h"
#include "common/assert.h"
@@ -134,7 +134,7 @@ void NVFlinger::Compose() {
MicroProfileFlip();
- if (buffer == boost::none) {
+ if (!buffer) {
auto& system_instance = Core::System::GetInstance();
// There was no queued buffer to draw, render previous frame
@@ -143,7 +143,7 @@ void NVFlinger::Compose() {
continue;
}
- auto& igbp_buffer = buffer->igbp_buffer;
+ auto& igbp_buffer = buffer->get().igbp_buffer;
// Now send the buffer to the GPU for drawing.
// TODO(Subv): Support more than just disp0. The display device selection is probably based
@@ -152,10 +152,10 @@ void NVFlinger::Compose() {
ASSERT(nvdisp);
nvdisp->flip(igbp_buffer.gpu_buffer_id, igbp_buffer.offset, igbp_buffer.format,
- igbp_buffer.width, igbp_buffer.height, igbp_buffer.stride, buffer->transform,
- buffer->crop_rect);
+ igbp_buffer.width, igbp_buffer.height, igbp_buffer.stride,
+ buffer->get().transform, buffer->get().crop_rect);
- buffer_queue->ReleaseBuffer(buffer->slot);
+ buffer_queue->ReleaseBuffer(buffer->get().slot);
}
}
diff --git a/src/core/hle/service/spl/module.cpp b/src/core/hle/service/spl/module.cpp
index 44a6717d0..69c260408 100644
--- a/src/core/hle/service/spl/module.cpp
+++ b/src/core/hle/service/spl/module.cpp
@@ -3,18 +3,23 @@
// Refer to the license.txt file included.
#include <algorithm>
+#include <chrono>
#include <cstdlib>
+#include <ctime>
+#include <functional>
#include <vector>
#include "common/logging/log.h"
#include "core/hle/ipc_helpers.h"
#include "core/hle/service/spl/csrng.h"
#include "core/hle/service/spl/module.h"
#include "core/hle/service/spl/spl.h"
+#include "core/settings.h"
namespace Service::SPL {
Module::Interface::Interface(std::shared_ptr<Module> module, const char* name)
- : ServiceFramework(name), module(std::move(module)) {}
+ : ServiceFramework(name), module(std::move(module)),
+ rng(Settings::values.rng_seed.value_or(std::time(nullptr))) {}
Module::Interface::~Interface() = default;
@@ -24,7 +29,7 @@ void Module::Interface::GetRandomBytes(Kernel::HLERequestContext& ctx) {
std::size_t size = ctx.GetWriteBufferSize();
std::vector<u8> data(size);
- std::generate(data.begin(), data.end(), std::rand);
+ std::generate(data.begin(), data.end(), rng);
ctx.WriteBuffer(data);
diff --git a/src/core/hle/service/spl/module.h b/src/core/hle/service/spl/module.h
index 48fda6099..afa1f0295 100644
--- a/src/core/hle/service/spl/module.h
+++ b/src/core/hle/service/spl/module.h
@@ -4,6 +4,7 @@
#pragma once
+#include <random>
#include "core/hle/service/service.h"
namespace Service::SPL {
@@ -19,6 +20,9 @@ public:
protected:
std::shared_ptr<Module> module;
+
+ private:
+ std::mt19937 rng;
};
};
diff --git a/src/core/hle/service/time/interface.cpp b/src/core/hle/service/time/interface.cpp
index 18a5d71d5..e3cbd7004 100644
--- a/src/core/hle/service/time/interface.cpp
+++ b/src/core/hle/service/time/interface.cpp
@@ -21,7 +21,7 @@ Time::Time(std::shared_ptr<Module> time, const char* name)
{102, nullptr, "GetStandardUserSystemClockInitialYear"},
{200, nullptr, "IsStandardNetworkSystemClockAccuracySufficient"},
{300, nullptr, "CalculateMonotonicSystemClockBaseTimePoint"},
- {400, nullptr, "GetClockSnapshot"},
+ {400, &Time::GetClockSnapshot, "GetClockSnapshot"},
{401, nullptr, "GetClockSnapshotFromSystemClockContext"},
{500, nullptr, "CalculateStandardUserSystemClockDifferenceByUser"},
{501, nullptr, "CalculateSpanBetween"},
diff --git a/src/core/hle/service/time/time.cpp b/src/core/hle/service/time/time.cpp
index 28fd8debc..85e7b1195 100644
--- a/src/core/hle/service/time/time.cpp
+++ b/src/core/hle/service/time/time.cpp
@@ -15,6 +15,44 @@
namespace Service::Time {
+static void PosixToCalendar(u64 posix_time, CalendarTime& calendar_time,
+ CalendarAdditionalInfo& additional_info,
+ [[maybe_unused]] const TimeZoneRule& /*rule*/) {
+ const std::time_t time(posix_time);
+ const std::tm* tm = std::localtime(&time);
+ if (tm == nullptr) {
+ calendar_time = {};
+ additional_info = {};
+ return;
+ }
+ calendar_time.year = tm->tm_year + 1900;
+ calendar_time.month = tm->tm_mon + 1;
+ calendar_time.day = tm->tm_mday;
+ calendar_time.hour = tm->tm_hour;
+ calendar_time.minute = tm->tm_min;
+ calendar_time.second = tm->tm_sec;
+
+ additional_info.day_of_week = tm->tm_wday;
+ additional_info.day_of_year = tm->tm_yday;
+ std::memcpy(additional_info.name.data(), "UTC", sizeof("UTC"));
+ additional_info.utc_offset = 0;
+}
+
+static u64 CalendarToPosix(const CalendarTime& calendar_time,
+ [[maybe_unused]] const TimeZoneRule& /*rule*/) {
+ std::tm time{};
+ time.tm_year = calendar_time.year - 1900;
+ time.tm_mon = calendar_time.month - 1;
+ time.tm_mday = calendar_time.day;
+
+ time.tm_hour = calendar_time.hour;
+ time.tm_min = calendar_time.minute;
+ time.tm_sec = calendar_time.second;
+
+ std::time_t epoch_time = std::mktime(&time);
+ return static_cast<u64>(epoch_time);
+}
+
class ISystemClock final : public ServiceFramework<ISystemClock> {
public:
ISystemClock() : ServiceFramework("ISystemClock") {
@@ -80,8 +118,8 @@ public:
{5, nullptr, "GetTimeZoneRuleVersion"},
{100, &ITimeZoneService::ToCalendarTime, "ToCalendarTime"},
{101, &ITimeZoneService::ToCalendarTimeWithMyRule, "ToCalendarTimeWithMyRule"},
- {201, nullptr, "ToPosixTime"},
- {202, nullptr, "ToPosixTimeWithMyRule"},
+ {201, &ITimeZoneService::ToPosixTime, "ToPosixTime"},
+ {202, &ITimeZoneService::ToPosixTimeWithMyRule, "ToPosixTimeWithMyRule"},
};
RegisterHandlers(functions);
}
@@ -151,24 +189,29 @@ private:
rb.PushRaw(additional_info);
}
- void PosixToCalendar(u64 posix_time, CalendarTime& calendar_time,
- CalendarAdditionalInfo& additional_info, const TimeZoneRule& /*rule*/) {
- std::time_t t(posix_time);
- std::tm* tm = std::localtime(&t);
- if (!tm) {
- return;
- }
- calendar_time.year = tm->tm_year + 1900;
- calendar_time.month = tm->tm_mon + 1;
- calendar_time.day = tm->tm_mday;
- calendar_time.hour = tm->tm_hour;
- calendar_time.minute = tm->tm_min;
- calendar_time.second = tm->tm_sec;
-
- additional_info.day_of_week = tm->tm_wday;
- additional_info.day_of_year = tm->tm_yday;
- std::memcpy(additional_info.name.data(), "UTC", sizeof("UTC"));
- additional_info.utc_offset = 0;
+ void ToPosixTime(Kernel::HLERequestContext& ctx) {
+ // TODO(ogniK): Figure out how to handle multiple times
+ LOG_WARNING(Service_Time, "(STUBBED) called");
+ IPC::RequestParser rp{ctx};
+ auto calendar_time = rp.PopRaw<CalendarTime>();
+ auto posix_time = CalendarToPosix(calendar_time, {});
+
+ IPC::ResponseBuilder rb{ctx, 3};
+ rb.Push(RESULT_SUCCESS);
+ rb.PushRaw<u32>(1); // Amount of times we're returning
+ ctx.WriteBuffer(&posix_time, sizeof(u64));
+ }
+
+ void ToPosixTimeWithMyRule(Kernel::HLERequestContext& ctx) {
+ LOG_WARNING(Service_Time, "(STUBBED) called");
+ IPC::RequestParser rp{ctx};
+ auto calendar_time = rp.PopRaw<CalendarTime>();
+ auto posix_time = CalendarToPosix(calendar_time, {});
+
+ IPC::ResponseBuilder rb{ctx, 3};
+ rb.Push(RESULT_SUCCESS);
+ rb.PushRaw<u32>(1); // Amount of times we're returning
+ ctx.WriteBuffer(&posix_time, sizeof(u64));
}
};
@@ -207,6 +250,55 @@ void Module::Interface::GetStandardLocalSystemClock(Kernel::HLERequestContext& c
LOG_DEBUG(Service_Time, "called");
}
+void Module::Interface::GetClockSnapshot(Kernel::HLERequestContext& ctx) {
+ LOG_DEBUG(Service_Time, "called");
+
+ IPC::RequestParser rp{ctx};
+ auto unknown_u8 = rp.PopRaw<u8>();
+
+ ClockSnapshot clock_snapshot{};
+
+ const s64 time_since_epoch{std::chrono::duration_cast<std::chrono::seconds>(
+ std::chrono::system_clock::now().time_since_epoch())
+ .count()};
+ CalendarTime calendar_time{};
+ const std::time_t time(time_since_epoch);
+ const std::tm* tm = std::localtime(&time);
+ if (tm == nullptr) {
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultCode(-1)); // TODO(ogniK): Find appropriate error code
+ return;
+ }
+ SteadyClockTimePoint steady_clock_time_point{CoreTiming::cyclesToMs(CoreTiming::GetTicks()) /
+ 1000};
+
+ LocationName location_name{"UTC"};
+ calendar_time.year = tm->tm_year + 1900;
+ calendar_time.month = tm->tm_mon + 1;
+ calendar_time.day = tm->tm_mday;
+ calendar_time.hour = tm->tm_hour;
+ calendar_time.minute = tm->tm_min;
+ calendar_time.second = tm->tm_sec;
+ clock_snapshot.system_posix_time = time_since_epoch;
+ clock_snapshot.network_posix_time = time_since_epoch;
+ clock_snapshot.system_calendar_time = calendar_time;
+ clock_snapshot.network_calendar_time = calendar_time;
+
+ CalendarAdditionalInfo additional_info{};
+ PosixToCalendar(time_since_epoch, calendar_time, additional_info, {});
+
+ clock_snapshot.system_calendar_info = additional_info;
+ clock_snapshot.network_calendar_info = additional_info;
+
+ clock_snapshot.steady_clock_timepoint = steady_clock_time_point;
+ clock_snapshot.location_name = location_name;
+ clock_snapshot.clock_auto_adjustment_enabled = 1;
+ clock_snapshot.ipc_u8 = unknown_u8;
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(RESULT_SUCCESS);
+ ctx.WriteBuffer(&clock_snapshot, sizeof(ClockSnapshot));
+}
+
Module::Interface::Interface(std::shared_ptr<Module> time, const char* name)
: ServiceFramework(name), time(std::move(time)) {}
diff --git a/src/core/hle/service/time/time.h b/src/core/hle/service/time/time.h
index 5659ecad3..77871ae07 100644
--- a/src/core/hle/service/time/time.h
+++ b/src/core/hle/service/time/time.h
@@ -5,6 +5,7 @@
#pragma once
#include <array>
+#include "common/common_funcs.h"
#include "core/hle/service/service.h"
namespace Service::Time {
@@ -53,6 +54,23 @@ struct SystemClockContext {
static_assert(sizeof(SystemClockContext) == 0x20,
"SystemClockContext structure has incorrect size");
+struct ClockSnapshot {
+ SystemClockContext user_clock_context;
+ SystemClockContext network_clock_context;
+ s64_le system_posix_time;
+ s64_le network_posix_time;
+ CalendarTime system_calendar_time;
+ CalendarTime network_calendar_time;
+ CalendarAdditionalInfo system_calendar_info;
+ CalendarAdditionalInfo network_calendar_info;
+ SteadyClockTimePoint steady_clock_timepoint;
+ LocationName location_name;
+ u8 clock_auto_adjustment_enabled;
+ u8 ipc_u8;
+ INSERT_PADDING_BYTES(2);
+};
+static_assert(sizeof(ClockSnapshot) == 0xd0, "ClockSnapshot is an invalid size");
+
class Module final {
public:
class Interface : public ServiceFramework<Interface> {
@@ -65,6 +83,7 @@ public:
void GetStandardSteadyClock(Kernel::HLERequestContext& ctx);
void GetTimeZoneService(Kernel::HLERequestContext& ctx);
void GetStandardLocalSystemClock(Kernel::HLERequestContext& ctx);
+ void GetClockSnapshot(Kernel::HLERequestContext& ctx);
protected:
std::shared_ptr<Module> time;
diff --git a/src/core/hle/service/usb/usb.cpp b/src/core/hle/service/usb/usb.cpp
index c489da071..f0a831d45 100644
--- a/src/core/hle/service/usb/usb.cpp
+++ b/src/core/hle/service/usb/usb.cpp
@@ -132,11 +132,11 @@ public:
// clang-format off
static const FunctionInfo functions[] = {
{0, nullptr, "BindNoticeEvent"},
- {1, nullptr, "Unknown1"},
+ {1, nullptr, "UnbindNoticeEvent"},
{2, nullptr, "GetStatus"},
{3, nullptr, "GetNotice"},
- {4, nullptr, "Unknown2"},
- {5, nullptr, "Unknown3"},
+ {4, nullptr, "EnablePowerRequestNotice"},
+ {5, nullptr, "DisablePowerRequestNotice"},
{6, nullptr, "ReplyPowerRequest"},
};
// clang-format on
diff --git a/src/core/hle/service/vi/vi.cpp b/src/core/hle/service/vi/vi.cpp
index 184537daa..d764b2406 100644
--- a/src/core/hle/service/vi/vi.cpp
+++ b/src/core/hle/service/vi/vi.cpp
@@ -6,9 +6,10 @@
#include <array>
#include <cstring>
#include <memory>
+#include <optional>
#include <type_traits>
#include <utility>
-#include <boost/optional.hpp>
+
#include "common/alignment.h"
#include "common/assert.h"
#include "common/common_funcs.h"
@@ -506,9 +507,9 @@ private:
IGBPDequeueBufferRequestParcel request{ctx.ReadBuffer()};
const u32 width{request.data.width};
const u32 height{request.data.height};
- boost::optional<u32> slot = buffer_queue->DequeueBuffer(width, height);
+ std::optional<u32> slot = buffer_queue->DequeueBuffer(width, height);
- if (slot != boost::none) {
+ if (slot) {
// Buffer is available
IGBPDequeueBufferResponseParcel response{*slot};
ctx.WriteBuffer(response.Serialize());
@@ -520,7 +521,7 @@ private:
Kernel::ThreadWakeupReason reason) {
// Repeat TransactParcel DequeueBuffer when a buffer is available
auto buffer_queue = nv_flinger->GetBufferQueue(id);
- boost::optional<u32> slot = buffer_queue->DequeueBuffer(width, height);
+ std::optional<u32> slot = buffer_queue->DequeueBuffer(width, height);
IGBPDequeueBufferResponseParcel response{*slot};
ctx.WriteBuffer(response.Serialize());
IPC::ResponseBuilder rb{ctx, 2};
diff --git a/src/core/loader/loader.h b/src/core/loader/loader.h
index e562b3a04..7686634bf 100644
--- a/src/core/loader/loader.h
+++ b/src/core/loader/loader.h
@@ -6,10 +6,11 @@
#include <iosfwd>
#include <memory>
+#include <optional>
#include <string>
#include <utility>
#include <vector>
-#include <boost/optional.hpp>
+
#include "common/common_types.h"
#include "core/file_sys/vfs.h"
@@ -145,7 +146,7 @@ public:
* information.
* @returns A pair with the optional system mode, and and the status.
*/
- virtual std::pair<boost::optional<u32>, ResultStatus> LoadKernelSystemMode() {
+ virtual std::pair<std::optional<u32>, ResultStatus> LoadKernelSystemMode() {
// 96MB allocated to the application.
return std::make_pair(2, ResultStatus::Success);
}
diff --git a/src/core/memory.cpp b/src/core/memory.cpp
index 014298ed6..70abd856a 100644
--- a/src/core/memory.cpp
+++ b/src/core/memory.cpp
@@ -4,9 +4,9 @@
#include <algorithm>
#include <cstring>
+#include <optional>
#include <utility>
-#include <boost/optional.hpp>
#include "common/assert.h"
#include "common/common_types.h"
#include "common/logging/log.h"
diff --git a/src/core/memory_hook.h b/src/core/memory_hook.h
index 0269c7ff1..940777107 100644
--- a/src/core/memory_hook.h
+++ b/src/core/memory_hook.h
@@ -5,7 +5,8 @@
#pragma once
#include <memory>
-#include <boost/optional.hpp>
+#include <optional>
+
#include "common/common_types.h"
namespace Memory {
@@ -18,19 +19,19 @@ namespace Memory {
*
* A hook may be mapped to multiple regions of memory.
*
- * If a boost::none or false is returned from a function, the read/write request is passed through
+ * If a std::nullopt or false is returned from a function, the read/write request is passed through
* to the underlying memory region.
*/
class MemoryHook {
public:
virtual ~MemoryHook();
- virtual boost::optional<bool> IsValidAddress(VAddr addr) = 0;
+ virtual std::optional<bool> IsValidAddress(VAddr addr) = 0;
- virtual boost::optional<u8> Read8(VAddr addr) = 0;
- virtual boost::optional<u16> Read16(VAddr addr) = 0;
- virtual boost::optional<u32> Read32(VAddr addr) = 0;
- virtual boost::optional<u64> Read64(VAddr addr) = 0;
+ virtual std::optional<u8> Read8(VAddr addr) = 0;
+ virtual std::optional<u16> Read16(VAddr addr) = 0;
+ virtual std::optional<u32> Read32(VAddr addr) = 0;
+ virtual std::optional<u64> Read64(VAddr addr) = 0;
virtual bool ReadBlock(VAddr src_addr, void* dest_buffer, std::size_t size) = 0;
diff --git a/src/core/settings.h b/src/core/settings.h
index b5aeff29b..83a1a7069 100644
--- a/src/core/settings.h
+++ b/src/core/settings.h
@@ -6,6 +6,7 @@
#include <array>
#include <atomic>
+#include <optional>
#include <string>
#include "common/common_types.h"
@@ -114,8 +115,9 @@ struct Values {
// System
bool use_docked_mode;
bool enable_nfc;
- int current_user;
- int language_index;
+ std::optional<u64> rng_seed;
+ s32 current_user;
+ s32 language_index;
// Controls
std::array<std::string, NativeButton::NumButtons> buttons;
diff --git a/src/core/telemetry_session.cpp b/src/core/telemetry_session.cpp
index 0de13edd3..a3b08c740 100644
--- a/src/core/telemetry_session.cpp
+++ b/src/core/telemetry_session.cpp
@@ -184,4 +184,13 @@ TelemetrySession::~TelemetrySession() {
backend = nullptr;
}
+bool TelemetrySession::SubmitTestcase() {
+#ifdef ENABLE_WEB_SERVICE
+ field_collection.Accept(*backend);
+ return backend->SubmitTestcase();
+#else
+ return false;
+#endif
+}
+
} // namespace Core
diff --git a/src/core/telemetry_session.h b/src/core/telemetry_session.h
index 2a4845797..023612b79 100644
--- a/src/core/telemetry_session.h
+++ b/src/core/telemetry_session.h
@@ -31,6 +31,12 @@ public:
field_collection.AddField(type, name, std::move(value));
}
+ /**
+ * Submits a Testcase.
+ * @returns A bool indicating whether the submission succeeded
+ */
+ bool SubmitTestcase();
+
private:
Telemetry::FieldCollection field_collection; ///< Tracks all added fields for the session
std::unique_ptr<Telemetry::VisitorInterface> backend; ///< Backend interface that logs fields