diff options
Diffstat (limited to 'src/core')
50 files changed, 426 insertions, 213 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..7e8e87c33 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp @@ -395,16 +395,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 +459,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 +468,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(); @@ -572,7 +600,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/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..a8954647f 100644 --- a/src/core/settings.h +++ b/src/core/settings.h @@ -114,8 +114,8 @@ struct Values {      // System      bool use_docked_mode;      bool enable_nfc; -    int current_user; -    int language_index; +    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  | 
