mirror of
https://github.com/thejerf/baijiSteamVR.git
synced 2026-10-18 15:01:49 +02:00
229 lines
6.6 KiB
C++
229 lines
6.6 KiB
C++
// Copyright 2026 Dolphin Emulator Project
|
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
|
|
#include "DolphinQt/Config/HideObjectWidget.h"
|
|
|
|
#include <QHBoxLayout>
|
|
#include <QLabel>
|
|
#include <QListWidget>
|
|
#include <QPushButton>
|
|
#include <QVBoxLayout>
|
|
|
|
#include "DolphinQt/Config/HideObjectAddEditDialog.h"
|
|
#include "DolphinQt/QtUtils/NonDefaultQPushButton.h"
|
|
#include "VideoCommon/HideObjectEngine.h"
|
|
|
|
HideObjectWidget::HideObjectWidget(std::string game_id, std::optional<u16> revision)
|
|
: m_game_id(std::move(game_id)), m_revision(revision)
|
|
{
|
|
CreateWidgets();
|
|
ConnectWidgets();
|
|
LoadCodes();
|
|
}
|
|
|
|
HideObjectWidget::~HideObjectWidget() = default;
|
|
|
|
void HideObjectWidget::CreateWidgets()
|
|
{
|
|
m_code_list = new QListWidget;
|
|
|
|
m_code_add = new NonDefaultQPushButton(tr("&Add..."));
|
|
m_code_edit = new NonDefaultQPushButton(tr("&Edit..."));
|
|
m_code_remove = new NonDefaultQPushButton(tr("&Remove"));
|
|
m_code_refresh = new NonDefaultQPushButton(tr("Re&fresh List"));
|
|
m_code_reload = new NonDefaultQPushButton(tr("Reload &Codes"));
|
|
|
|
m_code_edit->setEnabled(false);
|
|
m_code_remove->setEnabled(false);
|
|
|
|
auto* info_label = new QLabel(
|
|
tr("Hide object codes suppress rendering of specific vertex data patterns.\n"
|
|
"Use Add to create a new code, or use the Up/Down buttons in the editor\n"
|
|
"to discover codes while the game is running."));
|
|
info_label->setWordWrap(true);
|
|
|
|
auto* button_layout = new QHBoxLayout;
|
|
button_layout->addWidget(m_code_add);
|
|
button_layout->addWidget(m_code_edit);
|
|
button_layout->addWidget(m_code_remove);
|
|
button_layout->addStretch();
|
|
button_layout->addWidget(m_code_refresh);
|
|
button_layout->addWidget(m_code_reload);
|
|
|
|
auto* layout = new QVBoxLayout{this};
|
|
layout->addWidget(info_label);
|
|
layout->addWidget(m_code_list);
|
|
layout->addLayout(button_layout);
|
|
}
|
|
|
|
void HideObjectWidget::ConnectWidgets()
|
|
{
|
|
connect(m_code_list, &QListWidget::itemChanged, this, &HideObjectWidget::OnItemChanged);
|
|
connect(m_code_list, &QListWidget::itemSelectionChanged, this,
|
|
&HideObjectWidget::OnSelectionChanged);
|
|
connect(m_code_add, &QPushButton::clicked, this, &HideObjectWidget::OnAddClicked);
|
|
connect(m_code_edit, &QPushButton::clicked, this, &HideObjectWidget::OnEditClicked);
|
|
connect(m_code_remove, &QPushButton::clicked, this, &HideObjectWidget::OnRemoveClicked);
|
|
connect(m_code_refresh, &QPushButton::clicked, this, &HideObjectWidget::OnRefreshClicked);
|
|
connect(m_code_reload, &QPushButton::clicked, this, &HideObjectWidget::OnReloadClicked);
|
|
}
|
|
|
|
void HideObjectWidget::LoadCodes()
|
|
{
|
|
m_codes = HideObjectEngine::LoadFromINI(m_game_id, m_revision);
|
|
|
|
m_code_list->setEnabled(!m_game_id.empty());
|
|
m_code_edit->setEnabled(false);
|
|
m_code_remove->setEnabled(false);
|
|
|
|
UpdateList();
|
|
}
|
|
|
|
void HideObjectWidget::SaveCodes()
|
|
{
|
|
HideObjectEngine::SaveToINI(m_game_id, m_codes);
|
|
}
|
|
|
|
void HideObjectWidget::UpdateList()
|
|
{
|
|
const QSignalBlocker blocker(m_code_list);
|
|
m_code_list->clear();
|
|
|
|
for (size_t i = 0; i < m_codes.size(); i++)
|
|
{
|
|
const auto& code = m_codes[i];
|
|
|
|
QString display;
|
|
if (!code.entries.empty())
|
|
{
|
|
const auto& entry = code.entries[0];
|
|
const int char_len = HideObjectEngine::GetByteCount(entry.type) * 2;
|
|
QString value_str;
|
|
if (char_len <= 16)
|
|
{
|
|
value_str = QStringLiteral("%1")
|
|
.arg(entry.value_lower, char_len, 16, QLatin1Char('0'))
|
|
.toUpper();
|
|
}
|
|
else
|
|
{
|
|
const int upper_chars = char_len - 16;
|
|
value_str = QStringLiteral("%1%2")
|
|
.arg(entry.value_upper, upper_chars, 16, QLatin1Char('0'))
|
|
.arg(entry.value_lower, 16, 16, QLatin1Char('0'))
|
|
.toUpper();
|
|
}
|
|
|
|
display = QStringLiteral("%1 [%2 %3]")
|
|
.arg(QString::fromStdString(code.name))
|
|
.arg(QString::fromLatin1(HideObjectEngine::GetTypeName(entry.type)))
|
|
.arg(value_str);
|
|
}
|
|
else
|
|
{
|
|
display = QString::fromStdString(code.name);
|
|
}
|
|
|
|
auto* item = new QListWidgetItem(display);
|
|
item->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsUserCheckable);
|
|
item->setCheckState(code.active ? Qt::Checked : Qt::Unchecked);
|
|
item->setData(Qt::UserRole, static_cast<int>(i));
|
|
|
|
m_code_list->addItem(item);
|
|
}
|
|
}
|
|
|
|
void HideObjectWidget::OnItemChanged(QListWidgetItem* item)
|
|
{
|
|
const int row = m_code_list->row(item);
|
|
if (row < 0 || row >= static_cast<int>(m_codes.size()))
|
|
return;
|
|
|
|
m_codes[row].active = (item->checkState() == Qt::Checked);
|
|
SaveCodes();
|
|
HideObjectEngine::Engine::GetInstance().ApplyCodes(m_codes);
|
|
}
|
|
|
|
void HideObjectWidget::OnSelectionChanged()
|
|
{
|
|
const auto items = m_code_list->selectedItems();
|
|
const bool has_selection = !items.empty();
|
|
m_code_edit->setEnabled(has_selection);
|
|
m_code_remove->setEnabled(has_selection);
|
|
}
|
|
|
|
void HideObjectWidget::OnAddClicked()
|
|
{
|
|
HideObjectAddEditDialog dialog(this, nullptr, m_codes);
|
|
if (dialog.exec() == QDialog::Accepted)
|
|
{
|
|
m_codes.push_back(dialog.GetResult());
|
|
SaveCodes();
|
|
UpdateList();
|
|
|
|
// Re-apply codes to runtime engine so the new code takes effect immediately
|
|
HideObjectEngine::Engine::GetInstance().ApplyCodes(m_codes);
|
|
}
|
|
else
|
|
{
|
|
// Dialog was cancelled — restore the full code set to the runtime engine
|
|
// (in case brute-force Up/Down applied temporary codes)
|
|
HideObjectEngine::Engine::GetInstance().ApplyCodes(m_codes);
|
|
}
|
|
}
|
|
|
|
void HideObjectWidget::OnEditClicked()
|
|
{
|
|
const auto items = m_code_list->selectedItems();
|
|
if (items.empty())
|
|
return;
|
|
|
|
const int row = m_code_list->row(items[0]);
|
|
if (row < 0 || row >= static_cast<int>(m_codes.size()))
|
|
return;
|
|
|
|
HideObjectAddEditDialog dialog(this, &m_codes[row], m_codes);
|
|
if (dialog.exec() == QDialog::Accepted)
|
|
{
|
|
m_codes[row] = dialog.GetResult();
|
|
SaveCodes();
|
|
UpdateList();
|
|
|
|
HideObjectEngine::Engine::GetInstance().ApplyCodes(m_codes);
|
|
}
|
|
else
|
|
{
|
|
HideObjectEngine::Engine::GetInstance().ApplyCodes(m_codes);
|
|
}
|
|
}
|
|
|
|
void HideObjectWidget::OnRemoveClicked()
|
|
{
|
|
const auto items = m_code_list->selectedItems();
|
|
if (items.empty())
|
|
return;
|
|
|
|
const int row = m_code_list->row(items[0]);
|
|
if (row < 0 || row >= static_cast<int>(m_codes.size()))
|
|
return;
|
|
|
|
m_codes.erase(m_codes.begin() + row);
|
|
|
|
SaveCodes();
|
|
UpdateList();
|
|
HideObjectEngine::Engine::GetInstance().ApplyCodes(m_codes);
|
|
|
|
m_code_edit->setEnabled(false);
|
|
m_code_remove->setEnabled(false);
|
|
}
|
|
|
|
void HideObjectWidget::OnRefreshClicked()
|
|
{
|
|
LoadCodes();
|
|
}
|
|
|
|
void HideObjectWidget::OnReloadClicked()
|
|
{
|
|
HideObjectEngine::Engine::GetInstance().LoadCodes(m_game_id);
|
|
}
|