diff options
Diffstat (limited to '')
65 files changed, 649 insertions, 359 deletions
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 2ed87d3e9..c28abc24c 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -377,6 +377,8 @@ add_library(core STATIC hle/service/glue/arp.h hle/service/glue/bgtc.cpp hle/service/glue/bgtc.h + hle/service/glue/ectx.cpp + hle/service/glue/ectx.h hle/service/glue/errors.h hle/service/glue/glue.cpp hle/service/glue/glue.h diff --git a/src/core/crypto/aes_util.cpp b/src/core/crypto/aes_util.cpp index cb7506241..85a666de9 100644 --- a/src/core/crypto/aes_util.cpp +++ b/src/core/crypto/aes_util.cpp @@ -119,9 +119,9 @@ void AESCipher<Key, KeySize>::XTSTranscode(const u8* src, std::size_t size, u8* } template <typename Key, std::size_t KeySize> -void AESCipher<Key, KeySize>::SetIVImpl(const u8* data, std::size_t size) { - ASSERT_MSG((mbedtls_cipher_set_iv(&ctx->encryption_context, data, size) || - mbedtls_cipher_set_iv(&ctx->decryption_context, data, size)) == 0, +void AESCipher<Key, KeySize>::SetIV(std::span<const u8> data) { + ASSERT_MSG((mbedtls_cipher_set_iv(&ctx->encryption_context, data.data(), data.size()) || + mbedtls_cipher_set_iv(&ctx->decryption_context, data.data(), data.size())) == 0, "Failed to set IV on mbedtls ciphers."); } diff --git a/src/core/crypto/aes_util.h b/src/core/crypto/aes_util.h index e2a304186..230451b8f 100644 --- a/src/core/crypto/aes_util.h +++ b/src/core/crypto/aes_util.h @@ -5,6 +5,7 @@ #pragma once #include <memory> +#include <span> #include <type_traits> #include "common/common_types.h" #include "core/file_sys/vfs.h" @@ -33,10 +34,7 @@ public: AESCipher(Key key, Mode mode); ~AESCipher(); - template <typename ContiguousContainer> - void SetIV(const ContiguousContainer& container) { - SetIVImpl(std::data(container), std::size(container)); - } + void SetIV(std::span<const u8> data); template <typename Source, typename Dest> void Transcode(const Source* src, std::size_t size, Dest* dest, Op op) const { @@ -60,8 +58,6 @@ public: std::size_t sector_size, Op op); private: - void SetIVImpl(const u8* data, std::size_t size); - std::unique_ptr<CipherContext> ctx; }; } // namespace Core::Crypto diff --git a/src/core/file_sys/program_metadata.cpp b/src/core/file_sys/program_metadata.cpp index 9cf49bf44..83b83a044 100644 --- a/src/core/file_sys/program_metadata.cpp +++ b/src/core/file_sys/program_metadata.cpp @@ -58,7 +58,8 @@ Loader::ResultStatus ProgramMetadata::Load(VirtualFile file) { result.LoadManual( true /*is_64_bit*/, FileSys::ProgramAddressSpaceType::Is39Bit /*address_space*/, 0x2c /*main_thread_prio*/, 0 /*main_thread_core*/, 0x00100000 /*main_thread_stack_size*/, - {}, 0xFFFFFFFFFFFFFFFF /*filesystem_permissions*/, {} /*capabilities*/); + 0 /*title_id*/, 0xFFFFFFFFFFFFFFFF /*filesystem_permissions*/, + 0x1FE00000 /*system_resource_size*/, {} /*capabilities*/); return result; } @@ -66,7 +67,7 @@ Loader::ResultStatus ProgramMetadata::Load(VirtualFile file) { void ProgramMetadata::LoadManual(bool is_64_bit, ProgramAddressSpaceType address_space, s32 main_thread_prio, u32 main_thread_core, u32 main_thread_stack_size, u64 title_id, - u64 filesystem_permissions, + u64 filesystem_permissions, u32 system_resource_size, KernelCapabilityDescriptors capabilities) { npdm_header.has_64_bit_instructions.Assign(is_64_bit); npdm_header.address_space_type.Assign(address_space); @@ -75,6 +76,7 @@ void ProgramMetadata::LoadManual(bool is_64_bit, ProgramAddressSpaceType address npdm_header.main_stack_size = main_thread_stack_size; aci_header.title_id = title_id; aci_file_access.permissions = filesystem_permissions; + npdm_header.system_resource_size = system_resource_size; aci_kernel_capabilities = std ::move(capabilities); } diff --git a/src/core/file_sys/program_metadata.h b/src/core/file_sys/program_metadata.h index 455532567..1eee916be 100644 --- a/src/core/file_sys/program_metadata.h +++ b/src/core/file_sys/program_metadata.h @@ -44,6 +44,12 @@ public: ProgramMetadata(); ~ProgramMetadata(); + ProgramMetadata(const ProgramMetadata&) = default; + ProgramMetadata& operator=(const ProgramMetadata&) = default; + + ProgramMetadata(ProgramMetadata&&) = default; + ProgramMetadata& operator=(ProgramMetadata&&) = default; + /// Gets a default ProgramMetadata configuration, should only be used for homebrew formats where /// we do not have an NPDM file static ProgramMetadata GetDefault(); @@ -53,7 +59,8 @@ public: /// Load from parameters instead of NPDM file, used for KIP void LoadManual(bool is_64_bit, ProgramAddressSpaceType address_space, s32 main_thread_prio, u32 main_thread_core, u32 main_thread_stack_size, u64 title_id, - u64 filesystem_permissions, KernelCapabilityDescriptors capabilities); + u64 filesystem_permissions, u32 system_resource_size, + KernelCapabilityDescriptors capabilities); bool Is64BitProgram() const; ProgramAddressSpaceType GetAddressSpaceType() const; diff --git a/src/core/frontend/emu_window.cpp b/src/core/frontend/emu_window.cpp index 474de9206..cff49899a 100644 --- a/src/core/frontend/emu_window.cpp +++ b/src/core/frontend/emu_window.cpp @@ -60,23 +60,23 @@ EmuWindow::~EmuWindow() { * @param framebuffer_y Framebuffer y-coordinate to check * @return True if the coordinates are within the touchpad, otherwise false */ -static bool IsWithinTouchscreen(const Layout::FramebufferLayout& layout, unsigned framebuffer_x, - unsigned framebuffer_y) { +static bool IsWithinTouchscreen(const Layout::FramebufferLayout& layout, u32 framebuffer_x, + u32 framebuffer_y) { return (framebuffer_y >= layout.screen.top && framebuffer_y < layout.screen.bottom && framebuffer_x >= layout.screen.left && framebuffer_x < layout.screen.right); } -std::tuple<unsigned, unsigned> EmuWindow::ClipToTouchScreen(unsigned new_x, unsigned new_y) const { +std::pair<u32, u32> EmuWindow::ClipToTouchScreen(u32 new_x, u32 new_y) const { new_x = std::max(new_x, framebuffer_layout.screen.left); new_x = std::min(new_x, framebuffer_layout.screen.right - 1); new_y = std::max(new_y, framebuffer_layout.screen.top); new_y = std::min(new_y, framebuffer_layout.screen.bottom - 1); - return std::make_tuple(new_x, new_y); + return std::make_pair(new_x, new_y); } -void EmuWindow::TouchPressed(unsigned framebuffer_x, unsigned framebuffer_y, std::size_t id) { +void EmuWindow::TouchPressed(u32 framebuffer_x, u32 framebuffer_y, size_t id) { if (!IsWithinTouchscreen(framebuffer_layout, framebuffer_x, framebuffer_y)) { return; } @@ -95,7 +95,7 @@ void EmuWindow::TouchPressed(unsigned framebuffer_x, unsigned framebuffer_y, std touch_state->status[id] = std::make_tuple(x, y, true); } -void EmuWindow::TouchReleased(std::size_t id) { +void EmuWindow::TouchReleased(size_t id) { if (id >= touch_state->status.size()) { return; } @@ -103,20 +103,23 @@ void EmuWindow::TouchReleased(std::size_t id) { touch_state->status[id] = std::make_tuple(0.0f, 0.0f, false); } -void EmuWindow::TouchMoved(unsigned framebuffer_x, unsigned framebuffer_y, std::size_t id) { +void EmuWindow::TouchMoved(u32 framebuffer_x, u32 framebuffer_y, size_t id) { if (id >= touch_state->status.size()) { return; } - if (!std::get<2>(touch_state->status[id])) + + if (!std::get<2>(touch_state->status[id])) { return; + } - if (!IsWithinTouchscreen(framebuffer_layout, framebuffer_x, framebuffer_y)) + if (!IsWithinTouchscreen(framebuffer_layout, framebuffer_x, framebuffer_y)) { std::tie(framebuffer_x, framebuffer_y) = ClipToTouchScreen(framebuffer_x, framebuffer_y); + } TouchPressed(framebuffer_x, framebuffer_y, id); } -void EmuWindow::UpdateCurrentFramebufferLayout(unsigned width, unsigned height) { +void EmuWindow::UpdateCurrentFramebufferLayout(u32 width, u32 height) { NotifyFramebufferLayoutChanged(Layout::DefaultFrameLayout(width, height)); } diff --git a/src/core/frontend/emu_window.h b/src/core/frontend/emu_window.h index 2436c6580..076148698 100644 --- a/src/core/frontend/emu_window.h +++ b/src/core/frontend/emu_window.h @@ -82,7 +82,7 @@ public: bool fullscreen = false; int res_width = 0; int res_height = 0; - std::pair<unsigned, unsigned> min_client_area_size; + std::pair<u32, u32> min_client_area_size; }; /// Data describing host window system information @@ -119,13 +119,13 @@ public: * @param framebuffer_y Framebuffer y-coordinate that was pressed * @param id Touch event ID */ - void TouchPressed(unsigned framebuffer_x, unsigned framebuffer_y, std::size_t id); + void TouchPressed(u32 framebuffer_x, u32 framebuffer_y, size_t id); /** * Signal that a touch released event has occurred (e.g. mouse click released) * @param id Touch event ID */ - void TouchReleased(std::size_t id); + void TouchReleased(size_t id); /** * Signal that a touch movement event has occurred (e.g. mouse was moved over the emu window) @@ -133,7 +133,7 @@ public: * @param framebuffer_y Framebuffer y-coordinate * @param id Touch event ID */ - void TouchMoved(unsigned framebuffer_x, unsigned framebuffer_y, std::size_t id); + void TouchMoved(u32 framebuffer_x, u32 framebuffer_y, size_t id); /** * Returns currently active configuration. @@ -173,7 +173,7 @@ public: * Convenience method to update the current frame layout * Read from the current settings to determine which layout to use. */ - void UpdateCurrentFramebufferLayout(unsigned width, unsigned height); + void UpdateCurrentFramebufferLayout(u32 width, u32 height); protected: explicit EmuWindow(); @@ -208,7 +208,7 @@ protected: * Update internal client area size with the given parameter. * @note EmuWindow implementations will usually use this in window resize event handlers. */ - void NotifyClientAreaSizeChanged(const std::pair<unsigned, unsigned>& size) { + void NotifyClientAreaSizeChanged(std::pair<u32, u32> size) { client_area_width = size.first; client_area_height = size.second; } @@ -221,14 +221,19 @@ private: * For the request to be honored, EmuWindow implementations will usually reimplement this * function. */ - virtual void OnMinimalClientAreaChangeRequest(std::pair<unsigned, unsigned>) { + virtual void OnMinimalClientAreaChangeRequest(std::pair<u32, u32>) { // By default, ignore this request and do nothing. } + /** + * Clip the provided coordinates to be inside the touchscreen area. + */ + std::pair<u32, u32> ClipToTouchScreen(u32 new_x, u32 new_y) const; + Layout::FramebufferLayout framebuffer_layout; ///< Current framebuffer layout - unsigned client_area_width; ///< Current client width, should be set by window impl. - unsigned client_area_height; ///< Current client height, should be set by window impl. + u32 client_area_width; ///< Current client width, should be set by window impl. + u32 client_area_height; ///< Current client height, should be set by window impl. WindowConfig config; ///< Internal configuration (changes pending for being applied in /// ProcessConfigurationChanges) @@ -236,11 +241,6 @@ private: class TouchState; std::shared_ptr<TouchState> touch_state; - - /** - * Clip the provided coordinates to be inside the touchscreen area. - */ - std::tuple<unsigned, unsigned> ClipToTouchScreen(unsigned new_x, unsigned new_y) const; }; } // namespace Core::Frontend diff --git a/src/core/hle/service/acc/acc.cpp b/src/core/hle/service/acc/acc.cpp index 52535ecc0..5450dcf0f 100644 --- a/src/core/hle/service/acc/acc.cpp +++ b/src/core/hle/service/acc/acc.cpp @@ -702,16 +702,12 @@ void Module::Interface::IsUserRegistrationRequestPermitted(Kernel::HLERequestCon } void Module::Interface::InitializeApplicationInfo(Kernel::HLERequestContext& ctx) { - IPC::RequestParser rp{ctx}; - LOG_DEBUG(Service_ACC, "called"); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(InitializeApplicationInfoBase()); } void Module::Interface::InitializeApplicationInfoRestricted(Kernel::HLERequestContext& ctx) { - IPC::RequestParser rp{ctx}; - LOG_WARNING(Service_ACC, "(Partial implementation) called"); // TODO(ogniK): We require checking if the user actually owns the title and what not. As of diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp index 4c8216b47..58c7f2930 100644 --- a/src/core/hle/service/am/am.cpp +++ b/src/core/hle/service/am/am.cpp @@ -687,7 +687,7 @@ ICommonStateGetter::ICommonStateGetter(Core::System& system_, {501, nullptr, "SuppressDisablingSleepTemporarily"}, {502, nullptr, "IsSleepEnabled"}, {503, nullptr, "IsDisablingSleepSuppressed"}, - {900, nullptr, "SetRequestExitToLibraryAppletAtExecuteNextProgramEnabled"}, + {900, &ICommonStateGetter::SetRequestExitToLibraryAppletAtExecuteNextProgramEnabled, "SetRequestExitToLibraryAppletAtExecuteNextProgramEnabled"}, }; // clang-format on @@ -817,6 +817,14 @@ void ICommonStateGetter::SetCpuBoostMode(Kernel::HLERequestContext& ctx) { apm_sys->SetCpuBoostMode(ctx); } +void ICommonStateGetter::SetRequestExitToLibraryAppletAtExecuteNextProgramEnabled( + Kernel::HLERequestContext& ctx) { + LOG_WARNING(Service_AM, "(STUBBED) called"); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(RESULT_SUCCESS); +} + IStorageImpl::~IStorageImpl() = default; class StorageDataImpl final : public IStorageImpl { diff --git a/src/core/hle/service/am/am.h b/src/core/hle/service/am/am.h index 756434716..5d302e155 100644 --- a/src/core/hle/service/am/am.h +++ b/src/core/hle/service/am/am.h @@ -196,6 +196,7 @@ private: void EndVrModeEx(Kernel::HLERequestContext& ctx); void GetDefaultDisplayResolution(Kernel::HLERequestContext& ctx); void SetCpuBoostMode(Kernel::HLERequestContext& ctx); + void SetRequestExitToLibraryAppletAtExecuteNextProgramEnabled(Kernel::HLERequestContext& ctx); std::shared_ptr<AppletMessageQueue> msg_queue; bool vr_mode_state{}; diff --git a/src/core/hle/service/am/applets/error.cpp b/src/core/hle/service/am/applets/error.cpp index 23e30aa45..0dd6ec68e 100644 --- a/src/core/hle/service/am/applets/error.cpp +++ b/src/core/hle/service/am/applets/error.cpp @@ -158,11 +158,11 @@ void Error::Execute() { break; case ErrorAppletMode::ShowSystemError: case ErrorAppletMode::ShowApplicationError: { - const auto system = mode == ErrorAppletMode::ShowSystemError; + const auto is_system = mode == ErrorAppletMode::ShowSystemError; const auto& main_text = - system ? args->system_error.main_text : args->application_error.main_text; + is_system ? args->system_error.main_text : args->application_error.main_text; const auto& detail_text = - system ? args->system_error.detail_text : args->application_error.detail_text; + is_system ? args->system_error.detail_text : args->application_error.detail_text; const auto main_text_string = Common::StringFromFixedZeroTerminatedBuffer(main_text.data(), main_text.size()); diff --git a/src/core/hle/service/am/applets/general_backend.cpp b/src/core/hle/service/am/applets/general_backend.cpp index b26abad36..b7483261e 100644 --- a/src/core/hle/service/am/applets/general_backend.cpp +++ b/src/core/hle/service/am/applets/general_backend.cpp @@ -96,7 +96,7 @@ void Auth::Execute() { switch (type) { case AuthAppletType::ShowParentalAuthentication: { - const auto callback = [this](bool successful) { AuthFinished(successful); }; + const auto callback = [this](bool is_successful) { AuthFinished(is_successful); }; if (arg0 == 1 && arg1 == 0 && arg2 == 1) { // ShowAuthenticatorForConfiguration diff --git a/src/core/hle/service/bcat/backend/boxcat.cpp b/src/core/hle/service/bcat/backend/boxcat.cpp index 78c047bd2..cee1774d1 100644 --- a/src/core/hle/service/bcat/backend/boxcat.cpp +++ b/src/core/hle/service/bcat/backend/boxcat.cpp @@ -415,9 +415,9 @@ std::optional<std::vector<u8>> Boxcat::GetLaunchParameter(TitleIDVersion title) if (Settings::values.bcat_boxcat_local) { LOG_INFO(Service_BCAT, "Boxcat using local data by override, skipping download."); } else { - Boxcat::Client client{path, title.title_id, title.build_id}; + Client launch_client{path, title.title_id, title.build_id}; - const auto res = client.DownloadLaunchParam(); + const auto res = launch_client.DownloadLaunchParam(); if (res != DownloadResult::Success) { LOG_ERROR(Service_BCAT, "Boxcat synchronization failed with error '{}'!", res); diff --git a/src/core/hle/service/bcat/module.cpp b/src/core/hle/service/bcat/module.cpp index c7dd04a6e..285085f2a 100644 --- a/src/core/hle/service/bcat/module.cpp +++ b/src/core/hle/service/bcat/module.cpp @@ -174,9 +174,9 @@ private: }; std::shared_ptr<IDeliveryCacheProgressService> CreateProgressService(SyncType type) { - auto& backend{progress.at(static_cast<std::size_t>(type))}; - return std::make_shared<IDeliveryCacheProgressService>(system, backend.GetEvent(), - backend.GetImpl()); + auto& progress_backend{GetProgressBackend(type)}; + return std::make_shared<IDeliveryCacheProgressService>(system, progress_backend.GetEvent(), + progress_backend.GetImpl()); } void RequestSyncDeliveryCache(Kernel::HLERequestContext& ctx) { @@ -184,7 +184,7 @@ private: backend.Synchronize({system.CurrentProcess()->GetTitleID(), GetCurrentBuildID(system.GetCurrentProcessBuildID())}, - progress.at(static_cast<std::size_t>(SyncType::Normal))); + GetProgressBackend(SyncType::Normal)); IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(RESULT_SUCCESS); @@ -201,8 +201,7 @@ private: backend.SynchronizeDirectory({system.CurrentProcess()->GetTitleID(), GetCurrentBuildID(system.GetCurrentProcessBuildID())}, - name, - progress.at(static_cast<std::size_t>(SyncType::Directory))); + name, GetProgressBackend(SyncType::Directory)); IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(RESULT_SUCCESS); @@ -265,9 +264,16 @@ private: rb.Push(RESULT_SUCCESS); } - Backend& backend; + ProgressServiceBackend& GetProgressBackend(SyncType type) { + return progress.at(static_cast<size_t>(type)); + } - std::array<ProgressServiceBackend, static_cast<std::size_t>(SyncType::Count)> progress; + const ProgressServiceBackend& GetProgressBackend(SyncType type) const { + return progress.at(static_cast<size_t>(type)); + } + + Backend& backend; + std::array<ProgressServiceBackend, static_cast<size_t>(SyncType::Count)> progress; }; void Module::Interface::CreateBcatService(Kernel::HLERequestContext& ctx) { diff --git a/src/core/hle/service/filesystem/fsp_srv.cpp b/src/core/hle/service/filesystem/fsp_srv.cpp index a0215c4d7..7dc487e48 100644 --- a/src/core/hle/service/filesystem/fsp_srv.cpp +++ b/src/core/hle/service/filesystem/fsp_srv.cpp @@ -337,13 +337,14 @@ public: const auto file_buffer = ctx.ReadBuffer(); const std::string name = Common::StringFromBuffer(file_buffer); - const u64 mode = rp.Pop<u64>(); - const u32 size = rp.Pop<u32>(); + const u64 file_mode = rp.Pop<u64>(); + const u32 file_size = rp.Pop<u32>(); - LOG_DEBUG(Service_FS, "called. file={}, mode=0x{:X}, size=0x{:08X}", name, mode, size); + LOG_DEBUG(Service_FS, "called. file={}, mode=0x{:X}, size=0x{:08X}", name, file_mode, + file_size); IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(backend.CreateFile(name, size)); + rb.Push(backend.CreateFile(name, file_size)); } void DeleteFile(Kernel::HLERequestContext& ctx) { @@ -935,8 +936,8 @@ void FSP_SRV::ReadSaveDataFileSystemExtraDataWithMaskBySaveDataAttribute( void FSP_SRV::OpenDataStorageByCurrentProcess(Kernel::HLERequestContext& ctx) { LOG_DEBUG(Service_FS, "called"); - auto romfs = fsc.OpenRomFSCurrentProcess(); - if (romfs.Failed()) { + auto current_romfs = fsc.OpenRomFSCurrentProcess(); + if (current_romfs.Failed()) { // TODO (bunnei): Find the right error code to use here LOG_CRITICAL(Service_FS, "no file system interface available!"); IPC::ResponseBuilder rb{ctx, 2}; @@ -944,7 +945,7 @@ void FSP_SRV::OpenDataStorageByCurrentProcess(Kernel::HLERequestContext& ctx) { return; } - auto storage = std::make_shared<IStorage>(system, std::move(romfs.Unwrap())); + auto storage = std::make_shared<IStorage>(system, std::move(current_romfs.Unwrap())); IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(RESULT_SUCCESS); @@ -1010,10 +1011,10 @@ void FSP_SRV::OpenDataStorageWithProgramIndex(Kernel::HLERequestContext& ctx) { LOG_DEBUG(Service_FS, "called, program_index={}", program_index); - auto romfs = fsc.OpenPatchedRomFSWithProgramIndex( + auto patched_romfs = fsc.OpenPatchedRomFSWithProgramIndex( system.CurrentProcess()->GetTitleID(), program_index, FileSys::ContentRecordType::Program); - if (romfs.Failed()) { + if (patched_romfs.Failed()) { // TODO: Find the right error code to use here LOG_ERROR(Service_FS, "could not open storage with program_index={}", program_index); @@ -1022,7 +1023,7 @@ void FSP_SRV::OpenDataStorageWithProgramIndex(Kernel::HLERequestContext& ctx) { return; } - auto storage = std::make_shared<IStorage>(system, std::move(romfs.Unwrap())); + auto storage = std::make_shared<IStorage>(system, std::move(patched_romfs.Unwrap())); IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(RESULT_SUCCESS); diff --git a/src/core/hle/service/glue/ectx.cpp b/src/core/hle/service/glue/ectx.cpp new file mode 100644 index 000000000..249c6f003 --- /dev/null +++ b/src/core/hle/service/glue/ectx.cpp @@ -0,0 +1,22 @@ +// Copyright 2021 yuzu Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include "core/hle/service/glue/ectx.h" + +namespace Service::Glue { + +ECTX_AW::ECTX_AW(Core::System& system_) : ServiceFramework{system_, "ectx:aw"} { + // clang-format off + static const FunctionInfo functions[] = { + {0, nullptr, "CreateContextRegistrar"}, + {1, nullptr, "CommitContext"}, + }; + // clang-format on + + RegisterHandlers(functions); +} + +ECTX_AW::~ECTX_AW() = default; + +} // namespace Service::Glue diff --git a/src/core/hle/service/glue/ectx.h b/src/core/hle/service/glue/ectx.h new file mode 100644 index 000000000..b275e808a --- /dev/null +++ b/src/core/hle/service/glue/ectx.h @@ -0,0 +1,21 @@ +// Copyright 2021 yuzu Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +#include "core/hle/service/service.h" + +namespace Core { +class System; +} + +namespace Service::Glue { + +class ECTX_AW final : public ServiceFramework<ECTX_AW> { +public: + explicit ECTX_AW(Core::System& system_); + ~ECTX_AW() override; +}; + +} // namespace Service::Glue diff --git a/src/core/hle/service/glue/glue.cpp b/src/core/hle/service/glue/glue.cpp index 4eafbe5fa..a08dc9758 100644 --- a/src/core/hle/service/glue/glue.cpp +++ b/src/core/hle/service/glue/glue.cpp @@ -6,6 +6,7 @@ #include "core/core.h" #include "core/hle/service/glue/arp.h" #include "core/hle/service/glue/bgtc.h" +#include "core/hle/service/glue/ectx.h" #include "core/hle/service/glue/glue.h" namespace Service::Glue { @@ -20,6 +21,9 @@ void InstallInterfaces(Core::System& system) { // BackGround Task Controller std::make_shared<BGTC_T>(system)->InstallAsService(system.ServiceManager()); std::make_shared<BGTC_SC>(system)->InstallAsService(system.ServiceManager()); + + // Error Context + std::make_shared<ECTX_AW>(system)->InstallAsService(system.ServiceManager()); } } // namespace Service::Glue diff --git a/src/core/hle/service/lbl/lbl.cpp b/src/core/hle/service/lbl/lbl.cpp index f4490f3d9..e11a0c45a 100644 --- a/src/core/hle/service/lbl/lbl.cpp +++ b/src/core/hle/service/lbl/lbl.cpp @@ -79,7 +79,6 @@ private: } void GetCurrentBrightnessSetting(Kernel::HLERequestContext& ctx) { - IPC::RequestParser rp{ctx}; auto brightness = current_brightness; if (!std::isfinite(brightness)) { LOG_ERROR(Service_LBL, "Brightness is infinite!"); @@ -272,7 +271,6 @@ private: } void GetCurrentBrightnessSettingForVrMode(Kernel::HLERequestContext& ctx) { - IPC::RequestParser rp{ctx}; auto brightness = current_vr_brightness; if (!std::isfinite(brightness)) { LOG_ERROR(Service_LBL, "Brightness is infinite!"); diff --git a/src/core/hle/service/lm/lm.cpp b/src/core/hle/service/lm/lm.cpp index 7d7542fc2..9bcf8870d 100644 --- a/src/core/hle/service/lm/lm.cpp +++ b/src/core/hle/service/lm/lm.cpp @@ -46,7 +46,7 @@ struct hash<Service::LM::LogPacketHeaderEntry> { boost::hash_combine(seed, k.severity); boost::hash_combine(seed, k.verbosity); return seed; - }; + } }; } // namespace std @@ -95,7 +95,7 @@ private: std::memcpy(&header, data.data(), sizeof(LogPacketHeader)); offset += sizeof(LogPacketHeader); - LogPacketHeaderEntry entry{ + const LogPacketHeaderEntry entry{ .pid = header.pid, .tid = header.tid, .severity = header.severity, @@ -105,16 +105,17 @@ private: if (True(header.flags & LogPacketFlags::Head)) { std::vector<u8> tmp(data.size() - sizeof(LogPacketHeader)); std::memcpy(tmp.data(), data.data() + offset, tmp.size()); - entries[entry] = std::move(tmp); + entries.insert_or_assign(entry, std::move(tmp)); } else { + const auto entry_iter = entries.find(entry); + // Append to existing entry - if (!entries.contains(entry)) { + if (entry_iter == entries.cend()) { LOG_ERROR(Service_LM, "Log entry does not exist!"); return; } - std::vector<u8> tmp(data.size() - sizeof(LogPacketHeader)); - auto& existing_entry = entries[entry]; + auto& existing_entry = entry_iter->second; const auto base = existing_entry.size(); existing_entry.resize(base + (data.size() - sizeof(LogPacketHeader))); std::memcpy(existing_entry.data() + base, data.data() + offset, diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp index 4e58b9b80..e2f671d8e 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp @@ -31,9 +31,8 @@ NvResult nvhost_nvdec::Ioctl1(DeviceFD fd, Ioctl command, const std::vector<u8>& return SetSubmitTimeout(input, output); case 0x9: return MapBuffer(input, output); - case 0xa: { + case 0xa: return UnmapBuffer(input, output); - } default: break; } @@ -67,7 +66,8 @@ NvResult nvhost_nvdec::Ioctl3(DeviceFD fd, Ioctl command, const std::vector<u8>& void nvhost_nvdec::OnOpen(DeviceFD fd) {} void nvhost_nvdec::OnClose(DeviceFD fd) { - system.GPU().ClearCommandBuffer(); + LOG_INFO(Service_NVDRV, "NVDEC video stream ended"); + system.GPU().ClearCdmaInstance(); } } // namespace Service::Nvidia::Devices diff --git a/src/core/hle/service/nvdrv/devices/nvhost_vic.cpp b/src/core/hle/service/nvdrv/devices/nvhost_vic.cpp index 0421fb956..301efe8a1 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_vic.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_vic.cpp @@ -29,13 +29,8 @@ NvResult nvhost_vic::Ioctl1(DeviceFD fd, Ioctl command, const std::vector<u8>& i return GetWaitbase(input, output); case 0x9: return MapBuffer(input, output); - case 0xa: { - if (command.length == 0x1c) { - Tegra::ChCommandHeaderList cmdlist{{0xDEADB33F}}; - system.GPU().PushCommandBuffer(cmdlist); - } + case 0xa: return UnmapBuffer(input, output); - } default: break; } @@ -69,6 +64,9 @@ NvResult nvhost_vic::Ioctl3(DeviceFD fd, Ioctl command, const std::vector<u8>& i } void nvhost_vic::OnOpen(DeviceFD fd) {} -void nvhost_vic::OnClose(DeviceFD fd) {} + +void nvhost_vic::OnClose(DeviceFD fd) { + system.GPU().ClearCdmaInstance(); +} } // namespace Service::Nvidia::Devices diff --git a/src/core/hle/service/nvflinger/nvflinger.cpp b/src/core/hle/service/nvflinger/nvflinger.cpp index 539b02bc4..c43593e7f 100644 --- a/src/core/hle/service/nvflinger/nvflinger.cpp +++ b/src/core/hle/service/nvflinger/nvflinger.cpp @@ -72,7 +72,7 @@ NVFlinger::NVFlinger(Core::System& system) : system(system) { // Schedule the screen composition events composition_event = Core::Timing::CreateEvent( "ScreenComposition", [this](std::uintptr_t, std::chrono::nanoseconds ns_late) { - const auto guard = Lock(); + const auto lock_guard = Lock(); Compose(); const auto ticks = std::chrono::nanoseconds{GetNextTicks()}; @@ -112,7 +112,7 @@ void NVFlinger::SetNVDrvInstance(std::shared_ptr<Nvidia::Module> instance) { } std::optional<u64> NVFlinger::OpenDisplay(std::string_view name) { - const auto guard = Lock(); + const auto lock_guard = Lock(); LOG_DEBUG(Service, "Opening \"{}\" display", name); @@ -131,7 +131,7 @@ std::optional<u64> NVFlinger::OpenDisplay(std::string_view name) { } std::optional<u64> NVFlinger::CreateLayer(u64 display_id) { - const auto guard = Lock(); + const auto lock_guard = Lock(); auto* const display = FindDisplay(display_id); if (display == nullptr) { @@ -147,7 +147,7 @@ std::optional<u64> NVFlinger::CreateLayer(u64 display_id) { } void NVFlinger::CloseLayer(u64 layer_id) { - const auto guard = Lock(); + const auto lock_guard = Lock(); for (auto& display : displays) { display.CloseLayer(layer_id); @@ -155,7 +155,7 @@ void NVFlinger::CloseLayer(u64 layer_id) { } std::optional<u32> NVFlinger::FindBufferQueueId(u64 display_id, u64 layer_id) const { - const auto guard = Lock(); + const auto lock_guard = Lock(); const auto* const layer = FindLayer(display_id, layer_id); if (layer == nullptr) { @@ -166,7 +166,7 @@ std::optional<u32> NVFlinger::FindBufferQueueId(u64 display_id, u64 layer_id) co } std::shared_ptr<Kernel::KReadableEvent> NVFlinger::FindVsyncEvent(u64 display_id) const { - const auto guard = Lock(); + const auto lock_guard = Lock(); auto* const display = FindDisplay(display_id); if (display == nullptr) { @@ -177,7 +177,7 @@ std::shared_ptr<Kernel::KReadableEvent> NVFlinger::FindVsyncEvent(u64 display_id } BufferQueue* NVFlinger::FindBufferQueue(u32 id) { - const auto guard = Lock(); + const auto lock_guard = Lock(); const auto itr = std::find_if(buffer_queues.begin(), buffer_queues.end(), [id](const auto& queue) { return queue->GetId() == id; }); diff --git a/src/core/hle/service/time/standard_user_system_clock_core.cpp b/src/core/hle/service/time/standard_user_system_clock_core.cpp index b9faa474e..3172acc5a 100644 --- a/src/core/hle/service/time/standard_user_system_clock_core.cpp +++ b/src/core/hle/service/time/standard_user_system_clock_core.cpp @@ -45,12 +45,12 @@ ResultCode StandardUserSystemClockCore::GetClockContext(Core::System& system, return local_system_clock_core.GetClockContext(system, context); } -ResultCode StandardUserSystemClockCore::Flush(const SystemClockContext& context) { +ResultCode StandardUserSystemClockCore::Flush(const SystemClockContext&) { UNREACHABLE(); return ERROR_NOT_IMPLEMENTED; } -ResultCode StandardUserSystemClockCore::SetClockContext(const SystemClockContext& context) { +ResultCode StandardUserSystemClockCore::SetClockContext(const SystemClockContext&) { UNREACHABLE(); return ERROR_NOT_IMPLEMENTED; } diff --git a/src/core/hle/service/time/standard_user_system_clock_core.h b/src/core/hle/service/time/standard_user_system_clock_core.h index aac44d72f..5bc8bf5c2 100644 --- a/src/core/hle/service/time/standard_user_system_clock_core.h +++ b/src/core/hle/service/time/standard_user_system_clock_core.h @@ -39,7 +39,7 @@ public: } protected: - ResultCode Flush(const SystemClockContext& context) override; + ResultCode Flush(const SystemClockContext&) override; ResultCode SetClockContext(const SystemClockContext&) override; diff --git a/src/core/hle/service/time/system_clock_core.cpp b/src/core/hle/service/time/system_clock_core.cpp index d31d4e2ca..46fc8c6c3 100644 --- a/src/core/hle/service/time/system_clock_core.cpp +++ b/src/core/hle/service/time/system_clock_core.cpp @@ -45,18 +45,18 @@ ResultCode SystemClockCore::SetCurrentTime(Core::System& system, s64 posix_time) return Flush(clock_context); } -ResultCode SystemClockCore::Flush(const SystemClockContext& context) { +ResultCode SystemClockCore::Flush(const SystemClockContext& clock_context) { if (!system_clock_context_update_callback) { return RESULT_SUCCESS; } - return system_clock_context_update_callback->Update(context); + return system_clock_context_update_callback->Update(clock_context); } -ResultCode SystemClockCore::SetSystemClockContext(const SystemClockContext& context) { - if (const ResultCode result{SetClockContext(context)}; result != RESULT_SUCCESS) { +ResultCode SystemClockCore::SetSystemClockContext(const SystemClockContext& clock_context) { + if (const ResultCode result{SetClockContext(clock_context)}; result != RESULT_SUCCESS) { return result; } - return Flush(context); + return Flush(clock_context); } bool SystemClockCore::IsClockSetup(Core::System& system) const { diff --git a/src/core/hle/service/time/system_clock_core.h b/src/core/hle/service/time/system_clock_core.h index 608dd3b2e..82a8b79ff 100644 --- a/src/core/hle/service/time/system_clock_core.h +++ b/src/core/hle/service/time/system_clock_core.h @@ -43,7 +43,7 @@ public: return RESULT_SUCCESS; } - virtual ResultCode Flush(const SystemClockContext& context); + virtual ResultCode Flush(const SystemClockContext& clock_context); void SetUpdateCallbackInstance(std::shared_ptr<SystemClockContextUpdateCallback> callback) { system_clock_context_update_callback = std::move(callback); diff --git a/src/core/hle/service/time/time_manager.cpp b/src/core/hle/service/time/time_manager.cpp index f89c5aaad..fe01a3739 100644 --- a/src/core/hle/service/time/time_manager.cpp +++ b/src/core/hle/service/time/time_manager.cpp @@ -129,7 +129,7 @@ struct TimeManager::Impl final { return 0; } - void SetupStandardSteadyClock(Core::System& system, Common::UUID clock_source_id, + void SetupStandardSteadyClock(Core::System& system_, Common::UUID clock_source_id, Clock::TimeSpanType setup_value, Clock::TimeSpanType internal_offset, bool is_rtc_reset_detected) { standard_steady_clock_core.SetClockSourceId(clock_source_id); @@ -137,21 +137,21 @@ struct TimeManager::Impl final { standard_steady_clock_core.SetInternalOffset(internal_offset); standard_steady_clock_core.MarkAsInitialized(); - const auto current_time_point{standard_steady_clock_core.GetCurrentRawTimePoint(system)}; - shared_memory.SetupStandardSteadyClock(system, clock_source_id, current_time_point); + const auto current_time_point{standard_steady_clock_core.GetCurrentRawTimePoint(system_)}; + shared_memory.SetupStandardSteadyClock(clock_source_id, current_time_point); } - void SetupStandardLocalSystemClock(Core::System& system, + void SetupStandardLocalSystemClock(Core::System& system_, Clock::SystemClockContext clock_context, s64 posix_time) { standard_local_system_clock_core.SetUpdateCallbackInstance( local_system_clock_context_writer); const auto current_time_point{ - standard_local_system_clock_core.GetSteadyClockCore().GetCurrentTimePoint(system)}; + standard_local_system_clock_core.GetSteadyClockCore().GetCurrentTimePoint(system_)}; if (current_time_point.clock_source_id == clock_context.steady_time_point.clock_source_id) { standard_local_system_clock_core.SetSystemClockContext(clock_context); } else { - if (standard_local_system_clock_core.SetCurrentTime(system, posix_time) != + if (standard_local_system_clock_core.SetCurrentTime(system_, posix_time) != RESULT_SUCCESS) { UNREACHABLE(); return; @@ -177,10 +177,10 @@ struct TimeManager::Impl final { standard_network_system_clock_core.MarkAsInitialized(); } - void SetupStandardUserSystemClock(Core::System& system, bool is_automatic_correction_enabled, + void SetupStandardUserSystemClock(Core::System& system_, bool is_automatic_correction_enabled, Clock::SteadyClockTimePoint steady_clock_time_point) { if (standard_user_system_clock_core.SetAutomaticCorrectionEnabled( - system, is_automatic_correction_enabled) != RESULT_SUCCESS) { + system_, is_automatic_correction_enabled) != RESULT_SUCCESS) { UNREACHABLE(); return; } @@ -196,10 +196,10 @@ struct TimeManager::Impl final { ephemeral_network_system_clock_core.MarkAsInitialized(); } - void UpdateLocalSystemClockTime(Core::System& system, s64 posix_time) { - const auto timespan{Service::Time::Clock::TimeSpanType::FromSeconds(posix_time)}; + void UpdateLocalSystemClockTime(Core::System& system_, s64 posix_time) { + const auto timespan{Clock::TimeSpanType::FromSeconds(posix_time)}; if (GetStandardLocalSystemClockCore() - .SetCurrentTime(system, timespan.ToSeconds()) + .SetCurrentTime(system_, timespan.ToSeconds()) .IsError()) { UNREACHABLE(); return; diff --git a/src/core/hle/service/time/time_sharedmemory.cpp b/src/core/hle/service/time/time_sharedmemory.cpp index 4d8de81be..018ce94ed 100644 --- a/src/core/hle/service/time/time_sharedmemory.cpp +++ b/src/core/hle/service/time/time_sharedmemory.cpp @@ -26,8 +26,7 @@ std::shared_ptr<Kernel::KSharedMemory> SharedMemory::GetSharedMemoryHolder() con return shared_memory_holder; } -void SharedMemory::SetupStandardSteadyClock(Core::System& system, - const Common::UUID& clock_source_id, +void SharedMemory::SetupStandardSteadyClock(const Common::UUID& clock_source_id, Clock::TimeSpanType current_time_point) { const Clock::TimeSpanType ticks_time_span{Clock::TimeSpanType::FromTicks( system.CoreTiming().GetClockTicks(), Core::Hardware::CNTFREQ)}; diff --git a/src/core/hle/service/time/time_sharedmemory.h b/src/core/hle/service/time/time_sharedmemory.h index 299680517..3bc749114 100644 --- a/src/core/hle/service/time/time_sharedmemory.h +++ b/src/core/hle/service/time/time_sharedmemory.h @@ -56,8 +56,8 @@ public: }; static_assert(sizeof(Format) == 0xd8, "Format is an invalid size"); - void SetupStandardSteadyClock(Core::System& system, const Common::UUID& clock_source_id, - Clock::TimeSpanType currentTimePoint); + void SetupStandardSteadyClock(const Common::UUID& clock_source_id, + Clock::TimeSpanType current_time_point); void UpdateLocalSystemClockContext(const Clock::SystemClockContext& context); void UpdateNetworkSystemClockContext(const Clock::SystemClockContext& context); void SetAutomaticCorrectionEnabled(bool is_enabled); diff --git a/src/core/hle/service/vi/display/vi_display.cpp b/src/core/hle/service/vi/display/vi_display.cpp index 7f42aa4a0..ac9e87338 100644 --- a/src/core/hle/service/vi/display/vi_display.cpp +++ b/src/core/hle/service/vi/display/vi_display.cpp @@ -41,24 +41,22 @@ void Display::SignalVSyncEvent() { vsync_event->GetWritableEvent()->Signal(); } -void Display::CreateLayer(u64 id, NVFlinger::BufferQueue& buffer_queue) { +void Display::CreateLayer(u64 layer_id, NVFlinger::BufferQueue& buffer_queue) { // TODO(Subv): Support more than 1 layer. ASSERT_MSG(layers.empty(), "Only one layer is supported per display at the moment"); - layers.emplace_back(std::make_shared<Layer>(id, buffer_queue)); + layers.emplace_back(std::make_shared<Layer>(layer_id, buffer_queue)); } -void Display::CloseLayer(u64 id) { - layers.erase( - std::remove_if(layers.begin(), layers.end(), - [id](const std::shared_ptr<Layer>& layer) { return layer->GetID() == id; }), - layers.end()); +void Display::CloseLayer(u64 layer_id) { + std::erase_if(layers, [layer_id](const auto& layer) { return layer->GetID() == layer_id; }); } -Layer* Display::FindLayer(u64 id) { +Layer* Display::FindLayer(u64 layer_id) { const auto itr = - std::find_if(layers.begin(), layers.end(), - [id](const std::shared_ptr<Layer>& layer) { return layer->GetID() == id; }); + std::find_if(layers.begin(), layers.end(), [layer_id](const std::shared_ptr<Layer>& layer) { + return layer->GetID() == layer_id; + }); if (itr == layers.end()) { return nullptr; @@ -67,10 +65,11 @@ Layer* Display::FindLayer(u64 id) { return itr->get(); } -const Layer* Display::FindLayer(u64 id) const { +const Layer* Display::FindLayer(u64 layer_id) const { const auto itr = - std::find_if(layers.begin(), layers.end(), - [id](const std::shared_ptr<Layer>& layer) { return layer->GetID() == id; }); + std::find_if(layers.begin(), layers.end(), [layer_id](const std::shared_ptr<Layer>& layer) { + return layer->GetID() == layer_id; + }); if (itr == layers.end()) { return nullptr; diff --git a/src/core/hle/service/vi/display/vi_display.h b/src/core/hle/service/vi/display/vi_display.h index 931c898f6..8340059de 100644 --- a/src/core/hle/service/vi/display/vi_display.h +++ b/src/core/hle/service/vi/display/vi_display.h @@ -68,34 +68,34 @@ public: /// Creates and adds a layer to this display with the given ID. /// - /// @param id The ID to assign to the created layer. + /// @param layer_id The ID to assign to the created layer. /// @param buffer_queue The buffer queue for the layer instance to use. /// - void CreateLayer(u64 id, NVFlinger::BufferQueue& buffer_queue); + void CreateLayer(u64 layer_id, NVFlinger::BufferQueue& buffer_queue); /// Closes and removes a layer from this display with the given ID. /// - /// @param id The ID assigned to the layer to close. + /// @param layer_id The ID assigned to the layer to close. /// - void CloseLayer(u64 id); + void CloseLayer(u64 layer_id); /// Attempts to find a layer with the given ID. /// - /// @param id The layer ID. + /// @param layer_id The layer ID. /// /// @returns If found, the Layer instance with the given ID. /// If not found, then nullptr is returned. /// - Layer* FindLayer(u64 id); + Layer* FindLayer(u64 layer_id); /// Attempts to find a layer with the given ID. /// - /// @param id The layer ID. + /// @param layer_id The layer ID. /// /// @returns If found, the Layer instance with the given ID. /// If not found, then nullptr is returned. /// - const Layer* FindLayer(u64 id) const; + const Layer* FindLayer(u64 layer_id) const; private: u64 id; diff --git a/src/core/loader/deconstructed_rom_directory.cpp b/src/core/loader/deconstructed_rom_directory.cpp index 4a10211f6..ed776fc49 100644 --- a/src/core/loader/deconstructed_rom_directory.cpp +++ b/src/core/loader/deconstructed_rom_directory.cpp @@ -24,10 +24,10 @@ namespace Loader { AppLoader_DeconstructedRomDirectory::AppLoader_DeconstructedRomDirectory(FileSys::VirtualFile file_, bool override_update) : AppLoader(std::move(file_)), override_update(override_update) { - const auto dir = file->GetContainingDirectory(); + const auto file_dir = file->GetContainingDirectory(); // Title ID - const auto npdm = dir->GetFile("main.npdm"); + const auto npdm = file_dir->GetFile("main.npdm"); if (npdm != nullptr) { const auto res = metadata.Load(npdm); if (res == ResultStatus::Success) @@ -37,7 +37,7 @@ AppLoader_DeconstructedRomDirectory::AppLoader_DeconstructedRomDirectory(FileSys // Icon FileSys::VirtualFile icon_file = nullptr; for (const auto& language : FileSys::LANGUAGE_NAMES) { - icon_file = dir->GetFile("icon_" + std::string(language) + ".dat"); + icon_file = file_dir->GetFile("icon_" + std::string(language) + ".dat"); if (icon_file != nullptr) { icon_data = icon_file->ReadAllBytes(); break; @@ -46,7 +46,7 @@ AppLoader_DeconstructedRomDirectory::AppLoader_DeconstructedRomDirectory(FileSys if (icon_data.empty()) { // Any png, jpeg, or bmp file - const auto& files = dir->GetFiles(); + const auto& files = file_dir->GetFiles(); const auto icon_iter = std::find_if(files.begin(), files.end(), [](const FileSys::VirtualFile& file) { return file->GetExtension() == "png" || file->GetExtension() == "jpg" || @@ -57,9 +57,9 @@ AppLoader_DeconstructedRomDirectory::AppLoader_DeconstructedRomDirectory(FileSys } // Metadata - FileSys::VirtualFile nacp_file = dir->GetFile("control.nacp"); + FileSys::VirtualFile nacp_file = file_dir->GetFile("control.nacp"); if (nacp_file == nullptr) { - const auto& files = dir->GetFiles(); + const auto& files = file_dir->GetFiles(); const auto nacp_iter = std::find_if(files.begin(), files.end(), [](const FileSys::VirtualFile& file) { return file->GetExtension() == "nacp"; @@ -200,17 +200,21 @@ AppLoader_DeconstructedRomDirectory::LoadResult AppLoader_DeconstructedRomDirect LoadParameters{metadata.GetMainThreadPriority(), metadata.GetMainThreadStackSize()}}; } -ResultStatus AppLoader_DeconstructedRomDirectory::ReadRomFS(FileSys::VirtualFile& dir) { - if (romfs == nullptr) +ResultStatus AppLoader_DeconstructedRomDirectory::ReadRomFS(FileSys::VirtualFile& out_dir) { + if (romfs == nullptr) { return ResultStatus::ErrorNoRomFS; - dir = romfs; + } + + out_dir = romfs; return ResultStatus::Success; } -ResultStatus AppLoader_DeconstructedRomDirectory::ReadIcon(std::vector<u8>& buffer) { - if (icon_data.empty()) +ResultStatus AppLoader_DeconstructedRomDirectory::ReadIcon(std::vector<u8>& out_buffer) { + if (icon_data.empty()) { return ResultStatus::ErrorNoIcon; - buffer = icon_data; + } + + out_buffer = icon_data; return ResultStatus::Success; } @@ -219,10 +223,12 @@ ResultStatus AppLoader_DeconstructedRomDirectory::ReadProgramId(u64& out_program return ResultStatus::Success; } -ResultStatus AppLoader_DeconstructedRomDirectory::ReadTitle(std::string& title) { - if (name.empty()) +ResultStatus AppLoader_DeconstructedRomDirectory::ReadTitle(std::string& out_title) { + if (name.empty()) { return ResultStatus::ErrorNoControl; - title = name; + } + + out_title = name; return ResultStatus::Success; } @@ -230,12 +236,12 @@ bool AppLoader_DeconstructedRomDirectory::IsRomFSUpdatable() const { return false; } -ResultStatus AppLoader_DeconstructedRomDirectory::ReadNSOModules(Modules& modules) { +ResultStatus AppLoader_DeconstructedRomDirectory::ReadNSOModules(Modules& out_modules) { if (!is_loaded) { return ResultStatus::ErrorNotInitialized; } - modules = this->modules; + out_modules = this->modules; return ResultStatus::Success; } diff --git a/src/core/loader/deconstructed_rom_directory.h b/src/core/loader/deconstructed_rom_directory.h index 3c968580f..c2b46e1bf 100644 --- a/src/core/loader/deconstructed_rom_directory.h +++ b/src/core/loader/deconstructed_rom_directory.h @@ -43,13 +43,13 @@ public: LoadResult Load(Kernel::Process& process, Core::System& system) override; - ResultStatus ReadRomFS(FileSys::VirtualFile& dir) override; - ResultStatus ReadIcon(std::vector<u8>& buffer) override; + ResultStatus ReadRomFS(FileSys::VirtualFile& out_dir) override; + ResultStatus ReadIcon(std::vector<u8>& out_buffer) override; ResultStatus ReadProgramId(u64& out_program_id) override; ResultStatus ReadTitle(std::string& title) override; bool IsRomFSUpdatable() const override; - ResultStatus ReadNSOModules(Modules& modules) override; + ResultStatus ReadNSOModules(Modules& out_modules) override; private: FileSys::ProgramMetadata metadata; diff --git a/src/core/loader/elf.cpp b/src/core/loader/elf.cpp index f4a339390..627c18c7e 100644 --- a/src/core/loader/elf.cpp +++ b/src/core/loader/elf.cpp @@ -364,21 +364,24 @@ SectionID ElfReader::GetSectionByName(const char* name, int firstSection) const namespace Loader { -AppLoader_ELF::AppLoader_ELF(FileSys::VirtualFile file) : AppLoader(std::move(file)) {} +AppLoader_ELF::AppLoader_ELF(FileSys::VirtualFile file_) : AppLoader(std::move(file_)) {} -FileType AppLoader_ELF::IdentifyType(const FileSys::VirtualFile& file) { +FileType AppLoader_ELF::IdentifyType(const FileSys::VirtualFile& elf_file) { static constexpr u16 ELF_MACHINE_ARM{0x28}; u32 magic = 0; - if (4 != file->ReadObject(&magic)) + if (4 != elf_file->ReadObject(&magic)) { return FileType::Error; + } u16 machine = 0; - if (2 != file->ReadObject(&machine, 18)) + if (2 != elf_file->ReadObject(&machine, 18)) { return FileType::Error; + } - if (Common::MakeMagic('\x7f', 'E', 'L', 'F') == magic && ELF_MACHINE_ARM == machine) + if (Common::MakeMagic('\x7f', 'E', 'L', 'F') == magic && ELF_MACHINE_ARM == machine) { return FileType::ELF; + } return FileType::Error; } diff --git a/src/core/loader/elf.h b/src/core/loader/elf.h index 2067932c7..2b86c0b49 100644 --- a/src/core/loader/elf.h +++ b/src/core/loader/elf.h @@ -20,11 +20,13 @@ public: explicit AppLoader_ELF(FileSys::VirtualFile file); /** - * Returns the type of the file - * @param file open file - * @return FileType found, or FileType::Error if this loader doesn't know it + * Identifies whether or not the given file is an ELF file. + * + * @param elf_file The file to identify. + * + * @return FileType::ELF, or FileType::Error if the file is not an ELF file. */ - static FileType IdentifyType(const FileSys::VirtualFile& file); + static FileType IdentifyType(const FileSys::VirtualFile& elf_file); FileType GetFileType() const override { return IdentifyType(file); diff --git a/src/core/loader/kip.cpp b/src/core/loader/kip.cpp index 3f4ba233d..9b447da2a 100644 --- a/src/core/loader/kip.cpp +++ b/src/core/loader/kip.cpp @@ -24,9 +24,9 @@ AppLoader_KIP::AppLoader_KIP(FileSys::VirtualFile file_) AppLoader_KIP::~AppLoader_KIP() = default; -FileType AppLoader_KIP::IdentifyType(const FileSys::VirtualFile& file) { +FileType AppLoader_KIP::IdentifyType(const FileSys::VirtualFile& in_file) { u32_le magic{}; - if (file->GetSize() < sizeof(u32) || file->ReadObject(&magic) != sizeof(u32)) { + if (in_file->GetSize() < sizeof(u32) || in_file->ReadObject(&magic) != sizeof(u32)) { return FileType::Error; } @@ -56,10 +56,10 @@ AppLoader::LoadResult AppLoader_KIP::Load(Kernel::Process& process, return {kip->GetStatus(), {}}; } - const auto get_kip_address_space_type = [](const auto& kip) { - return kip.Is64Bit() - ? (kip.Is39BitAddressSpace() ? FileSys::ProgramAddressSpaceType::Is39Bit - : FileSys::ProgramAddressSpaceType::Is36Bit) + const auto get_kip_address_space_type = [](const auto& kip_type) { + return kip_type.Is64Bit() + ? (kip_type.Is39BitAddressSpace() ? FileSys::ProgramAddressSpaceType::Is39Bit + : FileSys::ProgramAddressSpaceType::Is36Bit) : FileSys::ProgramAddressSpaceType::Is32Bit; }; @@ -68,7 +68,8 @@ AppLoader::LoadResult AppLoader_KIP::Load(Kernel::Process& process, FileSys::ProgramMetadata metadata; metadata.LoadManual(kip->Is64Bit(), address_space, kip->GetMainThreadPriority(), kip->GetMainThreadCpuCore(), kip->GetMainThreadStackSize(), - kip->GetTitleID(), 0xFFFFFFFFFFFFFFFF, kip->GetKernelCapabilities()); + kip->GetTitleID(), 0xFFFFFFFFFFFFFFFF, 0x1FE00000, + kip->GetKernelCapabilities()); const VAddr base_address = process.PageTable().GetCodeRegionStart(); Kernel::CodeSet codeset; diff --git a/src/core/loader/kip.h b/src/core/loader/kip.h index 14a85e295..2fe636f01 100644 --- a/src/core/loader/kip.h +++ b/src/core/loader/kip.h @@ -22,11 +22,13 @@ public: ~AppLoader_KIP() override; /** - * Returns the type of the file - * @param file open file - * @return FileType found, or FileType::Error if this loader doesn't know it + * Identifies whether or not the given file is a KIP. + * + * @param in_file The file to identify. + * + * @return FileType::KIP if found, or FileType::Error if unknown. */ - static FileType IdentifyType(const FileSys::VirtualFile& file); + static FileType IdentifyType(const FileSys::VirtualFile& in_file); FileType GetFileType() const override; diff --git a/src/core/loader/loader.h b/src/core/loader/loader.h index b2e5b13de..bf6db1ab1 100644 --- a/src/core/loader/loader.h +++ b/src/core/loader/loader.h @@ -152,21 +152,26 @@ public: /** * Returns the type of this file + * * @return FileType corresponding to the loaded file */ virtual FileType GetFileType() const = 0; /** * Load the application and return the created Process instance + * * @param process The newly created process. * @param system The system that this process is being loaded under. + * * @return The status result of the operation. */ virtual LoadResult Load(Kernel::Process& process, Core::System& system) = 0; /** * Get the code (typically .code section) of the application - * @param buffer Reference to buffer to store data + * + * @param[out] buffer Reference to buffer to store data + * * @return ResultStatus result of function */ virtual ResultStatus ReadCode(std::vector<u8>& buffer) { @@ -175,7 +180,9 @@ public: /** * Get the icon (typically icon section) of the application - * @param buffer Reference to buffer to store data + * + * @param[out] buffer Reference to buffer to store data + * * @return ResultStatus result of function */ virtual ResultStatus ReadIcon(std::vector<u8>& buffer) { @@ -186,7 +193,9 @@ public: * Get the banner (typically banner section) of the application * In the context of NX, this is the animation that displays in the bottom right of the screen * when a game boots. Stored in GIF format. - * @param buffer Reference to buffer to store data + * + * @param[out] buffer Reference to buffer to store data + * * @return ResultStatus result of function */ virtual ResultStatus ReadBanner(std::vector<u8>& buffer) { @@ -197,7 +206,9 @@ public: * Get the logo (typically logo section) of the application * In the context of NX, this is the static image that displays in the top left of the screen * when a game boots. Stored in JPEG format. - * @param buffer Reference to buffer to store data + * + * @param[out] buffer Reference to buffer to store data + * * @return ResultStatus result of function */ virtual ResultStatus ReadLogo(std::vector<u8>& buffer) { @@ -206,7 +217,9 @@ public: /** * Get the program id of the application - * @param out_program_id Reference to store program id into + * + * @param[out] out_program_id Reference to store program id into + * * @return ResultStatus result of function */ virtual ResultStatus ReadProgramId(u64& out_program_id) { @@ -216,19 +229,23 @@ public: /** * Get the RomFS of the application * Since the RomFS can be huge, we return a file reference instead of copying to a buffer - * @param file The directory containing the RomFS + * + * @param[out] out_file The directory containing the RomFS + * * @return ResultStatus result of function */ - virtual ResultStatus ReadRomFS(FileSys::VirtualFile& file) { + virtual ResultStatus ReadRomFS(FileSys::VirtualFile& out_file) { return ResultStatus::ErrorNotImplemented; } /** * Get the raw update of the application, should it come packed with one - * @param file The raw update NCA file (Program-type + * + * @param[out] out_file The raw update NCA file (Program-type) + * * @return ResultStatus result of function */ - virtual ResultStatus ReadUpdateRaw(FileSys::VirtualFile& file) { + virtual ResultStatus ReadUpdateRaw(FileSys::VirtualFile& out_file) { return ResultStatus::ErrorNotImplemented; } @@ -236,7 +253,8 @@ public: * Get whether or not updates can be applied to the RomFS. * By default, this is true, however for formats where it cannot be guaranteed that the RomFS is * the base game it should be set to false. - * @return bool whether or not updatable. + * + * @return bool indicating whether or not the RomFS is updatable. */ virtual bool IsRomFSUpdatable() const { return true; @@ -244,8 +262,9 @@ public: /** * Gets the difference between the start of the IVFC header and the start of level 6 (RomFS) - * data. Needed for bktr patching. - * @return IVFC offset for romfs. + * data. Needed for BKTR patching. + * + * @return IVFC offset for RomFS. */ virtual u64 ReadRomFSIVFCOffset() const { return 0; @@ -253,7 +272,9 @@ public: /** * Get the title of the application - * @param title Reference to store the application title into + * + * @param[out] title Reference to store the application title into + * * @return ResultStatus result of function */ virtual ResultStatus ReadTitle(std::string& title) { @@ -262,7 +283,9 @@ public: /** * Get the control data (CNMT) of the application - * @param control Reference to store the application control data into + * + * @param[out] control Reference to store the application control data into + * * @return ResultStatus result of function */ virtual ResultStatus ReadControlData(FileSys::NACP& control) { @@ -271,10 +294,12 @@ public: /** * Get the RomFS of the manual of the application - * @param file The raw manual RomFS of the game + * + * @param[out] out_file The raw manual RomFS of the game + * * @return ResultStatus result of function */ - virtual ResultStatus ReadManualRomFS(FileSys::VirtualFile& file) { + virtual ResultStatus ReadManualRomFS(FileSys::VirtualFile& out_file) { return ResultStatus::ErrorNotImplemented; } diff --git a/src/core/loader/nax.cpp b/src/core/loader/nax.cpp index 49028177b..f53c3a72c 100644 --- a/src/core/loader/nax.cpp +++ b/src/core/loader/nax.cpp @@ -26,14 +26,14 @@ FileType IdentifyTypeImpl(const FileSys::NAX& nax) { } } // Anonymous namespace -AppLoader_NAX::AppLoader_NAX(FileSys::VirtualFile file) - : AppLoader(file), nax(std::make_unique<FileSys::NAX>(file)), +AppLoader_NAX::AppLoader_NAX(FileSys::VirtualFile file_) + : AppLoader(file_), nax(std::make_unique<FileSys::NAX>(file_)), nca_loader(std::make_unique<AppLoader_NCA>(nax->GetDecrypted())) {} AppLoader_NAX::~AppLoader_NAX() = default; -FileType AppLoader_NAX::IdentifyType(const FileSys::VirtualFile& file) { - const FileSys::NAX nax(file); +FileType AppLoader_NAX::IdentifyType(const FileSys::VirtualFile& nax_file) { + const FileSys::NAX nax(nax_file); return IdentifyTypeImpl(nax); } @@ -41,8 +41,7 @@ FileType AppLoader_NAX::GetFileType() const { return IdentifyTypeImpl(*nax); } -AppLoader_NAX::LoadResult AppLoader_NAX::Load(Kernel::Process& process, - [[maybe_unused]] Core::System& system) { +AppLoader_NAX::LoadResult AppLoader_NAX::Load(Kernel::Process& process, Core::System& system) { if (is_loaded) { return {ResultStatus::ErrorAlreadyLoaded, {}}; } diff --git a/src/core/loader/nax.h b/src/core/loader/nax.h index a5b5e2ae1..68427c1cf 100644 --- a/src/core/loader/nax.h +++ b/src/core/loader/nax.h @@ -23,15 +23,17 @@ class AppLoader_NCA; /// Loads a NAX file class AppLoader_NAX final : public AppLoader { public: - explicit AppLoader_NAX(FileSys::VirtualFile file); + explicit AppLoader_NAX(FileSys::VirtualFile file_); ~AppLoader_NAX() override; /** - * Returns the type of the file - * @param file open file - * @return FileType found, or FileType::Error if this loader doesn't know it + * Identifies whether or not the given file is a NAX file. + * + * @param nax_file The file to identify. + * + * @return FileType::NAX, or FileType::Error if the file is not a NAX file. */ - static FileType IdentifyType(const FileSys::VirtualFile& file); + static FileType IdentifyType(const FileSys::VirtualFile& nax_file); FileType GetFileType() const override; diff --git a/src/core/loader/nca.cpp b/src/core/loader/nca.cpp index fa694de37..47e7a77a9 100644 --- a/src/core/loader/nca.cpp +++ b/src/core/loader/nca.cpp @@ -21,12 +21,13 @@ AppLoader_NCA::AppLoader_NCA(FileSys::VirtualFile file_) AppLoader_NCA::~AppLoader_NCA() = default; -FileType AppLoader_NCA::IdentifyType(const FileSys::VirtualFile& file) { - FileSys::NCA nca(file); +FileType AppLoader_NCA::IdentifyType(const FileSys::VirtualFile& nca_file) { + const FileSys::NCA nca(nca_file); if (nca.GetStatus() == ResultStatus::Success && - nca.GetType() == FileSys::NCAContentType::Program) + nca.GetType() == FileSys::NCAContentType::Program) { return FileType::NCA; + } return FileType::Error; } @@ -67,43 +68,59 @@ AppLoader_NCA::LoadResult AppLoader_NCA::Load(Kernel::Process& process, Core::Sy } ResultStatus AppLoader_NCA::ReadRomFS(FileSys::VirtualFile& dir) { - if (nca == nullptr) + if (nca == nullptr) { return ResultStatus::ErrorNotInitialized; - if (nca->GetRomFS() == nullptr || nca->GetRomFS()->GetSize() == 0) + } + + if (nca->GetRomFS() == nullptr || nca->GetRomFS()->GetSize() == 0) { return ResultStatus::ErrorNoRomFS; + } + dir = nca->GetRomFS(); return ResultStatus::Success; } u64 AppLoader_NCA::ReadRomFSIVFCOffset() const { - if (nca == nullptr) + if (nca == nullptr) { return 0; + } + return nca->GetBaseIVFCOffset(); } ResultStatus AppLoader_NCA::ReadProgramId(u64& out_program_id) { - if (nca == nullptr || nca->GetStatus() != ResultStatus::Success) + if (nca == nullptr || nca->GetStatus() != ResultStatus::Success) { return ResultStatus::ErrorNotInitialized; + } + out_program_id = nca->GetTitleId(); return ResultStatus::Success; } ResultStatus AppLoader_NCA::ReadBanner(std::vector<u8>& buffer) { - if (nca == nullptr || nca->GetStatus() != ResultStatus::Success) + if (nca == nullptr || nca->GetStatus() != ResultStatus::Success) { return ResultStatus::ErrorNotInitialized; + } + const auto logo = nca->GetLogoPartition(); - if (logo == nullptr) + if (logo == nullptr) { return ResultStatus::ErrorNoIcon; + } + buffer = logo->GetFile("StartupMovie.gif")->ReadAllBytes(); return ResultStatus::Success; } ResultStatus AppLoader_NCA::ReadLogo(std::vector<u8>& buffer) { - if (nca == nullptr || nca->GetStatus() != ResultStatus::Success) + if (nca == nullptr || nca->GetStatus() != ResultStatus::Success) { return ResultStatus::ErrorNotInitialized; + } + const auto logo = nca->GetLogoPartition(); - if (logo == nullptr) + if (logo == nullptr) { return ResultStatus::ErrorNoIcon; + } + buffer = logo->GetFile("NintendoLogo.png")->ReadAllBytes(); return ResultStatus::Success; } diff --git a/src/core/loader/nca.h b/src/core/loader/nca.h index 918792800..c9792f390 100644 --- a/src/core/loader/nca.h +++ b/src/core/loader/nca.h @@ -23,15 +23,17 @@ class AppLoader_DeconstructedRomDirectory; /// Loads an NCA file class AppLoader_NCA final : public AppLoader { public: - explicit AppLoader_NCA(FileSys::VirtualFile file); + explicit AppLoader_NCA(FileSys::VirtualFile file_); ~AppLoader_NCA() override; /** - * Returns the type of the file - * @param file open file - * @return FileType found, or FileType::Error if this loader doesn't know it + * Identifies whether or not the given file is an NCA file. + * + * @param nca_file The file to identify. + * + * @return FileType::NCA, or FileType::Error if the file is not an NCA file. */ - static FileType IdentifyType(const FileSys::VirtualFile& file); + static FileType IdentifyType(const FileSys::VirtualFile& nca_file); FileType GetFileType() const override { return IdentifyType(file); diff --git a/src/core/loader/nro.cpp b/src/core/loader/nro.cpp index 0115ed0c4..0597cfa60 100644 --- a/src/core/loader/nro.cpp +++ b/src/core/loader/nro.cpp @@ -72,7 +72,7 @@ struct AssetHeader { }; static_assert(sizeof(AssetHeader) == 0x38, "AssetHeader has incorrect size."); -AppLoader_NRO::AppLoader_NRO(FileSys::VirtualFile file) : AppLoader(file) { +AppLoader_NRO::AppLoader_NRO(FileSys::VirtualFile file_) : AppLoader(std::move(file_)) { NroHeader nro_header{}; if (file->ReadObject(&nro_header) != sizeof(NroHeader)) { return; @@ -114,10 +114,10 @@ AppLoader_NRO::AppLoader_NRO(FileSys::VirtualFile file) : AppLoader(file) { AppLoader_NRO::~AppLoader_NRO() = default; -FileType AppLoader_NRO::IdentifyType(const FileSys::VirtualFile& file) { +FileType AppLoader_NRO::IdentifyType(const FileSys::VirtualFile& nro_file) { // Read NSO header NroHeader nro_header{}; - if (sizeof(NroHeader) != file->ReadObject(&nro_header)) { + if (sizeof(NroHeader) != nro_file->ReadObject(&nro_header)) { return FileType::Error; } if (nro_header.magic == Common::MakeMagic('N', 'R', 'O', '0')) { @@ -130,8 +130,7 @@ static constexpr u32 PageAlignSize(u32 size) { return static_cast<u32>((size + Core::Memory::PAGE_MASK) & ~Core::Memory::PAGE_MASK); } -static bool LoadNroImpl(Kernel::Process& process, const std::vector<u8>& data, - const std::string& name) { +static bool LoadNroImpl(Kernel::Process& process, const std::vector<u8>& data) { if (data.size() < sizeof(NroHeader)) { return {}; } @@ -200,8 +199,8 @@ static bool LoadNroImpl(Kernel::Process& process, const std::vector<u8>& data, return true; } -bool AppLoader_NRO::LoadNro(Kernel::Process& process, const FileSys::VfsFile& file) { - return LoadNroImpl(process, file.ReadAllBytes(), file.GetName()); +bool AppLoader_NRO::LoadNro(Kernel::Process& process, const FileSys::VfsFile& nro_file) { + return LoadNroImpl(process, nro_file.ReadAllBytes()); } AppLoader_NRO::LoadResult AppLoader_NRO::Load(Kernel::Process& process, Core::System& system) { diff --git a/src/core/loader/nro.h b/src/core/loader/nro.h index a82b66221..20bbaeb0e 100644 --- a/src/core/loader/nro.h +++ b/src/core/loader/nro.h @@ -27,15 +27,17 @@ namespace Loader { /// Loads an NRO file class AppLoader_NRO final : public AppLoader { public: - explicit AppLoader_NRO(FileSys::VirtualFile file); + explicit AppLoader_NRO(FileSys::VirtualFile file_); ~AppLoader_NRO() override; /** - * Returns the type of the file - * @param file open file - * @return FileType found, or FileType::Error if this loader doesn't know it + * Identifies whether or not the given file is an NRO file. + * + * @param nro_file The file to identify. + * + * @return FileType::NRO, or FileType::Error if the file is not an NRO file. */ - static FileType IdentifyType(const FileSys::VirtualFile& file); + static FileType IdentifyType(const FileSys::VirtualFile& nro_file); FileType GetFileType() const override { return IdentifyType(file); @@ -51,7 +53,7 @@ public: bool IsRomFSUpdatable() const override; private: - bool LoadNro(Kernel::Process& process, const FileSys::VfsFile& file); + bool LoadNro(Kernel::Process& process, const FileSys::VfsFile& nro_file); std::vector<u8> icon_data; std::unique_ptr<FileSys::NACP> nacp; diff --git a/src/core/loader/nso.cpp b/src/core/loader/nso.cpp index 0c83dd666..f671afe02 100644 --- a/src/core/loader/nso.cpp +++ b/src/core/loader/nso.cpp @@ -56,11 +56,11 @@ bool NSOHeader::IsSegmentCompressed(size_t segment_num) const { return ((flags >> segment_num) & 1) != 0; } -AppLoader_NSO::AppLoader_NSO(FileSys::VirtualFile file) : AppLoader(std::move(file)) {} +AppLoader_NSO::AppLoader_NSO(FileSys::VirtualFile file_) : AppLoader(std::move(file_)) {} -FileType AppLoader_NSO::IdentifyType(const FileSys::VirtualFile& file) { +FileType AppLoader_NSO::IdentifyType(const FileSys::VirtualFile& in_file) { u32 magic = 0; - if (file->ReadObject(&magic) != sizeof(magic)) { + if (in_file->ReadObject(&magic) != sizeof(magic)) { return FileType::Error; } @@ -72,15 +72,15 @@ FileType AppLoader_NSO::IdentifyType(const FileSys::VirtualFile& file) { } std::optional<VAddr> AppLoader_NSO::LoadModule(Kernel::Process& process, Core::System& system, - const FileSys::VfsFile& file, VAddr load_base, + const FileSys::VfsFile& nso_file, VAddr load_base, bool should_pass_arguments, bool load_into_process, std::optional<FileSys::PatchManager> pm) { - if (file.GetSize() < sizeof(NSOHeader)) { + if (nso_file.GetSize() < sizeof(NSOHeader)) { return std::nullopt; } NSOHeader nso_header{}; - if (sizeof(NSOHeader) != file.ReadObject(&nso_header)) { + if (sizeof(NSOHeader) != nso_file.ReadObject(&nso_header)) { return std::nullopt; } @@ -92,8 +92,8 @@ std::optional<VAddr> AppLoader_NSO::LoadModule(Kernel::Process& process, Core::S Kernel::CodeSet codeset; Kernel::PhysicalMemory program_image; for (std::size_t i = 0; i < nso_header.segments.size(); ++i) { - std::vector<u8> data = - file.ReadBytes(nso_header.segments_compressed_size[i], nso_header.segments[i].offset); + std::vector<u8> data = nso_file.ReadBytes(nso_header.segments_compressed_size[i], + nso_header.segments[i].offset); if (nso_header.IsSegmentCompressed(i)) { data = DecompressSegment(data, nso_header.segments[i]); } @@ -136,7 +136,7 @@ std::optional<VAddr> AppLoader_NSO::LoadModule(Kernel::Process& process, Core::S pi_header.insert(pi_header.begin() + sizeof(NSOHeader), program_image.data(), program_image.data() + program_image.size()); - pi_header = pm->PatchNSO(pi_header, file.GetName()); + pi_header = pm->PatchNSO(pi_header, nso_file.GetName()); std::copy(pi_header.begin() + sizeof(NSOHeader), pi_header.end(), program_image.data()); } @@ -183,8 +183,8 @@ AppLoader_NSO::LoadResult AppLoader_NSO::Load(Kernel::Process& process, Core::Sy Core::Memory::DEFAULT_STACK_SIZE}}; } -ResultStatus AppLoader_NSO::ReadNSOModules(Modules& modules) { - modules = this->modules; +ResultStatus AppLoader_NSO::ReadNSOModules(Modules& out_modules) { + out_modules = this->modules; return ResultStatus::Success; } diff --git a/src/core/loader/nso.h b/src/core/loader/nso.h index 3af461b5f..195149b55 100644 --- a/src/core/loader/nso.h +++ b/src/core/loader/nso.h @@ -71,27 +71,29 @@ static_assert(sizeof(NSOArgumentHeader) == 0x20, "NSOArgumentHeader has incorrec /// Loads an NSO file class AppLoader_NSO final : public AppLoader { public: - explicit AppLoader_NSO(FileSys::VirtualFile file); + explicit AppLoader_NSO(FileSys::VirtualFile file_); /** - * Returns the type of the file - * @param file open file - * @return FileType found, or FileType::Error if this loader doesn't know it + * Identifies whether or not the given file is a form of NSO file. + * + * @param in_file The file to be identified. + * + * @return FileType::NSO if found, or FileType::Error if some other type of file. */ - static FileType IdentifyType(const FileSys::VirtualFile& file); + static FileType IdentifyType(const FileSys::VirtualFile& in_file); FileType GetFileType() const override { return IdentifyType(file); } static std::optional<VAddr> LoadModule(Kernel::Process& process, Core::System& system, - const FileSys::VfsFile& file, VAddr load_base, + const FileSys::VfsFile& nso_file, VAddr load_base, bool should_pass_arguments, bool load_into_process, std::optional<FileSys::PatchManager> pm = {}); LoadResult Load(Kernel::Process& process, Core::System& system) override; - ResultStatus ReadNSOModules(Modules& modules) override; + ResultStatus ReadNSOModules(Modules& out_modules) override; private: Modules modules; diff --git a/src/core/loader/nsp.cpp b/src/core/loader/nsp.cpp index 928f64c8c..d7e590f1c 100644 --- a/src/core/loader/nsp.cpp +++ b/src/core/loader/nsp.cpp @@ -21,11 +21,11 @@ namespace Loader { -AppLoader_NSP::AppLoader_NSP(FileSys::VirtualFile file, +AppLoader_NSP::AppLoader_NSP(FileSys::VirtualFile file_, const Service::FileSystem::FileSystemController& fsc, const FileSys::ContentProvider& content_provider, std::size_t program_index) - : AppLoader(file), nsp(std::make_unique<FileSys::NSP>(file, program_index)), + : AppLoader(file_), nsp(std::make_unique<FileSys::NSP>(file_, program_index)), title_id(nsp->GetProgramTitleID()) { if (nsp->GetStatus() != ResultStatus::Success) { @@ -57,8 +57,8 @@ AppLoader_NSP::AppLoader_NSP(FileSys::VirtualFile file, AppLoader_NSP::~AppLoader_NSP() = default; -FileType AppLoader_NSP::IdentifyType(const FileSys::VirtualFile& file) { - FileSys::NSP nsp(file); +FileType AppLoader_NSP::IdentifyType(const FileSys::VirtualFile& nsp_file) { + const FileSys::NSP nsp(nsp_file); if (nsp.GetStatus() == ResultStatus::Success) { // Extracted Type case @@ -121,67 +121,80 @@ AppLoader_NSP::LoadResult AppLoader_NSP::Load(Kernel::Process& process, Core::Sy return result; } -ResultStatus AppLoader_NSP::ReadRomFS(FileSys::VirtualFile& file) { - return secondary_loader->ReadRomFS(file); +ResultStatus AppLoader_NSP::ReadRomFS(FileSys::VirtualFile& out_file) { + return secondary_loader->ReadRomFS(out_file); } u64 AppLoader_NSP::ReadRomFSIVFCOffset() const { return secondary_loader->ReadRomFSIVFCOffset(); } -ResultStatus AppLoader_NSP::ReadUpdateRaw(FileSys::VirtualFile& file) { - if (nsp->IsExtractedType()) +ResultStatus AppLoader_NSP::ReadUpdateRaw(FileSys::VirtualFile& out_file) { + if (nsp->IsExtractedType()) { return ResultStatus::ErrorNoPackedUpdate; + } const auto read = nsp->GetNCAFile(FileSys::GetUpdateTitleID(title_id), FileSys::ContentRecordType::Program); - if (read == nullptr) + if (read == nullptr) { return ResultStatus::ErrorNoPackedUpdate; - const auto nca_test = std::make_shared<FileSys::NCA>(read); + } - if (nca_test->GetStatus() != ResultStatus::ErrorMissingBKTRBaseRomFS) + const auto nca_test = std::make_shared<FileSys::NCA>(read); + if (nca_test->GetStatus() != ResultStatus::ErrorMissingBKTRBaseRomFS) { return nca_test->GetStatus(); + } - file = read; + out_file = read; return ResultStatus::Success; } ResultStatus AppLoader_NSP::ReadProgramId(u64& out_program_id) { - if (title_id == 0) + if (title_id == 0) { return ResultStatus::ErrorNotInitialized; + } + out_program_id = title_id; return ResultStatus::Success; } ResultStatus AppLoader_NSP::ReadIcon(std::vector<u8>& buffer) { - if (icon_file == nullptr) + if (icon_file == nullptr) { return ResultStatus::ErrorNoControl; + } + buffer = icon_file->ReadAllBytes(); return ResultStatus::Success; } ResultStatus AppLoader_NSP::ReadTitle(std::string& title) { - if (nacp_file == nullptr) + if (nacp_file == nullptr) { return ResultStatus::ErrorNoControl; + } + title = nacp_file->GetApplicationName(); return ResultStatus::Success; } ResultStatus AppLoader_NSP::ReadControlData(FileSys::NACP& nacp) { - if (nacp_file == nullptr) + if (nacp_file == nullptr) { return ResultStatus::ErrorNoControl; + } + nacp = *nacp_file; return ResultStatus::Success; } -ResultStatus AppLoader_NSP::ReadManualRomFS(FileSys::VirtualFile& file) { +ResultStatus AppLoader_NSP::ReadManualRomFS(FileSys::VirtualFile& out_file) { const auto nca = nsp->GetNCA(nsp->GetProgramTitleID(), FileSys::ContentRecordType::HtmlDocument); - if (nsp->GetStatus() != ResultStatus::Success || nca == nullptr) + if (nsp->GetStatus() != ResultStatus::Success || nca == nullptr) { return ResultStatus::ErrorNoRomFS; - file = nca->GetRomFS(); - return file == nullptr ? ResultStatus::ErrorNoRomFS : ResultStatus::Success; + } + + out_file = nca->GetRomFS(); + return out_file == nullptr ? ResultStatus::ErrorNoRomFS : ResultStatus::Success; } ResultStatus AppLoader_NSP::ReadBanner(std::vector<u8>& buffer) { diff --git a/src/core/loader/nsp.h b/src/core/loader/nsp.h index d48d87f2c..1660f1b94 100644 --- a/src/core/loader/nsp.h +++ b/src/core/loader/nsp.h @@ -26,18 +26,20 @@ class AppLoader_NCA; /// Loads an XCI file class AppLoader_NSP final : public AppLoader { public: - explicit AppLoader_NSP(FileSys::VirtualFile file, + explicit AppLoader_NSP(FileSys::VirtualFile file_, const Service::FileSystem::FileSystemController& fsc, const FileSys::ContentProvider& content_provider, std::size_t program_index); ~AppLoader_NSP() override; /** - * Returns the type of the file - * @param file open file - * @return FileType found, or FileType::Error if this loader doesn't know it + * Identifies whether or not the given file is an NSP file. + * + * @param nsp_file The file to identify. + * + * @return FileType::NSP, or FileType::Error if the file is not an NSP. */ - static FileType IdentifyType(const FileSys::VirtualFile& file); + static FileType IdentifyType(const FileSys::VirtualFile& nsp_file); FileType GetFileType() const override { return IdentifyType(file); @@ -45,14 +47,14 @@ public: LoadResult Load(Kernel::Process& process, Core::System& system) override; - ResultStatus ReadRomFS(FileSys::VirtualFile& file) override; + ResultStatus ReadRomFS(FileSys::VirtualFile& out_file) override; u64 ReadRomFSIVFCOffset() const override; - ResultStatus ReadUpdateRaw(FileSys::VirtualFile& file) override; + ResultStatus ReadUpdateRaw(FileSys::VirtualFile& out_file) override; ResultStatus ReadProgramId(u64& out_program_id) override; ResultStatus ReadIcon(std::vector<u8>& buffer) override; ResultStatus ReadTitle(std::string& title) override; ResultStatus ReadControlData(FileSys::NACP& nacp) override; - ResultStatus ReadManualRomFS(FileSys::VirtualFile& file) override; + ResultStatus ReadManualRomFS(FileSys::VirtualFile& out_file) override; ResultStatus ReadBanner(std::vector<u8>& buffer) override; ResultStatus ReadLogo(std::vector<u8>& buffer) override; diff --git a/src/core/loader/xci.cpp b/src/core/loader/xci.cpp index aaa250cea..0125ddf33 100644 --- a/src/core/loader/xci.cpp +++ b/src/core/loader/xci.cpp @@ -20,11 +20,11 @@ namespace Loader { -AppLoader_XCI::AppLoader_XCI(FileSys::VirtualFile file, +AppLoader_XCI::AppLoader_XCI(FileSys::VirtualFile file_, const Service::FileSystem::FileSystemController& fsc, const FileSys::ContentProvider& content_provider, std::size_t program_index) - : AppLoader(file), xci(std::make_unique<FileSys::XCI>(file, program_index)), + : AppLoader(file_), xci(std::make_unique<FileSys::XCI>(file_, program_index)), nca_loader(std::make_unique<AppLoader_NCA>(xci->GetProgramNCAFile())) { if (xci->GetStatus() != ResultStatus::Success) { return; @@ -43,8 +43,8 @@ AppLoader_XCI::AppLoader_XCI(FileSys::VirtualFile file, AppLoader_XCI::~AppLoader_XCI() = default; -FileType AppLoader_XCI::IdentifyType(const FileSys::VirtualFile& file) { - FileSys::XCI xci(file); +FileType AppLoader_XCI::IdentifyType(const FileSys::VirtualFile& xci_file) { + const FileSys::XCI xci(xci_file); if (xci.GetStatus() == ResultStatus::Success && xci.GetNCAByType(FileSys::NCAContentType::Program) != nullptr && @@ -87,31 +87,33 @@ AppLoader_XCI::LoadResult AppLoader_XCI::Load(Kernel::Process& process, Core::Sy return result; } -ResultStatus AppLoader_XCI::ReadRomFS(FileSys::VirtualFile& file) { - return nca_loader->ReadRomFS(file); +ResultStatus AppLoader_XCI::ReadRomFS(FileSys::VirtualFile& out_file) { + return nca_loader->ReadRomFS(out_file); } u64 AppLoader_XCI::ReadRomFSIVFCOffset() const { return nca_loader->ReadRomFSIVFCOffset(); } -ResultStatus AppLoader_XCI::ReadUpdateRaw(FileSys::VirtualFile& file) { +ResultStatus AppLoader_XCI::ReadUpdateRaw(FileSys::VirtualFile& out_file) { u64 program_id{}; nca_loader->ReadProgramId(program_id); - if (program_id == 0) + if (program_id == 0) { return ResultStatus::ErrorXCIMissingProgramNCA; + } const auto read = xci->GetSecurePartitionNSP()->GetNCAFile( FileSys::GetUpdateTitleID(program_id), FileSys::ContentRecordType::Program); - - if (read == nullptr) + if (read == nullptr) { return ResultStatus::ErrorNoPackedUpdate; - const auto nca_test = std::make_shared<FileSys::NCA>(read); + } - if (nca_test->GetStatus() != ResultStatus::ErrorMissingBKTRBaseRomFS) + const auto nca_test = std::make_shared<FileSys::NCA>(read); + if (nca_test->GetStatus() != ResultStatus::ErrorMissingBKTRBaseRomFS) { return nca_test->GetStatus(); + } - file = read; + out_file = read; return ResultStatus::Success; } @@ -120,33 +122,41 @@ ResultStatus AppLoader_XCI::ReadProgramId(u64& out_program_id) { } ResultStatus AppLoader_XCI::ReadIcon(std::vector<u8>& buffer) { - if (icon_file == nullptr) + if (icon_file == nullptr) { return ResultStatus::ErrorNoControl; + } + buffer = icon_file->ReadAllBytes(); return ResultStatus::Success; } ResultStatus AppLoader_XCI::ReadTitle(std::string& title) { - if (nacp_file == nullptr) + if (nacp_file == nullptr) { return ResultStatus::ErrorNoControl; + } + title = nacp_file->GetApplicationName(); return ResultStatus::Success; } ResultStatus AppLoader_XCI::ReadControlData(FileSys::NACP& control) { - if (nacp_file == nullptr) + if (nacp_file == nullptr) { return ResultStatus::ErrorNoControl; + } + control = *nacp_file; return ResultStatus::Success; } -ResultStatus AppLoader_XCI::ReadManualRomFS(FileSys::VirtualFile& file) { +ResultStatus AppLoader_XCI::ReadManualRomFS(FileSys::VirtualFile& out_file) { const auto nca = xci->GetSecurePartitionNSP()->GetNCA(xci->GetProgramTitleID(), FileSys::ContentRecordType::HtmlDocument); - if (xci->GetStatus() != ResultStatus::Success || nca == nullptr) + if (xci->GetStatus() != ResultStatus::Success || nca == nullptr) { return ResultStatus::ErrorXCIMissingPartition; - file = nca->GetRomFS(); - return file == nullptr ? ResultStatus::ErrorNoRomFS : ResultStatus::Success; + } + + out_file = nca->GetRomFS(); + return out_file == nullptr ? ResultStatus::ErrorNoRomFS : ResultStatus::Success; } ResultStatus AppLoader_XCI::ReadBanner(std::vector<u8>& buffer) { diff --git a/src/core/loader/xci.h b/src/core/loader/xci.h index 9f0ceb5ef..7ea8179af 100644 --- a/src/core/loader/xci.h +++ b/src/core/loader/xci.h @@ -26,18 +26,20 @@ class AppLoader_NCA; /// Loads an XCI file class AppLoader_XCI final : public AppLoader { public: - explicit AppLoader_XCI(FileSys::VirtualFile file, + explicit AppLoader_XCI(FileSys::VirtualFile file_, const Service::FileSystem::FileSystemController& fsc, const FileSys::ContentProvider& content_provider, std::size_t program_index); ~AppLoader_XCI() override; /** - * Returns the type of the file - * @param file open file - * @return FileType found, or FileType::Error if this loader doesn't know it + * Identifies whether or not the given file is an XCI file. + * + * @param xci_file The file to identify. + * + * @return FileType::XCI, or FileType::Error if the file is not an XCI file. */ - static FileType IdentifyType(const FileSys::VirtualFile& file); + static FileType IdentifyType(const FileSys::VirtualFile& xci_file); FileType GetFileType() const override { return IdentifyType(file); @@ -45,14 +47,14 @@ public: LoadResult Load(Kernel::Process& process, Core::System& system) override; - ResultStatus ReadRomFS(FileSys::VirtualFile& file) override; + ResultStatus ReadRomFS(FileSys::VirtualFile& out_file) override; u64 ReadRomFSIVFCOffset() const override; - ResultStatus ReadUpdateRaw(FileSys::VirtualFile& file) override; + ResultStatus ReadUpdateRaw(FileSys::VirtualFile& out_file) override; ResultStatus ReadProgramId(u64& out_program_id) override; ResultStatus ReadIcon(std::vector<u8>& buffer) override; ResultStatus ReadTitle(std::string& title) override; ResultStatus ReadControlData(FileSys::NACP& control) override; - ResultStatus ReadManualRomFS(FileSys::VirtualFile& file) override; + ResultStatus ReadManualRomFS(FileSys::VirtualFile& out_file) override; ResultStatus ReadBanner(std::vector<u8>& buffer) override; ResultStatus ReadLogo(std::vector<u8>& buffer) override; diff --git a/src/video_core/gpu.cpp b/src/video_core/gpu.cpp index 7c42f1177..a38024242 100644 --- a/src/video_core/gpu.cpp +++ b/src/video_core/gpu.cpp @@ -492,10 +492,8 @@ void GPU::PushCommandBuffer(Tegra::ChCommandHeaderList& entries) { cdma_pusher->ProcessEntries(std::move(entries)); } -void GPU::ClearCommandBuffer() { - // This condition fires when a video stream ends, clear all intermediary data +void GPU::ClearCdmaInstance() { cdma_pusher.reset(); - LOG_INFO(Service_NVDRV, "NVDEC video stream ended"); } void GPU::SwapBuffers(const Tegra::FramebufferConfig* framebuffer) { diff --git a/src/video_core/gpu.h b/src/video_core/gpu.h index b1960ea86..8669e9940 100644 --- a/src/video_core/gpu.h +++ b/src/video_core/gpu.h @@ -324,8 +324,8 @@ public: /// Push GPU command buffer entries to be processed void PushCommandBuffer(Tegra::ChCommandHeaderList& entries); - /// Frees the CDMAPusher to free up resources - void ClearCommandBuffer(); + /// Frees the CDMAPusher instance to free up resources + void ClearCdmaInstance(); /// Swap buffers (render frame) void SwapBuffers(const Tegra::FramebufferConfig* framebuffer); diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.cpp b/src/video_core/renderer_vulkan/vk_texture_cache.cpp index bc2a53841..017348e05 100644 --- a/src/video_core/renderer_vulkan/vk_texture_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_texture_cache.cpp @@ -417,7 +417,7 @@ constexpr VkBorderColor ConvertBorderColor(const std::array<float, 4>& color) { }; } -[[nodiscard]] constexpr SwizzleSource ConvertGreenRed(SwizzleSource value) { +[[nodiscard]] SwizzleSource ConvertGreenRed(SwizzleSource value) { switch (value) { case SwizzleSource::G: return SwizzleSource::R; @@ -426,6 +426,17 @@ constexpr VkBorderColor ConvertBorderColor(const std::array<float, 4>& color) { } } +[[nodiscard]] SwizzleSource SwapBlueRed(SwizzleSource value) { + switch (value) { + case SwizzleSource::R: + return SwizzleSource::B; + case SwizzleSource::B: + return SwizzleSource::R; + default: + return value; + } +} + void CopyBufferToImage(vk::CommandBuffer cmdbuf, VkBuffer src_buffer, VkImage image, VkImageAspectFlags aspect_mask, bool is_initialized, std::span<const VkBufferImageCopy> copies) { @@ -543,6 +554,15 @@ void CopyBufferToImage(vk::CommandBuffer cmdbuf, VkBuffer src_buffer, VkImage im }; } +[[nodiscard]] bool IsFormatFlipped(PixelFormat format) { + switch (format) { + case PixelFormat::A1B5G5R5_UNORM: + return true; + default: + return false; + } +} + struct RangedBarrierRange { u32 min_mip = std::numeric_limits<u32>::max(); u32 max_mip = std::numeric_limits<u32>::min(); @@ -948,6 +968,9 @@ ImageView::ImageView(TextureCacheRuntime& runtime, const VideoCommon::ImageViewI }; if (!info.IsRenderTarget()) { swizzle = info.Swizzle(); + if (IsFormatFlipped(format)) { + std::ranges::transform(swizzle, swizzle.begin(), SwapBlueRed); + } if ((aspect_mask & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) != 0) { std::ranges::transform(swizzle, swizzle.begin(), ConvertGreenRed); } diff --git a/src/yuzu/applets/software_keyboard.cpp b/src/yuzu/applets/software_keyboard.cpp index fd3368479..653486493 100644 --- a/src/yuzu/applets/software_keyboard.cpp +++ b/src/yuzu/applets/software_keyboard.cpp @@ -1027,10 +1027,8 @@ void QtSoftwareKeyboardDialog::ChangeBottomOSKIndex() { ui->bottomOSK->setCurrentIndex(static_cast<int>(bottom_osk_index)); ui->button_shift_shift->setStyleSheet( - QStringLiteral("background-image: url(:/overlay/osk_button_shift_lock_off.png);" - "\nbackground-position: left top;" - "\nbackground-repeat: no-repeat;" - "\nbackground-origin: content;")); + QStringLiteral("image: url(:/overlay/osk_button_shift_lock_off.png);" + "\nimage-position: left;")); ui->button_shift_shift->setIconSize(ui->button_shift->iconSize()); ui->button_backspace_shift->setIconSize(ui->button_backspace->iconSize()); @@ -1040,10 +1038,8 @@ void QtSoftwareKeyboardDialog::ChangeBottomOSKIndex() { caps_lock_enabled = false; ui->button_shift_shift->setStyleSheet( - QStringLiteral("background-image: url(:/overlay/osk_button_shift_lock_off.png);" - "\nbackground-position: left top;" - "\nbackground-repeat: no-repeat;" - "\nbackground-origin: content;")); + QStringLiteral("image: url(:/overlay/osk_button_shift_lock_off.png);" + "\nimage-position: left;")); ui->button_shift_shift->setIconSize(ui->button_shift->iconSize()); ui->button_backspace_shift->setIconSize(ui->button_backspace->iconSize()); @@ -1056,10 +1052,8 @@ void QtSoftwareKeyboardDialog::ChangeBottomOSKIndex() { caps_lock_enabled = true; ui->button_shift_shift->setStyleSheet( - QStringLiteral("background-image: url(:/overlay/osk_button_shift_lock_on.png);" - "\nbackground-position: left top;" - "\nbackground-repeat: no-repeat;" - "\nbackground-origin: content;")); + QStringLiteral("image: url(:/overlay/osk_button_shift_lock_on.png);" + "\nimage-position: left;")); ui->button_shift_shift->setIconSize(ui->button_shift->iconSize()); ui->button_backspace_shift->setIconSize(ui->button_backspace->iconSize()); diff --git a/src/yuzu/configuration/config.cpp b/src/yuzu/configuration/config.cpp index 851246233..e80a3df77 100644 --- a/src/yuzu/configuration/config.cpp +++ b/src/yuzu/configuration/config.cpp @@ -29,9 +29,10 @@ Config::~Config() { } const std::array<int, Settings::NativeButton::NumButtons> Config::default_buttons = { - Qt::Key_A, Qt::Key_S, Qt::Key_Z, Qt::Key_X, Qt::Key_3, Qt::Key_4, Qt::Key_Q, - Qt::Key_W, Qt::Key_1, Qt::Key_2, Qt::Key_N, Qt::Key_M, Qt::Key_F, Qt::Key_T, - Qt::Key_H, Qt::Key_G, Qt::Key_D, Qt::Key_C, Qt::Key_B, Qt::Key_V, + Qt::Key_C, Qt::Key_X, Qt::Key_V, Qt::Key_Z, Qt::Key_F, + Qt::Key_G, Qt::Key_Q, Qt::Key_E, Qt::Key_R, Qt::Key_T, + Qt::Key_M, Qt::Key_N, Qt::Key_Left, Qt::Key_Up, Qt::Key_Right, + Qt::Key_Down, Qt::Key_Q, Qt::Key_E, 0, 0, }; const std::array<int, Settings::NativeMotion::NumMotions> Config::default_motions = { @@ -41,10 +42,10 @@ const std::array<int, Settings::NativeMotion::NumMotions> Config::default_motion const std::array<std::array<int, 4>, Settings::NativeAnalog::NumAnalogs> Config::default_analogs{{ { - Qt::Key_Up, - Qt::Key_Down, - Qt::Key_Left, - Qt::Key_Right, + Qt::Key_W, + Qt::Key_S, + Qt::Key_A, + Qt::Key_D, }, { Qt::Key_I, @@ -55,8 +56,8 @@ const std::array<std::array<int, 4>, Settings::NativeAnalog::NumAnalogs> Config: }}; const std::array<int, 2> Config::default_stick_mod = { - Qt::Key_E, - Qt::Key_R, + Qt::Key_Shift, + 0, }; const std::array<int, Settings::NativeMouseButton::NumMouseButtons> Config::default_mouse_buttons = @@ -862,8 +863,7 @@ void Config::ReadSystemValues() { Settings::values.rng_seed.SetGlobal(rng_seed_global); if (global || !rng_seed_global) { if (rng_seed_enabled) { - Settings::values.rng_seed.SetValue( - ReadSetting(QStringLiteral("rng_seed"), 0).toULongLong()); + Settings::values.rng_seed.SetValue(ReadSetting(QStringLiteral("rng_seed"), 0).toUInt()); } else { Settings::values.rng_seed.SetValue(std::nullopt); } @@ -936,6 +936,13 @@ void Config::ReadUIGamelistValues() { UISettings::values.row_2_text_id = ReadSetting(QStringLiteral("row_2_text_id"), 2).toUInt(); UISettings::values.cache_game_list = ReadSetting(QStringLiteral("cache_game_list"), true).toBool(); + const int favorites_size = qt_config->beginReadArray(QStringLiteral("favorites")); + for (int i = 0; i < favorites_size; i++) { + qt_config->setArrayIndex(i); + UISettings::values.favorited_ids.append( + ReadSetting(QStringLiteral("program_id")).toULongLong()); + } + qt_config->endArray(); qt_config->endGroup(); } @@ -1479,6 +1486,13 @@ void Config::SaveUIGamelistValues() { WriteSetting(QStringLiteral("row_1_text_id"), UISettings::values.row_1_text_id, 3); WriteSetting(QStringLiteral("row_2_text_id"), UISettings::values.row_2_text_id, 2); WriteSetting(QStringLiteral("cache_game_list"), UISettings::values.cache_game_list, true); + qt_config->beginWriteArray(QStringLiteral("favorites")); + for (int i = 0; i < UISettings::values.favorited_ids.size(); i++) { + qt_config->setArrayIndex(i); + WriteSetting(QStringLiteral("program_id"), + QVariant::fromValue(UISettings::values.favorited_ids[i])); + } + qt_config->endArray(); qt_config->endGroup(); } diff --git a/src/yuzu/game_list.cpp b/src/yuzu/game_list.cpp index 9afd5b45f..48b78d65f 100644 --- a/src/yuzu/game_list.cpp +++ b/src/yuzu/game_list.cpp @@ -11,6 +11,7 @@ #include <QJsonDocument> #include <QJsonObject> #include <QKeyEvent> +#include <QList> #include <QMenu> #include <QThreadPool> #include <fmt/format.h> @@ -84,6 +85,10 @@ void GameListSearchField::setFilterResult(int visible, int total) { label_filter_result->setText(tr("%1 of %n result(s)", "", total).arg(visible)); } +bool GameListSearchField::isEmpty() const { + return edit_filter->text().isEmpty(); +} + QString GameList::GetLastFilterResultItem() const { QString file_path; const int folder_count = item_model->rowCount(); @@ -187,7 +192,9 @@ void GameList::OnTextChanged(const QString& new_text) { // If the searchfield is empty every item is visible // Otherwise the filter gets applied if (edit_filter_text.isEmpty()) { - for (int i = 0; i < folder_count; ++i) { + tree_view->setRowHidden(0, item_model->invisibleRootItem()->index(), + UISettings::values.favorited_ids.size() == 0); + for (int i = 1; i < folder_count; ++i) { folder = item_model->item(i, 0); const QModelIndex folder_index = folder->index(); const int children_count = folder->rowCount(); @@ -198,8 +205,9 @@ void GameList::OnTextChanged(const QString& new_text) { } search_field->setFilterResult(children_total, children_total); } else { + tree_view->setRowHidden(0, item_model->invisibleRootItem()->index(), true); int result_count = 0; - for (int i = 0; i < folder_count; ++i) { + for (int i = 1; i < folder_count; ++i) { folder = item_model->item(i, 0); const QModelIndex folder_index = folder->index(); const int children_count = folder->rowCount(); @@ -280,6 +288,13 @@ void GameList::OnUpdateThemedIcons() { .scaled(icon_size, icon_size, Qt::IgnoreAspectRatio, Qt::SmoothTransformation), Qt::DecorationRole); break; + case GameListItemType::Favorites: + child->setData( + QIcon::fromTheme(QStringLiteral("star")) + .pixmap(icon_size) + .scaled(icon_size, icon_size, Qt::IgnoreAspectRatio, Qt::SmoothTransformation), + Qt::DecorationRole); + break; default: break; } @@ -427,6 +442,13 @@ void GameList::DonePopulating(const QStringList& watch_list) { emit ShowList(!IsEmpty()); item_model->invisibleRootItem()->appendRow(new GameListAddDir()); + item_model->invisibleRootItem()->insertRow(0, new GameListFavorites()); + tree_view->setRowHidden(0, item_model->invisibleRootItem()->index(), + UISettings::values.favorited_ids.size() == 0); + tree_view->expand(item_model->invisibleRootItem()->child(0)->index()); + for (const auto id : UISettings::values.favorited_ids) { + AddFavorite(id); + } // Clear out the old directories to watch for changes and add the new ones auto watch_dirs = watcher->directories(); @@ -446,7 +468,7 @@ void GameList::DonePopulating(const QStringList& watch_list) { tree_view->setEnabled(true); const int folder_count = tree_view->model()->rowCount(); int children_total = 0; - for (int i = 0; i < folder_count; ++i) { + for (int i = 1; i < folder_count; ++i) { children_total += item_model->item(i, 0)->rowCount(); } search_field->setFilterResult(children_total, children_total); @@ -478,6 +500,9 @@ void GameList::PopupContextMenu(const QPoint& menu_location) { case GameListItemType::SysNandDir: AddPermDirPopup(context_menu, selected); break; + case GameListItemType::Favorites: + AddFavoritesPopup(context_menu); + break; default: break; } @@ -485,6 +510,8 @@ void GameList::PopupContextMenu(const QPoint& menu_location) { } void GameList::AddGamePopup(QMenu& context_menu, u64 program_id, const std::string& path) { + QAction* favorite = context_menu.addAction(tr("Favorite")); + context_menu.addSeparator(); QAction* open_save_location = context_menu.addAction(tr("Open Save Data Location")); QAction* open_mod_location = context_menu.addAction(tr("Open Mod Data Location")); QAction* open_transferable_shader_cache = @@ -503,6 +530,9 @@ void GameList::AddGamePopup(QMenu& context_menu, u64 program_id, const std::stri context_menu.addSeparator(); QAction* properties = context_menu.addAction(tr("Properties")); + favorite->setVisible(program_id != 0); + favorite->setCheckable(true); + favorite->setChecked(UISettings::values.favorited_ids.contains(program_id)); open_save_location->setVisible(program_id != 0); open_mod_location->setVisible(program_id != 0); open_transferable_shader_cache->setVisible(program_id != 0); @@ -513,6 +543,7 @@ void GameList::AddGamePopup(QMenu& context_menu, u64 program_id, const std::stri auto it = FindMatchingCompatibilityEntry(compatibility_list, program_id); navigate_to_gamedb_entry->setVisible(it != compatibility_list.end() && program_id != 0); + connect(favorite, &QAction::triggered, [this, program_id]() { ToggleFavorite(program_id); }); connect(open_save_location, &QAction::triggered, [this, program_id, path]() { emit OpenFolderRequested(program_id, GameListOpenTarget::SaveData, path); }); @@ -576,7 +607,7 @@ void GameList::AddPermDirPopup(QMenu& context_menu, QModelIndex selected) { const int row = selected.row(); - move_up->setEnabled(row > 0); + move_up->setEnabled(row > 1); move_down->setEnabled(row < item_model->rowCount() - 2); connect(move_up, &QAction::triggered, [this, selected, row, game_dir_index] { @@ -614,6 +645,18 @@ void GameList::AddPermDirPopup(QMenu& context_menu, QModelIndex selected) { }); } +void GameList::AddFavoritesPopup(QMenu& context_menu) { + QAction* clear_all = context_menu.addAction(tr("Clear")); + + connect(clear_all, &QAction::triggered, [this] { + for (const auto id : UISettings::values.favorited_ids) { + RemoveFavorite(id); + } + UISettings::values.favorited_ids.clear(); + tree_view->setRowHidden(0, item_model->invisibleRootItem()->index(), true); + }); +} + void GameList::LoadCompatibilityList() { QFile compat_list{QStringLiteral(":compatibility_list/compatibility_list.json")}; @@ -728,6 +771,58 @@ void GameList::RefreshGameDirectory() { } } +void GameList::ToggleFavorite(u64 program_id) { + if (!UISettings::values.favorited_ids.contains(program_id)) { + tree_view->setRowHidden(0, item_model->invisibleRootItem()->index(), + !search_field->isEmpty()); + UISettings::values.favorited_ids.append(program_id); + AddFavorite(program_id); + item_model->sort(tree_view->header()->sortIndicatorSection(), + tree_view->header()->sortIndicatorOrder()); + } else { + UISettings::values.favorited_ids.removeOne(program_id); + RemoveFavorite(program_id); + if (UISettings::values.favorited_ids.size() == 0) { + tree_view->setRowHidden(0, item_model->invisibleRootItem()->index(), true); + } + } +} + +void GameList::AddFavorite(u64 program_id) { + auto* favorites_row = item_model->item(0); + + for (int i = 1; i < item_model->rowCount() - 1; i++) { + const auto* folder = item_model->item(i); + for (int j = 0; j < folder->rowCount(); j++) { + if (folder->child(j)->data(GameListItemPath::ProgramIdRole).toULongLong() == + program_id) { + QList<QStandardItem*> list; + for (int k = 0; k < item_model->columnCount(); k++) { + list.append(folder->child(j, k)->clone()); + } + list[0]->setData(folder->child(j)->data(GameListItem::SortRole), + GameListItem::SortRole); + list[0]->setText(folder->child(j)->data(Qt::DisplayRole).toString()); + + favorites_row->appendRow(list); + return; + } + } + } +} + +void GameList::RemoveFavorite(u64 program_id) { + auto* favorites_row = item_model->item(0); + + for (int i = 0; i < favorites_row->rowCount(); i++) { + const auto* game = favorites_row->child(i); + if (game->data(GameListItemPath::ProgramIdRole).toULongLong() == program_id) { + favorites_row->removeRow(i); + return; + } + } +} + GameListPlaceholder::GameListPlaceholder(GMainWindow* parent) : QWidget{parent} { connect(parent, &GMainWindow::UpdateThemedIcons, this, &GameListPlaceholder::onUpdateThemedIcons); diff --git a/src/yuzu/game_list.h b/src/yuzu/game_list.h index 58059a3c4..9c0a1a482 100644 --- a/src/yuzu/game_list.h +++ b/src/yuzu/game_list.h @@ -112,10 +112,15 @@ private: void RefreshGameDirectory(); + void ToggleFavorite(u64 program_id); + void AddFavorite(u64 program_id); + void RemoveFavorite(u64 program_id); + void PopupContextMenu(const QPoint& menu_location); void AddGamePopup(QMenu& context_menu, u64 program_id, const std::string& path); void AddCustomDirPopup(QMenu& context_menu, QModelIndex selected); void AddPermDirPopup(QMenu& context_menu, QModelIndex selected); + void AddFavoritesPopup(QMenu& context_menu); std::shared_ptr<FileSys::VfsFilesystem> vfs; FileSys::ManualContentProvider* provider; diff --git a/src/yuzu/game_list_p.h b/src/yuzu/game_list_p.h index f25445f18..7ca8ece23 100644 --- a/src/yuzu/game_list_p.h +++ b/src/yuzu/game_list_p.h @@ -29,7 +29,8 @@ enum class GameListItemType { SdmcDir = QStandardItem::UserType + 3, UserNandDir = QStandardItem::UserType + 4, SysNandDir = QStandardItem::UserType + 5, - AddDir = QStandardItem::UserType + 6 + AddDir = QStandardItem::UserType + 6, + Favorites = QStandardItem::UserType + 7, }; Q_DECLARE_METATYPE(GameListItemType); @@ -310,6 +311,28 @@ public: } }; +class GameListFavorites : public GameListItem { +public: + explicit GameListFavorites() { + setData(type(), TypeRole); + + const int icon_size = std::min(static_cast<int>(UISettings::values.icon_size), 64); + setData(QIcon::fromTheme(QStringLiteral("star")) + .pixmap(icon_size) + .scaled(icon_size, icon_size, Qt::IgnoreAspectRatio, Qt::SmoothTransformation), + Qt::DecorationRole); + setData(QObject::tr("Favorites"), Qt::DisplayRole); + } + + int type() const override { + return static_cast<int>(GameListItemType::Favorites); + } + + bool operator<(const QStandardItem& other) const override { + return false; + } +}; + class GameList; class QHBoxLayout; class QTreeView; @@ -324,6 +347,7 @@ public: explicit GameListSearchField(GameList* parent = nullptr); void setFilterResult(int visible, int total); + bool isEmpty() const; void clear(); void setFocus(); diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index 5f6cdc0c6..39bdf186d 100644 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp @@ -349,7 +349,7 @@ GMainWindow::GMainWindow() continue; } - Settings::values.current_user = selected_user; + Settings::values.current_user = static_cast<s32>(selected_user); continue; } diff --git a/src/yuzu/uisettings.h b/src/yuzu/uisettings.h index ce3945485..5ba00b8c8 100644 --- a/src/yuzu/uisettings.h +++ b/src/yuzu/uisettings.h @@ -74,6 +74,7 @@ struct Values { QString game_dir_deprecated; bool game_dir_deprecated_deepscan; QVector<UISettings::GameDir> game_dirs; + QVector<u64> favorited_ids; QStringList recent_files; QString language; diff --git a/src/yuzu_cmd/CMakeLists.txt b/src/yuzu_cmd/CMakeLists.txt index 8461f8896..4bf25727b 100644 --- a/src/yuzu_cmd/CMakeLists.txt +++ b/src/yuzu_cmd/CMakeLists.txt @@ -20,7 +20,6 @@ add_executable(yuzu-cmd emu_window/emu_window_sdl2_gl.h emu_window/emu_window_sdl2_vk.cpp emu_window/emu_window_sdl2_vk.h - resource.h yuzu.cpp yuzu.rc ) diff --git a/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp b/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp index 3bb555a6b..d64f81106 100644 --- a/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp +++ b/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp @@ -238,6 +238,6 @@ void EmuWindow_SDL2::SetWindowIcon() { SDL_FreeSurface(window_icon); } -void EmuWindow_SDL2::OnMinimalClientAreaChangeRequest(std::pair<unsigned, unsigned> minimal_size) { +void EmuWindow_SDL2::OnMinimalClientAreaChangeRequest(std::pair<u32, u32> minimal_size) { SDL_SetWindowMinimumSize(render_window, minimal_size.first, minimal_size.second); } diff --git a/src/yuzu_cmd/emu_window/emu_window_sdl2.h b/src/yuzu_cmd/emu_window/emu_window_sdl2.h index 0e17bbca7..1b9ab5b93 100644 --- a/src/yuzu_cmd/emu_window/emu_window_sdl2.h +++ b/src/yuzu_cmd/emu_window/emu_window_sdl2.h @@ -71,7 +71,7 @@ protected: void Fullscreen(); /// Called when a configuration change affects the minimal size of the window - void OnMinimalClientAreaChangeRequest(std::pair<unsigned, unsigned> minimal_size) override; + void OnMinimalClientAreaChangeRequest(std::pair<u32, u32> minimal_size) override; /// Is the window still open? bool is_open = true; diff --git a/src/yuzu_cmd/resource.h b/src/yuzu_cmd/resource.h deleted file mode 100644 index df8e459e4..000000000 --- a/src/yuzu_cmd/resource.h +++ /dev/null @@ -1,16 +0,0 @@ -//{{NO_DEPENDENCIES}} -// Microsoft Visual C++ generated include file. -// Used by pcafe.rc -// -#define IDI_ICON3 103 - -// Next default values for new objects -// -#ifdef APSTUDIO_INVOKED -#ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 105 -#define _APS_NEXT_COMMAND_VALUE 40001 -#define _APS_NEXT_CONTROL_VALUE 1001 -#define _APS_NEXT_SYMED_VALUE 101 -#endif -#endif |