diff options
23 files changed, 216 insertions, 90 deletions
diff --git a/externals/dynarmic b/externals/dynarmic -Subproject 959446573f3adfcba173ef4b0011a4a280f18eb +Subproject 171d11659d760a4d4674d3a90698fe31ea407e2 diff --git a/src/core/arm/dynarmic/arm_dynarmic.cpp b/src/core/arm/dynarmic/arm_dynarmic.cpp index 3f072c51f..32cd5746e 100644 --- a/src/core/arm/dynarmic/arm_dynarmic.cpp +++ b/src/core/arm/dynarmic/arm_dynarmic.cpp @@ -12,6 +12,7 @@ #include "core/core.h" #include "core/core_cpu.h" #include "core/core_timing.h" +#include "core/gdbstub/gdbstub.h" #include "core/hle/kernel/process.h" #include "core/hle/kernel/svc.h" #include "core/memory.h" @@ -79,6 +80,17 @@ public: case Dynarmic::A64::Exception::SendEventLocal: case Dynarmic::A64::Exception::Yield: return; + case Dynarmic::A64::Exception::Breakpoint: + if (GDBStub::IsServerEnabled()) { + parent.jit->HaltExecution(); + parent.SetPC(pc); + Kernel::Thread* thread = Kernel::GetCurrentThread(); + parent.SaveContext(thread->context); + GDBStub::Break(); + GDBStub::SendTrap(thread, 5); + return; + } + [[fallthrough]]; default: ASSERT_MSG(false, "ExceptionRaised(exception = {}, pc = {:X})", static_cast<std::size_t>(exception), pc); diff --git a/src/core/file_sys/control_metadata.cpp b/src/core/file_sys/control_metadata.cpp index e76bf77bf..f11b91399 100644 --- a/src/core/file_sys/control_metadata.cpp +++ b/src/core/file_sys/control_metadata.cpp @@ -8,6 +8,14 @@ namespace FileSys { +const std::array<const char*, 15> LANGUAGE_NAMES = { + "AmericanEnglish", "BritishEnglish", "Japanese", + "French", "German", "LatinAmericanSpanish", + "Spanish", "Italian", "Dutch", + "CanadianFrench", "Portugese", "Russian", + "Korean", "Taiwanese", "Chinese", +}; + std::string LanguageEntry::GetApplicationName() const { return Common::StringFromFixedZeroTerminatedBuffer(application_name.data(), 0x200); } @@ -23,15 +31,15 @@ NACP::NACP(VirtualFile file) : raw(std::make_unique<RawNACP>()) { const LanguageEntry& NACP::GetLanguageEntry(Language language) const { if (language != Language::Default) { return raw->language_entries.at(static_cast<u8>(language)); - } else { - for (const auto& language_entry : raw->language_entries) { - if (!language_entry.GetApplicationName().empty()) - return language_entry; - } - - // Fallback to English - return GetLanguageEntry(Language::AmericanEnglish); } + + for (const auto& language_entry : raw->language_entries) { + if (!language_entry.GetApplicationName().empty()) + return language_entry; + } + + // Fallback to English + return GetLanguageEntry(Language::AmericanEnglish); } std::string NACP::GetApplicationName(Language language) const { diff --git a/src/core/file_sys/control_metadata.h b/src/core/file_sys/control_metadata.h index 8a510bf46..319bae821 100644 --- a/src/core/file_sys/control_metadata.h +++ b/src/core/file_sys/control_metadata.h @@ -66,12 +66,7 @@ enum class Language : u8 { Default = 255, }; -static constexpr std::array<const char*, 15> LANGUAGE_NAMES = { - "AmericanEnglish", "BritishEnglish", "Japanese", - "French", "German", "LatinAmericanSpanish", - "Spanish", "Italian", "Dutch", - "CanadianFrench", "Portugese", "Russian", - "Korean", "Taiwanese", "Chinese"}; +extern const std::array<const char*, 15> LANGUAGE_NAMES; // A class representing the format used by NX metadata files, typically named Control.nacp. // These store application name, dev name, title id, and other miscellaneous data. diff --git a/src/core/file_sys/savedata_factory.cpp b/src/core/file_sys/savedata_factory.cpp index e437d34e5..cddb014fc 100644 --- a/src/core/file_sys/savedata_factory.cpp +++ b/src/core/file_sys/savedata_factory.cpp @@ -85,10 +85,10 @@ std::string SaveDataFactory::GetFullPath(SaveDataSpaceId space, SaveDataType typ switch (space) { case SaveDataSpaceId::NandSystem: - out = "/system/save/"; + out = "/system/"; break; case SaveDataSpaceId::NandUser: - out = "/user/save/"; + out = "/user/"; break; default: ASSERT_MSG(false, "Unrecognized SaveDataSpaceId: {:02X}", static_cast<u8>(space)); @@ -96,9 +96,12 @@ std::string SaveDataFactory::GetFullPath(SaveDataSpaceId space, SaveDataType typ switch (type) { case SaveDataType::SystemSaveData: - return fmt::format("{}{:016X}/{:016X}{:016X}", out, save_id, user_id[1], user_id[0]); + return fmt::format("{}save/{:016X}/{:016X}{:016X}", out, save_id, user_id[1], user_id[0]); case SaveDataType::SaveData: - return fmt::format("{}{:016X}/{:016X}{:016X}/{:016X}", out, 0, user_id[1], user_id[0], + return fmt::format("{}save/{:016X}/{:016X}{:016X}/{:016X}", out, 0, user_id[1], user_id[0], + title_id); + case SaveDataType::TemporaryStorage: + return fmt::format("{}temp/{:016X}/{:016X}{:016X}/{:016X}", out, 0, user_id[1], user_id[0], title_id); default: ASSERT_MSG(false, "Unrecognized SaveDataType: {:02X}", static_cast<u8>(type)); diff --git a/src/core/file_sys/xts_archive.cpp b/src/core/file_sys/xts_archive.cpp index 0173f71c1..e937d1403 100644 --- a/src/core/file_sys/xts_archive.cpp +++ b/src/core/file_sys/xts_archive.cpp @@ -30,9 +30,6 @@ static bool CalculateHMAC256(Destination* out, const SourceKey* key, std::size_t mbedtls_md_context_t context; mbedtls_md_init(&context); - const auto key_f = reinterpret_cast<const u8*>(key); - const std::vector<u8> key_v(key_f, key_f + key_length); - if (mbedtls_md_setup(&context, mbedtls_md_info_from_type(MBEDTLS_MD_SHA256), 1) || mbedtls_md_hmac_starts(&context, reinterpret_cast<const u8*>(key), key_length) || mbedtls_md_hmac_update(&context, reinterpret_cast<const u8*>(data), data_length) || @@ -45,7 +42,7 @@ static bool CalculateHMAC256(Destination* out, const SourceKey* key, std::size_t return true; } -NAX::NAX(VirtualFile file_) : file(std::move(file_)), header(std::make_unique<NAXHeader>()) { +NAX::NAX(VirtualFile file_) : header(std::make_unique<NAXHeader>()), file(std::move(file_)) { std::string path = FileUtil::SanitizePath(file->GetFullPath()); static const std::regex nax_path_regex("/registered/(000000[0-9A-F]{2})/([0-9A-F]{32})\\.nca", std::regex_constants::ECMAScript | @@ -65,7 +62,7 @@ NAX::NAX(VirtualFile file_) : file(std::move(file_)), header(std::make_unique<NA } NAX::NAX(VirtualFile file_, std::array<u8, 0x10> nca_id) - : file(std::move(file_)), header(std::make_unique<NAXHeader>()) { + : header(std::make_unique<NAXHeader>()), file(std::move(file_)) { Core::Crypto::SHA256Hash hash{}; mbedtls_sha256(nca_id.data(), nca_id.size(), hash.data(), 0); status = Parse(fmt::format("/registered/000000{:02X}/{}.nca", hash[0], @@ -138,9 +135,9 @@ VirtualFile NAX::GetDecrypted() const { return dec_file; } -std::shared_ptr<NCA> NAX::AsNCA() const { +std::unique_ptr<NCA> NAX::AsNCA() const { if (type == NAXContentType::NCA) - return std::make_shared<NCA>(GetDecrypted()); + return std::make_unique<NCA>(GetDecrypted()); return nullptr; } diff --git a/src/core/file_sys/xts_archive.h b/src/core/file_sys/xts_archive.h index 55d2154a6..6e2fc4d2e 100644 --- a/src/core/file_sys/xts_archive.h +++ b/src/core/file_sys/xts_archive.h @@ -38,7 +38,7 @@ public: VirtualFile GetDecrypted() const; - std::shared_ptr<NCA> AsNCA() const; + std::unique_ptr<NCA> AsNCA() const; NAXContentType GetContentType() const; @@ -60,7 +60,7 @@ private: VirtualFile file; Loader::ResultStatus status; - NAXContentType type; + NAXContentType type{}; VirtualFile dec_file; diff --git a/src/core/gdbstub/gdbstub.cpp b/src/core/gdbstub/gdbstub.cpp index 1b04f68bf..0ecdd9f82 100644 --- a/src/core/gdbstub/gdbstub.cpp +++ b/src/core/gdbstub/gdbstub.cpp @@ -995,7 +995,7 @@ static bool CommitBreakpoint(BreakpointType type, VAddr addr, u64 len) { breakpoint.addr = addr; breakpoint.len = len; Memory::ReadBlock(addr, breakpoint.inst.data(), breakpoint.inst.size()); - static constexpr std::array<u8, 4> btrap{{0xd4, 0x20, 0x7d, 0x0}}; + static constexpr std::array<u8, 4> btrap{{0x00, 0x7d, 0x20, 0xd4}}; Memory::WriteBlock(addr, btrap.data(), btrap.size()); Core::System::GetInstance().InvalidateCpuInstructionCaches(); p.insert({addr, breakpoint}); diff --git a/src/core/hle/ipc_helpers.h b/src/core/hle/ipc_helpers.h index 7545ecf2a..a4bfe2eb0 100644 --- a/src/core/hle/ipc_helpers.h +++ b/src/core/hle/ipc_helpers.h @@ -290,13 +290,6 @@ public: Skip(CommandIdSize, false); } - ResponseBuilder MakeBuilder(u32 normal_params_size, u32 num_handles_to_copy, - u32 num_handles_to_move, - ResponseBuilder::Flags flags = ResponseBuilder::Flags::None) const { - return ResponseBuilder{*context, normal_params_size, num_handles_to_copy, - num_handles_to_move, flags}; - } - template <typename T> T Pop(); diff --git a/src/core/hle/service/acc/acc.cpp b/src/core/hle/service/acc/acc.cpp index 4d4eb542e..e61748ca3 100644 --- a/src/core/hle/service/acc/acc.cpp +++ b/src/core/hle/service/acc/acc.cpp @@ -130,11 +130,10 @@ private: void GetAccountId(Kernel::HLERequestContext& ctx) { LOG_WARNING(Service_ACC, "(STUBBED) called"); - // TODO(Subv): Find out what this actually does and implement it. Stub it as an error for - // now since we do not implement NNID. Returning a bogus id here will cause games to send - // invalid IPC requests after ListOpenUsers is called. - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ResultCode(-1)); + // Should return a nintendo account ID + IPC::ResponseBuilder rb{ctx, 4}; + rb.Push(RESULT_SUCCESS); + rb.PushRaw<u64>(1); } }; diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp index 9c975325a..69bfce1c1 100644 --- a/src/core/hle/service/am/am.cpp +++ b/src/core/hle/service/am/am.cpp @@ -462,7 +462,7 @@ private: std::memcpy(&buffer[offset], data.data(), data.size()); - IPC::ResponseBuilder rb{rp.MakeBuilder(2, 0, 0)}; + IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); LOG_DEBUG(Service_AM, "called, offset={}", offset); @@ -478,7 +478,7 @@ private: ctx.WriteBuffer(buffer.data() + offset, size); - IPC::ResponseBuilder rb{rp.MakeBuilder(2, 0, 0)}; + IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); LOG_DEBUG(Service_AM, "called, offset={}", offset); @@ -568,7 +568,7 @@ private: IPC::RequestParser rp{ctx}; storage_stack.push(rp.PopIpcInterface<AM::IStorage>()); - IPC::ResponseBuilder rb{rp.MakeBuilder(2, 0, 0)}; + IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); LOG_DEBUG(Service_AM, "called"); @@ -616,7 +616,7 @@ void ILibraryAppletCreator::CreateStorage(Kernel::HLERequestContext& ctx) { const u64 size{rp.Pop<u64>()}; std::vector<u8> buffer(size); - IPC::ResponseBuilder rb{rp.MakeBuilder(2, 0, 1)}; + IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(RESULT_SUCCESS); rb.PushIpcInterface<AM::IStorage>(std::move(buffer)); diff --git a/src/core/hle/service/audio/audout_u.cpp b/src/core/hle/service/audio/audout_u.cpp index 80a002322..ff1edefbb 100644 --- a/src/core/hle/service/audio/audout_u.cpp +++ b/src/core/hle/service/audio/audout_u.cpp @@ -190,7 +190,7 @@ void AudOutU::ListAudioOutsImpl(Kernel::HLERequestContext& ctx) { ctx.WriteBuffer(DefaultDevice); - IPC::ResponseBuilder rb = rp.MakeBuilder(3, 0, 0); + IPC::ResponseBuilder rb{ctx, 3}; rb.Push(RESULT_SUCCESS); rb.Push<u32>(1); // Amount of audio devices diff --git a/src/core/hle/service/audio/audren_u.cpp b/src/core/hle/service/audio/audren_u.cpp index e84c4fa2b..06ac6372d 100644 --- a/src/core/hle/service/audio/audren_u.cpp +++ b/src/core/hle/service/audio/audren_u.cpp @@ -137,7 +137,7 @@ private: constexpr std::array<char, 15> audio_interface{{"AudioInterface"}}; ctx.WriteBuffer(audio_interface); - IPC::ResponseBuilder rb = rp.MakeBuilder(3, 0, 0); + IPC::ResponseBuilder rb{ctx, 3}; rb.Push(RESULT_SUCCESS); rb.Push<u32>(1); } @@ -151,7 +151,7 @@ private: auto file_buffer = ctx.ReadBuffer(); auto end = std::find(file_buffer.begin(), file_buffer.end(), '\0'); - IPC::ResponseBuilder rb = rp.MakeBuilder(2, 0, 0); + IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); } @@ -162,7 +162,7 @@ private: constexpr std::array<char, 12> audio_interface{{"AudioDevice"}}; ctx.WriteBuffer(audio_interface); - IPC::ResponseBuilder rb = rp.MakeBuilder(3, 0, 0); + IPC::ResponseBuilder rb{ctx, 3}; rb.Push(RESULT_SUCCESS); rb.Push<u32>(1); } diff --git a/src/core/hle/service/filesystem/filesystem.cpp b/src/core/hle/service/filesystem/filesystem.cpp index 5c4971724..d349ee686 100644 --- a/src/core/hle/service/filesystem/filesystem.cpp +++ b/src/core/hle/service/filesystem/filesystem.cpp @@ -197,7 +197,7 @@ ResultVal<FileSys::VirtualDir> VfsDirectoryServiceWrapper::OpenDirectory(const s auto dir = GetDirectoryRelativeWrapped(backing, path); if (dir == nullptr) { // TODO(DarkLordZach): Find a better error code for this - return ResultCode(-1); + return FileSys::ERROR_PATH_NOT_FOUND; } return MakeResult(dir); } diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp index 256c49bfc..7c6b0a4e6 100644 --- a/src/core/hle/service/hid/hid.cpp +++ b/src/core/hle/service/hid/hid.cpp @@ -338,7 +338,7 @@ public: {106, &Hid::AcquireNpadStyleSetUpdateEventHandle, "AcquireNpadStyleSetUpdateEventHandle"}, {107, &Hid::DisconnectNpad, "DisconnectNpad"}, {108, &Hid::GetPlayerLedPattern, "GetPlayerLedPattern"}, - {109, nullptr, "ActivateNpadWithRevision"}, + {109, &Hid::ActivateNpadWithRevision, "ActivateNpadWithRevision"}, {120, &Hid::SetNpadJoyHoldType, "SetNpadJoyHoldType"}, {121, &Hid::GetNpadJoyHoldType, "GetNpadJoyHoldType"}, {122, &Hid::SetNpadJoyAssignmentModeSingleByDefault, "SetNpadJoyAssignmentModeSingleByDefault"}, @@ -603,6 +603,12 @@ private: rb.Push(RESULT_SUCCESS); LOG_WARNING(Service_HID, "(STUBBED) called"); } + + void ActivateNpadWithRevision(Kernel::HLERequestContext& ctx) { + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(RESULT_SUCCESS); + LOG_WARNING(Service_HID, "(STUBBED) called"); + } }; class HidDbg final : public ServiceFramework<HidDbg> { diff --git a/src/core/hle/service/nifm/nifm.cpp b/src/core/hle/service/nifm/nifm.cpp index ed4f5f539..eda910bbe 100644 --- a/src/core/hle/service/nifm/nifm.cpp +++ b/src/core/hle/service/nifm/nifm.cpp @@ -114,10 +114,11 @@ public: private: void GetClientId(Kernel::HLERequestContext& ctx) { + static constexpr u32 client_id = 1; LOG_WARNING(Service_NIFM, "(STUBBED) called"); IPC::ResponseBuilder rb{ctx, 4}; rb.Push(RESULT_SUCCESS); - rb.Push<u64>(0); + rb.Push<u64>(client_id); // Client ID needs to be non zero otherwise it's considered invalid } void CreateScanRequest(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 2, 0, 1}; @@ -141,10 +142,16 @@ private: rb.Push(RESULT_SUCCESS); } void CreateTemporaryNetworkProfile(Kernel::HLERequestContext& ctx) { - IPC::ResponseBuilder rb{ctx, 2, 0, 1}; + ASSERT_MSG(ctx.GetReadBufferSize() == 0x17c, "NetworkProfileData is not the correct size"); + u128 uuid{}; + auto buffer = ctx.ReadBuffer(); + std::memcpy(&uuid, buffer.data() + 8, sizeof(u128)); + + IPC::ResponseBuilder rb{ctx, 6, 0, 1}; rb.Push(RESULT_SUCCESS); rb.PushIpcInterface<INetworkProfile>(); + rb.PushRaw<u128>(uuid); LOG_DEBUG(Service_NIFM, "called"); } diff --git a/src/core/hle/service/nim/nim.cpp b/src/core/hle/service/nim/nim.cpp index bd05b0a70..c1737defa 100644 --- a/src/core/hle/service/nim/nim.cpp +++ b/src/core/hle/service/nim/nim.cpp @@ -2,6 +2,10 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include <chrono> +#include <ctime> +#include "core/hle/ipc_helpers.h" +#include "core/hle/kernel/event.h" #include "core/hle/service/nim/nim.h" #include "core/hle/service/service.h" #include "core/hle/service/sm/sm.h" @@ -100,19 +104,111 @@ public: } }; +class IEnsureNetworkClockAvailabilityService final + : public ServiceFramework<IEnsureNetworkClockAvailabilityService> { +public: + IEnsureNetworkClockAvailabilityService() + : ServiceFramework("IEnsureNetworkClockAvailabilityService") { + static const FunctionInfo functions[] = { + {0, &IEnsureNetworkClockAvailabilityService::StartTask, "StartTask"}, + {1, &IEnsureNetworkClockAvailabilityService::GetFinishNotificationEvent, + "GetFinishNotificationEvent"}, + {2, &IEnsureNetworkClockAvailabilityService::GetResult, "GetResult"}, + {3, &IEnsureNetworkClockAvailabilityService::Cancel, "Cancel"}, + {4, &IEnsureNetworkClockAvailabilityService::IsProcessing, "IsProcessing"}, + {5, &IEnsureNetworkClockAvailabilityService::GetServerTime, "GetServerTime"}, + }; + RegisterHandlers(functions); + + auto& kernel = Core::System::GetInstance().Kernel(); + finished_event = + Kernel::Event::Create(kernel, Kernel::ResetType::OneShot, + "IEnsureNetworkClockAvailabilityService:FinishEvent"); + } + +private: + Kernel::SharedPtr<Kernel::Event> finished_event; + + void StartTask(Kernel::HLERequestContext& ctx) { + // No need to connect to the internet, just finish the task straight away. + finished_event->Signal(); + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(RESULT_SUCCESS); + LOG_DEBUG(Service_NIM, "called"); + } + + void GetFinishNotificationEvent(Kernel::HLERequestContext& ctx) { + IPC::ResponseBuilder rb{ctx, 2, 1}; + rb.Push(RESULT_SUCCESS); + rb.PushCopyObjects(finished_event); + LOG_DEBUG(Service_NIM, "called"); + } + + void GetResult(Kernel::HLERequestContext& ctx) { + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(RESULT_SUCCESS); + LOG_DEBUG(Service_NIM, "called"); + } + + void Cancel(Kernel::HLERequestContext& ctx) { + finished_event->Clear(); + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(RESULT_SUCCESS); + LOG_DEBUG(Service_NIM, "called"); + } + + void IsProcessing(Kernel::HLERequestContext& ctx) { + IPC::ResponseBuilder rb{ctx, 3}; + rb.Push(RESULT_SUCCESS); + rb.PushRaw<u32>(0); // We instantly process the request + LOG_DEBUG(Service_NIM, "called"); + } + + void GetServerTime(Kernel::HLERequestContext& ctx) { + const s64 server_time{std::chrono::duration_cast<std::chrono::seconds>( + std::chrono::system_clock::now().time_since_epoch()) + .count()}; + IPC::ResponseBuilder rb{ctx, 4}; + rb.Push(RESULT_SUCCESS); + rb.PushRaw<s64>(server_time); + LOG_DEBUG(Service_NIM, "called"); + } +}; + class NTC final : public ServiceFramework<NTC> { public: explicit NTC() : ServiceFramework{"ntc"} { // clang-format off static const FunctionInfo functions[] = { - {0, nullptr, "OpenEnsureNetworkClockAvailabilityService"}, - {100, nullptr, "SuspendAutonomicTimeCorrection"}, - {101, nullptr, "ResumeAutonomicTimeCorrection"}, + {0, &NTC::OpenEnsureNetworkClockAvailabilityService, "OpenEnsureNetworkClockAvailabilityService"}, + {100, &NTC::SuspendAutonomicTimeCorrection, "SuspendAutonomicTimeCorrection"}, + {101, &NTC::ResumeAutonomicTimeCorrection, "ResumeAutonomicTimeCorrection"}, }; // clang-format on RegisterHandlers(functions); } + +private: + void OpenEnsureNetworkClockAvailabilityService(Kernel::HLERequestContext& ctx) { + IPC::ResponseBuilder rb{ctx, 2, 0, 1}; + rb.Push(RESULT_SUCCESS); + rb.PushIpcInterface<IEnsureNetworkClockAvailabilityService>(); + LOG_DEBUG(Service_NIM, "called"); + } + + // TODO(ogniK): Do we need these? + void SuspendAutonomicTimeCorrection(Kernel::HLERequestContext& ctx) { + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(RESULT_SUCCESS); + LOG_WARNING(Service_NIM, "(STUBBED) called"); + } + + void ResumeAutonomicTimeCorrection(Kernel::HLERequestContext& ctx) { + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(RESULT_SUCCESS); + LOG_WARNING(Service_NIM, "(STUBBED) called"); + } }; void InstallInterfaces(SM::ServiceManager& sm) { diff --git a/src/core/hle/service/sm/sm.cpp b/src/core/hle/service/sm/sm.cpp index 096f0fd52..464e79d01 100644 --- a/src/core/hle/service/sm/sm.cpp +++ b/src/core/hle/service/sm/sm.cpp @@ -108,7 +108,7 @@ void SM::GetService(Kernel::HLERequestContext& ctx) { auto client_port = service_manager->GetServicePort(name); if (client_port.Failed()) { - IPC::ResponseBuilder rb = rp.MakeBuilder(2, 0, 0); + IPC::ResponseBuilder rb{ctx, 2}; rb.Push(client_port.Code()); LOG_ERROR(Service_SM, "called service={} -> error 0x{:08X}", name, client_port.Code().raw); if (name.length() == 0) @@ -121,8 +121,7 @@ void SM::GetService(Kernel::HLERequestContext& ctx) { ASSERT(session.Succeeded()); if (session.Succeeded()) { LOG_DEBUG(Service_SM, "called service={} -> session={}", name, (*session)->GetObjectId()); - IPC::ResponseBuilder rb = - rp.MakeBuilder(2, 0, 1, IPC::ResponseBuilder::Flags::AlwaysMoveHandles); + IPC::ResponseBuilder rb{ctx, 2, 0, 1, IPC::ResponseBuilder::Flags::AlwaysMoveHandles}; rb.Push(session.Code()); rb.PushMoveObjects(std::move(session).Unwrap()); } diff --git a/src/core/hle/service/ssl/ssl.cpp b/src/core/hle/service/ssl/ssl.cpp index 63b86e099..fe0a318ee 100644 --- a/src/core/hle/service/ssl/ssl.cpp +++ b/src/core/hle/service/ssl/ssl.cpp @@ -71,7 +71,7 @@ private: LOG_WARNING(Service_SSL, "(STUBBED) called"); IPC::RequestParser rp{ctx}; - IPC::ResponseBuilder rb = rp.MakeBuilder(2, 0, 0); + IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); } diff --git a/src/core/hle/service/vi/vi.cpp b/src/core/hle/service/vi/vi.cpp index d0cde5ede..2ee60f1ec 100644 --- a/src/core/hle/service/vi/vi.cpp +++ b/src/core/hle/service/vi/vi.cpp @@ -650,7 +650,7 @@ private: u64 layer_id = rp.Pop<u64>(); u64 z_value = rp.Pop<u64>(); - IPC::ResponseBuilder rb = rp.MakeBuilder(2, 0, 0); + IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); } @@ -658,7 +658,7 @@ private: IPC::RequestParser rp{ctx}; u64 layer_id = rp.Pop<u64>(); bool visibility = rp.Pop<bool>(); - IPC::ResponseBuilder rb = rp.MakeBuilder(2, 0, 0); + IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); LOG_WARNING(Service_VI, "(STUBBED) called, layer_id=0x{:08X}, visibility={}", layer_id, visibility); @@ -747,7 +747,7 @@ private: IPC::RequestParser rp{ctx}; u64 display = rp.Pop<u64>(); - IPC::ResponseBuilder rb = rp.MakeBuilder(2, 0, 0); + IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); } @@ -761,7 +761,7 @@ private: u64 layer_id = nv_flinger->CreateLayer(display); - IPC::ResponseBuilder rb = rp.MakeBuilder(4, 0, 0); + IPC::ResponseBuilder rb{ctx, 4}; rb.Push(RESULT_SUCCESS); rb.Push(layer_id); } @@ -772,7 +772,7 @@ private: u32 stack = rp.Pop<u32>(); u64 layer_id = rp.Pop<u64>(); - IPC::ResponseBuilder rb = rp.MakeBuilder(2, 0, 0); + IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); } @@ -780,7 +780,7 @@ private: IPC::RequestParser rp{ctx}; u64 layer_id = rp.Pop<u64>(); bool visibility = rp.Pop<bool>(); - IPC::ResponseBuilder rb = rp.MakeBuilder(2, 0, 0); + IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); LOG_WARNING(Service_VI, "(STUBBED) called, layer_id=0x{:X}, visibility={}", layer_id, visibility); @@ -837,7 +837,7 @@ private: ASSERT_MSG(name == "Default", "Non-default displays aren't supported yet"); - IPC::ResponseBuilder rb = rp.MakeBuilder(4, 0, 0); + IPC::ResponseBuilder rb{ctx, 4}; rb.Push(RESULT_SUCCESS); rb.Push<u64>(nv_flinger->OpenDisplay(name)); } @@ -847,7 +847,7 @@ private: IPC::RequestParser rp{ctx}; u64 display_id = rp.Pop<u64>(); - IPC::ResponseBuilder rb = rp.MakeBuilder(2, 0, 0); + IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); } @@ -856,7 +856,7 @@ private: IPC::RequestParser rp{ctx}; u64 display_id = rp.Pop<u64>(); - IPC::ResponseBuilder rb = rp.MakeBuilder(6, 0, 0); + IPC::ResponseBuilder rb{ctx, 6}; rb.Push(RESULT_SUCCESS); if (Settings::values.use_docked_mode) { @@ -874,7 +874,7 @@ private: u32 scaling_mode = rp.Pop<u32>(); u64 unknown = rp.Pop<u64>(); - IPC::ResponseBuilder rb = rp.MakeBuilder(2, 0, 0); + IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); } @@ -882,7 +882,7 @@ private: IPC::RequestParser rp{ctx}; DisplayInfo display_info; ctx.WriteBuffer(&display_info, sizeof(DisplayInfo)); - IPC::ResponseBuilder rb = rp.MakeBuilder(4, 0, 0); + IPC::ResponseBuilder rb{ctx, 4}; rb.Push(RESULT_SUCCESS); rb.Push<u64>(1); LOG_WARNING(Service_VI, "(STUBBED) called"); @@ -903,7 +903,7 @@ private: u32 buffer_queue_id = nv_flinger->GetBufferQueueId(display_id, layer_id); NativeWindow native_window{buffer_queue_id}; - IPC::ResponseBuilder rb = rp.MakeBuilder(4, 0, 0); + IPC::ResponseBuilder rb{ctx, 4}; rb.Push(RESULT_SUCCESS); rb.Push<u64>(ctx.WriteBuffer(native_window.Serialize())); } @@ -922,7 +922,7 @@ private: u32 buffer_queue_id = nv_flinger->GetBufferQueueId(display_id, layer_id); NativeWindow native_window{buffer_queue_id}; - IPC::ResponseBuilder rb = rp.MakeBuilder(6, 0, 0); + IPC::ResponseBuilder rb{ctx, 6}; rb.Push(RESULT_SUCCESS); rb.Push(layer_id); rb.Push<u64>(ctx.WriteBuffer(native_window.Serialize())); @@ -934,7 +934,7 @@ private: IPC::RequestParser rp{ctx}; u64 layer_id = rp.Pop<u64>(); - IPC::ResponseBuilder rb = rp.MakeBuilder(2, 0, 0); + IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); } @@ -945,7 +945,7 @@ private: auto vsync_event = nv_flinger->GetVsyncEvent(display_id); - IPC::ResponseBuilder rb = rp.MakeBuilder(2, 1, 0); + IPC::ResponseBuilder rb{ctx, 2, 1}; rb.Push(RESULT_SUCCESS); rb.PushCopyObjects(vsync_event); } diff --git a/src/core/loader/nax.cpp b/src/core/loader/nax.cpp index b46d81c02..5d4380684 100644 --- a/src/core/loader/nax.cpp +++ b/src/core/loader/nax.cpp @@ -11,6 +11,20 @@ #include "core/loader/nca.h" namespace Loader { +namespace { +FileType IdentifyTypeImpl(const FileSys::NAX& nax) { + if (nax.GetStatus() != ResultStatus::Success) { + return FileType::Error; + } + + const auto nca = nax.AsNCA(); + if (nca == nullptr || nca->GetStatus() != ResultStatus::Success) { + return FileType::Error; + } + + return FileType::NAX; +} +} // Anonymous namespace AppLoader_NAX::AppLoader_NAX(FileSys::VirtualFile file) : AppLoader(file), nax(std::make_unique<FileSys::NAX>(file)), @@ -19,14 +33,12 @@ AppLoader_NAX::AppLoader_NAX(FileSys::VirtualFile file) AppLoader_NAX::~AppLoader_NAX() = default; FileType AppLoader_NAX::IdentifyType(const FileSys::VirtualFile& file) { - FileSys::NAX nax(file); - - if (nax.GetStatus() == ResultStatus::Success && nax.AsNCA() != nullptr && - nax.AsNCA()->GetStatus() == ResultStatus::Success) { - return FileType::NAX; - } + const FileSys::NAX nax(file); + return IdentifyTypeImpl(nax); +} - return FileType::Error; +FileType AppLoader_NAX::GetFileType() { + return IdentifyTypeImpl(*nax); } ResultStatus AppLoader_NAX::Load(Kernel::SharedPtr<Kernel::Process>& process) { diff --git a/src/core/loader/nax.h b/src/core/loader/nax.h index 4dbae2918..56605fe45 100644 --- a/src/core/loader/nax.h +++ b/src/core/loader/nax.h @@ -31,9 +31,7 @@ public: */ static FileType IdentifyType(const FileSys::VirtualFile& file); - FileType GetFileType() override { - return IdentifyType(file); - } + FileType GetFileType() override; ResultStatus Load(Kernel::SharedPtr<Kernel::Process>& process) override; diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 274c2dbcf..e37acbfac 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -484,8 +484,13 @@ void RasterizerOpenGL::DrawArrays() { GLintptr index_buffer_offset = 0; if (is_indexed) { MICROPROFILE_SCOPE(OpenGL_Index); - index_buffer_offset = - buffer_cache.UploadMemory(regs.index_array.StartAddress(), index_buffer_size); + + // Adjust the index buffer offset so it points to the first desired index. + auto index_start = regs.index_array.StartAddress(); + index_start += static_cast<size_t>(regs.index_array.first) * + static_cast<size_t>(regs.index_array.FormatSizeInBytes()); + + index_buffer_offset = buffer_cache.UploadMemory(index_start, index_buffer_size); } SetupShaders(); @@ -499,10 +504,6 @@ void RasterizerOpenGL::DrawArrays() { if (is_indexed) { const GLint base_vertex{static_cast<GLint>(regs.vb_element_base)}; - // Adjust the index buffer offset so it points to the first desired index. - index_buffer_offset += static_cast<GLintptr>(regs.index_array.first) * - static_cast<GLintptr>(regs.index_array.FormatSizeInBytes()); - if (gpu.state.current_instance > 0) { glDrawElementsInstancedBaseVertexBaseInstance( primitive_mode, regs.index_array.count, |