diff options
| -rw-r--r-- | src/core/file_sys/control_metadata.cpp | 4 | ||||
| -rw-r--r-- | src/core/file_sys/control_metadata.h | 1 | ||||
| -rw-r--r-- | src/core/file_sys/savedata_factory.cpp | 9 | ||||
| -rw-r--r-- | src/core/hle/service/filesystem/fsp_srv.cpp | 38 | ||||
| -rw-r--r-- | src/core/hle/service/filesystem/fsp_srv.h | 1 | ||||
| -rw-r--r-- | src/core/hle/service/hid/controllers/keyboard.cpp | 7 | ||||
| -rw-r--r-- | src/core/hle/service/nvflinger/buffer_queue.cpp | 4 | ||||
| -rw-r--r-- | src/core/hle/service/nvflinger/buffer_queue.h | 10 | ||||
| -rw-r--r-- | src/video_core/dma_pusher.cpp | 9 | ||||
| -rw-r--r-- | src/video_core/dma_pusher.h | 1 | ||||
| -rw-r--r-- | src/yuzu/game_list.cpp | 8 | ||||
| -rw-r--r-- | src/yuzu/game_list.h | 2 | ||||
| -rw-r--r-- | src/yuzu/main.cpp | 64 | ||||
| -rw-r--r-- | src/yuzu/main.h | 2 | 
14 files changed, 114 insertions, 46 deletions
| diff --git a/src/core/file_sys/control_metadata.cpp b/src/core/file_sys/control_metadata.cpp index f155a1341..63cd2eead 100644 --- a/src/core/file_sys/control_metadata.cpp +++ b/src/core/file_sys/control_metadata.cpp @@ -95,6 +95,10 @@ u32 NACP::GetSupportedLanguages() const {      return raw.supported_languages;  } +u64 NACP::GetDeviceSaveDataSize() const { +    return raw.device_save_data_size; +} +  std::vector<u8> NACP::GetRawBytes() const {      std::vector<u8> out(sizeof(RawNACP));      std::memcpy(out.data(), &raw, sizeof(RawNACP)); diff --git a/src/core/file_sys/control_metadata.h b/src/core/file_sys/control_metadata.h index 2d8c251ac..e37b2fadf 100644 --- a/src/core/file_sys/control_metadata.h +++ b/src/core/file_sys/control_metadata.h @@ -113,6 +113,7 @@ public:      u32 GetSupportedLanguages() const;      std::vector<u8> GetRawBytes() const;      bool GetUserAccountSwitchLock() const; +    u64 GetDeviceSaveDataSize() const;  private:      RawNACP raw{}; diff --git a/src/core/file_sys/savedata_factory.cpp b/src/core/file_sys/savedata_factory.cpp index f3def93ab..adfd2c1a4 100644 --- a/src/core/file_sys/savedata_factory.cpp +++ b/src/core/file_sys/savedata_factory.cpp @@ -57,7 +57,8 @@ void PrintSaveDataDescriptorWarnings(SaveDataDescriptor meta) {  bool ShouldSaveDataBeAutomaticallyCreated(SaveDataSpaceId space, const SaveDataDescriptor& desc) {      return desc.type == SaveDataType::CacheStorage || desc.type == SaveDataType::TemporaryStorage ||             (space == SaveDataSpaceId::NandUser && ///< Normal Save Data -- Current Title & User -            desc.type == SaveDataType::SaveData && desc.title_id == 0 && desc.save_id == 0); +            (desc.type == SaveDataType::SaveData || desc.type == SaveDataType::DeviceSaveData) && +            desc.title_id == 0 && desc.save_id == 0);  }  } // Anonymous namespace @@ -139,8 +140,10 @@ std::string SaveDataFactory::GetFullPath(SaveDataSpaceId space, SaveDataType typ                                           u128 user_id, u64 save_id) {      // According to switchbrew, if a save is of type SaveData and the title id field is 0, it should      // be interpreted as the title id of the current process. -    if (type == SaveDataType::SaveData && title_id == 0) { -        title_id = Core::System::GetInstance().CurrentProcess()->GetTitleID(); +    if (type == SaveDataType::SaveData || type == SaveDataType::DeviceSaveData) { +        if (title_id == 0) { +            title_id = Core::System::GetInstance().CurrentProcess()->GetTitleID(); +        }      }      std::string out = GetSaveDataSpaceIdPath(space); diff --git a/src/core/hle/service/filesystem/fsp_srv.cpp b/src/core/hle/service/filesystem/fsp_srv.cpp index f6503fe2f..20c331b77 100644 --- a/src/core/hle/service/filesystem/fsp_srv.cpp +++ b/src/core/hle/service/filesystem/fsp_srv.cpp @@ -767,7 +767,7 @@ FSP_SRV::FSP_SRV(FileSystemController& fsc, const Core::Reporter& reporter)          {1014, nullptr, "OutputMultiProgramTagAccessLog"},          {1100, nullptr, "OverrideSaveDataTransferTokenSignVerificationKey"},          {1110, nullptr, "CorruptSaveDataFileSystemBySaveDataSpaceId2"}, -        {1200, nullptr, "OpenMultiCommitManager"}, +        {1200, &FSP_SRV::OpenMultiCommitManager, "OpenMultiCommitManager"},          {1300, nullptr, "OpenBisWiper"},      };      // clang-format on @@ -988,4 +988,40 @@ void FSP_SRV::GetAccessLogVersionInfo(Kernel::HLERequestContext& ctx) {      rb.Push(access_log_program_index);  } +class IMultiCommitManager final : public ServiceFramework<IMultiCommitManager> { +public: +    explicit IMultiCommitManager() : ServiceFramework("IMultiCommitManager") { +        static const FunctionInfo functions[] = { +            {1, &IMultiCommitManager::Add, "Add"}, +            {2, &IMultiCommitManager::Commit, "Commit"}, +        }; +        RegisterHandlers(functions); +    } + +private: +    FileSys::VirtualFile backend; + +    void Add(Kernel::HLERequestContext& ctx) { +        LOG_WARNING(Service_FS, "(STUBBED) called"); + +        IPC::ResponseBuilder rb{ctx, 2}; +        rb.Push(RESULT_SUCCESS); +    } + +    void Commit(Kernel::HLERequestContext& ctx) { +        LOG_WARNING(Service_FS, "(STUBBED) called"); + +        IPC::ResponseBuilder rb{ctx, 2}; +        rb.Push(RESULT_SUCCESS); +    } +}; + +void FSP_SRV::OpenMultiCommitManager(Kernel::HLERequestContext& ctx) { +    LOG_DEBUG(Service_FS, "called"); + +    IPC::ResponseBuilder rb{ctx, 2, 0, 1}; +    rb.Push(RESULT_SUCCESS); +    rb.PushIpcInterface<IMultiCommitManager>(std::make_shared<IMultiCommitManager>()); +} +  } // namespace Service::FileSystem diff --git a/src/core/hle/service/filesystem/fsp_srv.h b/src/core/hle/service/filesystem/fsp_srv.h index d52b55999..dfb3e395b 100644 --- a/src/core/hle/service/filesystem/fsp_srv.h +++ b/src/core/hle/service/filesystem/fsp_srv.h @@ -50,6 +50,7 @@ private:      void OpenPatchDataStorageByCurrentProcess(Kernel::HLERequestContext& ctx);      void OutputAccessLogToSdCard(Kernel::HLERequestContext& ctx);      void GetAccessLogVersionInfo(Kernel::HLERequestContext& ctx); +    void OpenMultiCommitManager(Kernel::HLERequestContext& ctx);      FileSystemController& fsc; diff --git a/src/core/hle/service/hid/controllers/keyboard.cpp b/src/core/hle/service/hid/controllers/keyboard.cpp index 358cb9329..9a8d354ba 100644 --- a/src/core/hle/service/hid/controllers/keyboard.cpp +++ b/src/core/hle/service/hid/controllers/keyboard.cpp @@ -38,10 +38,11 @@ void Controller_Keyboard::OnUpdate(const Core::Timing::CoreTiming& core_timing,      cur_entry.sampling_number = last_entry.sampling_number + 1;      cur_entry.sampling_number2 = cur_entry.sampling_number; +    cur_entry.key.fill(0); +    cur_entry.modifier = 0; +      for (std::size_t i = 0; i < keyboard_keys.size(); ++i) { -        for (std::size_t k = 0; k < KEYS_PER_BYTE; ++k) { -            cur_entry.key[i / KEYS_PER_BYTE] |= (keyboard_keys[i]->GetStatus() << k); -        } +        cur_entry.key[i / KEYS_PER_BYTE] |= (keyboard_keys[i]->GetStatus() << (i % KEYS_PER_BYTE));      }      for (std::size_t i = 0; i < keyboard_mods.size(); ++i) { diff --git a/src/core/hle/service/nvflinger/buffer_queue.cpp b/src/core/hle/service/nvflinger/buffer_queue.cpp index f1e3d832a..caca80dde 100644 --- a/src/core/hle/service/nvflinger/buffer_queue.cpp +++ b/src/core/hle/service/nvflinger/buffer_queue.cpp @@ -138,9 +138,7 @@ u32 BufferQueue::Query(QueryType type) {      switch (type) {      case QueryType::NativeWindowFormat: -        // TODO(Subv): Use an enum for this -        static constexpr u32 FormatABGR8 = 1; -        return FormatABGR8; +        return static_cast<u32>(PixelFormat::RGBA8888);      }      UNIMPLEMENTED(); diff --git a/src/core/hle/service/nvflinger/buffer_queue.h b/src/core/hle/service/nvflinger/buffer_queue.h index d5f31e567..8a837e5aa 100644 --- a/src/core/hle/service/nvflinger/buffer_queue.h +++ b/src/core/hle/service/nvflinger/buffer_queue.h @@ -66,6 +66,16 @@ public:          Rotate270 = 0x07,      }; +    enum class PixelFormat : u32 { +        RGBA8888 = 1, +        RGBX8888 = 2, +        RGB888 = 3, +        RGB565 = 4, +        BGRA8888 = 5, +        RGBA5551 = 6, +        RRGBA4444 = 7, +    }; +      struct Buffer {          enum class Status { Free = 0, Queued = 1, Dequeued = 2, Acquired = 3 }; diff --git a/src/video_core/dma_pusher.cpp b/src/video_core/dma_pusher.cpp index bdc023d54..f2f96ac33 100644 --- a/src/video_core/dma_pusher.cpp +++ b/src/video_core/dma_pusher.cpp @@ -54,9 +54,7 @@ bool DmaPusher::Step() {          return true;      });      const CommandListHeader command_list_header{command_list[dma_pushbuffer_subindex++]}; -    GPUVAddr dma_get = command_list_header.addr; -    GPUVAddr dma_put = dma_get + command_list_header.size * sizeof(u32); -    bool non_main = command_list_header.is_non_main; +    const GPUVAddr dma_get = command_list_header.addr;      if (dma_pushbuffer_subindex >= command_list.size()) {          // We've gone through the current list, remove it from the queue @@ -133,11 +131,6 @@ bool DmaPusher::Step() {          index++;      } -    if (!non_main) { -        // TODO (degasus): This is dead code, as dma_mget is never read. -        dma_mget = dma_put; -    } -      return true;  } diff --git a/src/video_core/dma_pusher.h b/src/video_core/dma_pusher.h index e8b714e94..efa90d170 100644 --- a/src/video_core/dma_pusher.h +++ b/src/video_core/dma_pusher.h @@ -102,7 +102,6 @@ private:      DmaState dma_state{};      bool dma_increment_once{}; -    GPUVAddr dma_mget{};  ///< main pushbuffer last read address      bool ib_enable{true}; ///< IB mode enabled      std::array<Tegra::Engines::EngineInterface*, max_subchannels> subchannels{}; diff --git a/src/yuzu/game_list.cpp b/src/yuzu/game_list.cpp index dccbabcbf..bfb600df0 100644 --- a/src/yuzu/game_list.cpp +++ b/src/yuzu/game_list.cpp @@ -488,11 +488,11 @@ void GameList::AddGamePopup(QMenu& context_menu, u64 program_id, std::string pat      auto it = FindMatchingCompatibilityEntry(compatibility_list, program_id);      navigate_to_gamedb_entry->setVisible(it != compatibility_list.end() && program_id != 0); -    connect(open_save_location, &QAction::triggered, [this, program_id]() { -        emit OpenFolderRequested(program_id, GameListOpenTarget::SaveData); +    connect(open_save_location, &QAction::triggered, [this, program_id, path]() { +        emit OpenFolderRequested(GameListOpenTarget::SaveData, path);      }); -    connect(open_lfs_location, &QAction::triggered, [this, program_id]() { -        emit OpenFolderRequested(program_id, GameListOpenTarget::ModData); +    connect(open_lfs_location, &QAction::triggered, [this, program_id, path]() { +        emit OpenFolderRequested(GameListOpenTarget::ModData, path);      });      connect(open_transferable_shader_cache, &QAction::triggered,              [this, program_id]() { emit OpenTransferableShaderCacheRequested(program_id); }); diff --git a/src/yuzu/game_list.h b/src/yuzu/game_list.h index 878d94413..a38cb2fc3 100644 --- a/src/yuzu/game_list.h +++ b/src/yuzu/game_list.h @@ -73,7 +73,7 @@ public:  signals:      void GameChosen(QString game_path);      void ShouldCancelWorker(); -    void OpenFolderRequested(u64 program_id, GameListOpenTarget target); +    void OpenFolderRequested(GameListOpenTarget target, const std::string& game_path);      void OpenTransferableShaderCacheRequested(u64 program_id);      void DumpRomFSRequested(u64 program_id, const std::string& game_path);      void CopyTIDRequested(u64 program_id); diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index dd6e5173e..0b291c7d0 100644 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp @@ -1155,39 +1155,61 @@ void GMainWindow::OnGameListLoadFile(QString game_path) {      BootGame(game_path);  } -void GMainWindow::OnGameListOpenFolder(u64 program_id, GameListOpenTarget target) { +void GMainWindow::OnGameListOpenFolder(GameListOpenTarget target, const std::string& game_path) {      std::string path;      QString open_target; + +    const auto v_file = Core::GetGameFileFromPath(vfs, game_path); +    const auto loader = Loader::GetLoader(v_file); +    FileSys::NACP control{}; +    u64 program_id{}; + +    loader->ReadControlData(control); +    loader->ReadProgramId(program_id); + +    const bool has_user_save{control.GetDefaultNormalSaveSize() > 0}; +    const bool has_device_save{control.GetDeviceSaveDataSize() > 0}; + +    ASSERT_MSG(has_user_save != has_device_save, "Game uses both user and device savedata?"); +      switch (target) {      case GameListOpenTarget::SaveData: {          open_target = tr("Save Data");          const std::string nand_dir = FileUtil::GetUserPath(FileUtil::UserPath::NANDDir);          ASSERT(program_id != 0); -        const auto select_profile = [this] { -            QtProfileSelectionDialog dialog(this); -            dialog.setWindowFlags(Qt::Dialog | Qt::CustomizeWindowHint | Qt::WindowTitleHint | -                                  Qt::WindowSystemMenuHint | Qt::WindowCloseButtonHint); -            dialog.setWindowModality(Qt::WindowModal); +        if (has_user_save) { +            // User save data +            const auto select_profile = [this] { +                QtProfileSelectionDialog dialog(this); +                dialog.setWindowFlags(Qt::Dialog | Qt::CustomizeWindowHint | Qt::WindowTitleHint | +                                      Qt::WindowSystemMenuHint | Qt::WindowCloseButtonHint); +                dialog.setWindowModality(Qt::WindowModal); -            if (dialog.exec() == QDialog::Rejected) { -                return -1; -            } +                if (dialog.exec() == QDialog::Rejected) { +                    return -1; +                } -            return dialog.GetIndex(); -        }; +                return dialog.GetIndex(); +            }; -        const auto index = select_profile(); -        if (index == -1) { -            return; -        } +            const auto index = select_profile(); +            if (index == -1) { +                return; +            } -        Service::Account::ProfileManager manager; -        const auto user_id = manager.GetUser(static_cast<std::size_t>(index)); -        ASSERT(user_id); -        path = nand_dir + FileSys::SaveDataFactory::GetFullPath(FileSys::SaveDataSpaceId::NandUser, -                                                                FileSys::SaveDataType::SaveData, -                                                                program_id, user_id->uuid, 0); +            Service::Account::ProfileManager manager; +            const auto user_id = manager.GetUser(static_cast<std::size_t>(index)); +            ASSERT(user_id); +            path = nand_dir + FileSys::SaveDataFactory::GetFullPath( +                                  FileSys::SaveDataSpaceId::NandUser, +                                  FileSys::SaveDataType::SaveData, program_id, user_id->uuid, 0); +        } else { +            // Device save data +            path = nand_dir + FileSys::SaveDataFactory::GetFullPath( +                                  FileSys::SaveDataSpaceId::NandUser, +                                  FileSys::SaveDataType::SaveData, program_id, {}, 0); +        }          if (!FileUtil::Exists(path)) {              FileUtil::CreateFullPath(path); diff --git a/src/yuzu/main.h b/src/yuzu/main.h index 4bff4330c..4f4c8ddbe 100644 --- a/src/yuzu/main.h +++ b/src/yuzu/main.h @@ -183,7 +183,7 @@ private slots:      void OnMenuReportCompatibility();      /// Called whenever a user selects a game in the game list widget.      void OnGameListLoadFile(QString game_path); -    void OnGameListOpenFolder(u64 program_id, GameListOpenTarget target); +    void OnGameListOpenFolder(GameListOpenTarget target, const std::string& game_path);      void OnTransferableShaderCacheOpenFile(u64 program_id);      void OnGameListDumpRomFS(u64 program_id, const std::string& game_path);      void OnGameListCopyTID(u64 program_id); | 
