mirror of
https://git.eden-emu.dev/eden-emu/eden
synced 2026-04-10 05:28:56 +02:00
[fs/core] Load external content without NAND install (#2862)
Adds the capability to add DLC and Updates without installing them to NAND. This was tested on Windows only and needs Android integration. Co-authored-by: crueter <crueter@eden-emu.dev> Co-authored-by: wildcard <wildcard@eden-emu.dev> Co-authored-by: nekle <nekle@protonmail.com> Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/2862 Reviewed-by: DraVee <dravee@eden-emu.dev> Reviewed-by: crueter <crueter@eden-emu.dev> Co-authored-by: Maufeat <sahyno1996@gmail.com> Co-committed-by: Maufeat <sahyno1996@gmail.com>
This commit is contained in:
parent
e07e269bd7
commit
69aff83ef4
40 changed files with 1790 additions and 126 deletions
|
|
@ -8,6 +8,8 @@
|
|||
#include <memory>
|
||||
#include <utility>
|
||||
|
||||
#include <fmt/format.h>
|
||||
|
||||
#include <QHeaderView>
|
||||
#include <QMenu>
|
||||
#include <QStandardItemModel>
|
||||
|
|
@ -16,6 +18,7 @@
|
|||
#include <QTreeView>
|
||||
#include <qstandardpaths.h>
|
||||
|
||||
#include "common/common_types.h"
|
||||
#include "common/fs/fs.h"
|
||||
#include "common/fs/path_util.h"
|
||||
#include "configuration/addon/mod_select_dialog.h"
|
||||
|
|
@ -68,6 +71,8 @@ ConfigurePerGameAddons::ConfigurePerGameAddons(Core::System& system_, QWidget* p
|
|||
|
||||
ui->scrollArea->setEnabled(!system.IsPoweredOn());
|
||||
|
||||
connect(item_model, &QStandardItemModel::itemChanged, this,
|
||||
&ConfigurePerGameAddons::OnItemChanged);
|
||||
connect(item_model, &QStandardItemModel::itemChanged,
|
||||
[] { UISettings::values.is_game_list_reload_pending.exchange(true); });
|
||||
|
||||
|
|
@ -77,13 +82,37 @@ ConfigurePerGameAddons::ConfigurePerGameAddons(Core::System& system_, QWidget* p
|
|||
|
||||
ConfigurePerGameAddons::~ConfigurePerGameAddons() = default;
|
||||
|
||||
void ConfigurePerGameAddons::OnItemChanged(QStandardItem* item) {
|
||||
if (update_items.size() > 1 && item->checkState() == Qt::Checked) {
|
||||
auto it = std::find(update_items.begin(), update_items.end(), item);
|
||||
if (it != update_items.end()) {
|
||||
for (auto* update_item : update_items) {
|
||||
if (update_item != item && update_item->checkState() == Qt::Checked) {
|
||||
disconnect(item_model, &QStandardItemModel::itemChanged, this,
|
||||
&ConfigurePerGameAddons::OnItemChanged);
|
||||
update_item->setCheckState(Qt::Unchecked);
|
||||
connect(item_model, &QStandardItemModel::itemChanged, this,
|
||||
&ConfigurePerGameAddons::OnItemChanged);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ConfigurePerGameAddons::ApplyConfiguration() {
|
||||
std::vector<std::string> disabled_addons;
|
||||
|
||||
for (const auto& item : list_items) {
|
||||
const auto disabled = item.front()->checkState() == Qt::Unchecked;
|
||||
if (disabled)
|
||||
disabled_addons.push_back(item.front()->text().toStdString());
|
||||
if (disabled) {
|
||||
QVariant userData = item.front()->data(Qt::UserRole);
|
||||
if (userData.isValid() && userData.canConvert<quint32>() && item.front()->text() == QStringLiteral("Update")) {
|
||||
quint32 numeric_version = userData.toUInt();
|
||||
disabled_addons.push_back(fmt::format("Update@{}", numeric_version));
|
||||
} else {
|
||||
disabled_addons.push_back(item.front()->text().toStdString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto current = Settings::values.disabled_addons[title_id];
|
||||
|
|
@ -194,17 +223,51 @@ void ConfigurePerGameAddons::LoadConfiguration() {
|
|||
|
||||
const auto& disabled = Settings::values.disabled_addons[title_id];
|
||||
|
||||
for (const auto& patch : pm.GetPatches(update_raw)) {
|
||||
update_items.clear();
|
||||
list_items.clear();
|
||||
item_model->removeRows(0, item_model->rowCount());
|
||||
|
||||
std::vector<FileSys::Patch> patches = pm.GetPatches(update_raw);
|
||||
|
||||
bool has_enabled_update = false;
|
||||
|
||||
for (const auto& patch : patches) {
|
||||
const auto name = QString::fromStdString(patch.name);
|
||||
|
||||
auto* const first_item = new QStandardItem;
|
||||
first_item->setText(name);
|
||||
first_item->setCheckable(true);
|
||||
|
||||
const auto patch_disabled =
|
||||
std::find(disabled.begin(), disabled.end(), name.toStdString()) != disabled.end();
|
||||
const bool is_external_update = patch.type == FileSys::PatchType::Update &&
|
||||
patch.source == FileSys::PatchSource::External &&
|
||||
patch.numeric_version != 0;
|
||||
|
||||
first_item->setCheckState(patch_disabled ? Qt::Unchecked : Qt::Checked);
|
||||
if (is_external_update) {
|
||||
first_item->setData(static_cast<quint32>(patch.numeric_version), Qt::UserRole);
|
||||
}
|
||||
|
||||
bool patch_disabled = false;
|
||||
if (is_external_update) {
|
||||
std::string disabled_key = fmt::format("Update@{}", patch.numeric_version);
|
||||
patch_disabled = std::find(disabled.begin(), disabled.end(), disabled_key) != disabled.end();
|
||||
} else {
|
||||
patch_disabled = std::find(disabled.begin(), disabled.end(), name.toStdString()) != disabled.end();
|
||||
}
|
||||
|
||||
bool should_enable = !patch_disabled;
|
||||
|
||||
if (patch.type == FileSys::PatchType::Update) {
|
||||
if (should_enable) {
|
||||
if (has_enabled_update) {
|
||||
should_enable = false;
|
||||
} else {
|
||||
has_enabled_update = true;
|
||||
}
|
||||
}
|
||||
update_items.push_back(first_item);
|
||||
}
|
||||
|
||||
first_item->setCheckState(should_enable ? Qt::Checked : Qt::Unchecked);
|
||||
|
||||
list_items.push_back(QList<QStandardItem*>{
|
||||
first_item, new QStandardItem{QString::fromStdString(patch.version)}});
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue