mirror of
https://github.com/WinampDesktop/winamp.git
synced 2025-06-18 20:05:47 -04:00
Merge branch 'master' into patch-6
This commit is contained in:
@ -68,6 +68,7 @@ set(TS_FILES
|
||||
translations/duckstation-qt_de.ts
|
||||
translations/duckstation-qt_es.ts
|
||||
translations/duckstation-qt_he.ts
|
||||
translations/duckstation-qt_it.ts
|
||||
translations/duckstation-qt_pt-br.ts
|
||||
translations/duckstation-qt_pt-pt.ts
|
||||
translations/duckstation-qt_zh-cn.ts
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include "advancedsettingswidget.h"
|
||||
#include "mainwindow.h"
|
||||
#include "settingsdialog.h"
|
||||
#include "settingwidgetbinder.h"
|
||||
|
||||
@ -8,7 +9,7 @@ AdvancedSettingsWidget::AdvancedSettingsWidget(QtHostInterface* host_interface,
|
||||
m_ui.setupUi(this);
|
||||
|
||||
for (u32 i = 0; i < static_cast<u32>(LOGLEVEL_COUNT); i++)
|
||||
m_ui.logLevel->addItem(tr(Settings::GetLogLevelDisplayName(static_cast<LOGLEVEL>(i))));
|
||||
m_ui.logLevel->addItem(qApp->translate("LogLevel", Settings::GetLogLevelDisplayName(static_cast<LOGLEVEL>(i))));
|
||||
|
||||
SettingWidgetBinder::BindWidgetToEnumSetting(m_host_interface, m_ui.logLevel, "Logging", "LogLevel",
|
||||
&Settings::ParseLogLevelName, &Settings::GetLogLevelName,
|
||||
@ -27,9 +28,12 @@ AdvancedSettingsWidget::AdvancedSettingsWidget(QtHostInterface* host_interface,
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(m_host_interface, m_ui.cpuRecompilerMemoryExceptions, "CPU",
|
||||
"RecompilerMemoryExceptions", false);
|
||||
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(m_host_interface, m_ui.showDebugMenu, "Main", "ShowDebugMenu");
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(m_host_interface, m_ui.gpuUseDebugDevice, "GPU", "UseDebugDevice");
|
||||
|
||||
connect(m_ui.resetToDefaultButton, &QPushButton::clicked, this, &AdvancedSettingsWidget::onResetToDefaultClicked);
|
||||
connect(m_ui.showDebugMenu, &QCheckBox::toggled, m_host_interface->getMainWindow(),
|
||||
&MainWindow::updateDebugMenuVisibility, Qt::QueuedConnection);
|
||||
|
||||
dialog->registerWidgetHelp(m_ui.gpuUseDebugDevice, tr("Use Debug Host GPU Device"), tr("Unchecked"),
|
||||
tr("Enables the usage of debug devices and shaders for rendering APIs which support them. "
|
||||
|
@ -207,7 +207,14 @@
|
||||
<string>System Settings</string>
|
||||
</property>
|
||||
<layout class="QFormLayout" name="formLayout">
|
||||
<item row="0" column="0" colspan="2">
|
||||
<item row="0" column="0">
|
||||
<widget class="QCheckBox" name="showDebugMenu">
|
||||
<property name="text">
|
||||
<string>Show Debug Menu</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QCheckBox" name="gpuUseDebugDevice">
|
||||
<property name="text">
|
||||
<string>Use Debug Host GPU Device</string>
|
||||
|
@ -11,7 +11,10 @@ AudioSettingsWidget::AudioSettingsWidget(QtHostInterface* host_interface, QWidge
|
||||
m_ui.setupUi(this);
|
||||
|
||||
for (u32 i = 0; i < static_cast<u32>(AudioBackend::Count); i++)
|
||||
m_ui.audioBackend->addItem(tr(Settings::GetAudioBackendDisplayName(static_cast<AudioBackend>(i))));
|
||||
{
|
||||
m_ui.audioBackend->addItem(
|
||||
qApp->translate("AudioBackend", Settings::GetAudioBackendDisplayName(static_cast<AudioBackend>(i))));
|
||||
}
|
||||
|
||||
SettingWidgetBinder::BindWidgetToEnumSetting(m_host_interface, m_ui.audioBackend, "Audio", "Backend",
|
||||
&Settings::ParseAudioBackend, &Settings::GetAudioBackendName,
|
||||
|
@ -39,6 +39,7 @@ Log_SetChannel(AutoUpdaterDialog);
|
||||
static constexpr char LATEST_TAG_URL[] = "https://api.github.com/repos/stenzek/duckstation/tags";
|
||||
static constexpr char LATEST_RELEASE_URL[] =
|
||||
"https://api.github.com/repos/stenzek/duckstation/releases/tags/" SCM_RELEASE_TAG;
|
||||
static constexpr char CHANGES_URL[] = "https://api.github.com/repos/stenzek/duckstation/compare/%s..." SCM_RELEASE_TAG;
|
||||
static constexpr char UPDATE_ASSET_FILENAME[] = SCM_RELEASE_ASSET;
|
||||
|
||||
#endif
|
||||
@ -196,10 +197,11 @@ void AutoUpdaterDialog::getLatestReleaseComplete(QNetworkReply* reply)
|
||||
m_download_url = asset_obj["browser_download_url"].toString();
|
||||
if (!m_download_url.isEmpty())
|
||||
{
|
||||
m_ui.currentVersion->setText(tr("Current Version: %1 (%2)").arg(g_scm_hash_str).arg(__TIMESTAMP__));
|
||||
m_ui.currentVersion->setText(tr("Current Version: %1 (%2)").arg(g_scm_hash_str).arg(g_scm_date_str));
|
||||
m_ui.newVersion->setText(
|
||||
tr("New Version: %1 (%2)").arg(m_latest_sha).arg(doc_object["published_at"].toString()));
|
||||
m_ui.updateNotes->setText(doc_object["body"].toString());
|
||||
m_ui.updateNotes->setText(tr("Loading..."));
|
||||
queueGetChanges();
|
||||
exec();
|
||||
emit updateCheckCompleted();
|
||||
return;
|
||||
@ -223,6 +225,68 @@ void AutoUpdaterDialog::getLatestReleaseComplete(QNetworkReply* reply)
|
||||
#endif
|
||||
}
|
||||
|
||||
void AutoUpdaterDialog::queueGetChanges()
|
||||
{
|
||||
#ifdef AUTO_UPDATER_SUPPORTED
|
||||
connect(m_network_access_mgr, &QNetworkAccessManager::finished, this, &AutoUpdaterDialog::getChangesComplete);
|
||||
|
||||
const std::string url_string(StringUtil::StdStringFromFormat(CHANGES_URL, g_scm_hash_str));
|
||||
QUrl url(QUrl::fromEncoded(QByteArray(url_string.c_str(), static_cast<int>(url_string.size()))));
|
||||
QNetworkRequest request(url);
|
||||
request.setAttribute(QNetworkRequest::FollowRedirectsAttribute, true);
|
||||
m_network_access_mgr->get(request);
|
||||
#endif
|
||||
}
|
||||
|
||||
void AutoUpdaterDialog::getChangesComplete(QNetworkReply* reply)
|
||||
{
|
||||
#ifdef AUTO_UPDATER_SUPPORTED
|
||||
m_network_access_mgr->disconnect(this);
|
||||
reply->deleteLater();
|
||||
|
||||
if (reply->error() == QNetworkReply::NoError)
|
||||
{
|
||||
const QByteArray reply_json(reply->readAll());
|
||||
QJsonParseError parse_error;
|
||||
QJsonDocument doc(QJsonDocument::fromJson(reply_json, &parse_error));
|
||||
if (doc.isObject())
|
||||
{
|
||||
const QJsonObject doc_object(doc.object());
|
||||
|
||||
QString changes_html = QStringLiteral("<ul>");
|
||||
|
||||
const QJsonArray commits(doc_object["commits"].toArray());
|
||||
for (const QJsonValue& commit : commits)
|
||||
{
|
||||
const QJsonObject commit_obj(commit["commit"].toObject());
|
||||
|
||||
QString message = commit_obj["message"].toString();
|
||||
QString author = commit_obj["author"].toObject()["name"].toString();
|
||||
const int first_line_terminator = message.indexOf('\n');
|
||||
if (first_line_terminator >= 0)
|
||||
message.remove(first_line_terminator, message.size() - first_line_terminator);
|
||||
if (!message.isEmpty())
|
||||
changes_html +=
|
||||
QStringLiteral("<li>%1 <i>(%2)</i></li>").arg(message.toHtmlEscaped()).arg(author.toHtmlEscaped());
|
||||
}
|
||||
|
||||
changes_html += "</ul>";
|
||||
m_ui.updateNotes->setText(changes_html);
|
||||
}
|
||||
else
|
||||
{
|
||||
reportError("Change list JSON is not an object");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
reportError("Failed to download change list: %d", static_cast<int>(reply->error()));
|
||||
}
|
||||
#endif
|
||||
|
||||
m_ui.downloadAndInstall->setEnabled(true);
|
||||
}
|
||||
|
||||
void AutoUpdaterDialog::downloadUpdateClicked()
|
||||
{
|
||||
QUrl url(m_download_url);
|
||||
|
@ -28,6 +28,9 @@ private Q_SLOTS:
|
||||
void getLatestTagComplete(QNetworkReply* reply);
|
||||
void getLatestReleaseComplete(QNetworkReply* reply);
|
||||
|
||||
void queueGetChanges();
|
||||
void getChangesComplete(QNetworkReply* reply);
|
||||
|
||||
void downloadUpdateClicked();
|
||||
void skipThisUpdateClicked();
|
||||
void remindMeLaterClicked();
|
||||
|
@ -82,6 +82,9 @@
|
||||
<property name="text">
|
||||
<string>Download and Install...</string>
|
||||
</property>
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
|
@ -11,10 +11,16 @@ ConsoleSettingsWidget::ConsoleSettingsWidget(QtHostInterface* host_interface, QW
|
||||
m_ui.setupUi(this);
|
||||
|
||||
for (u32 i = 0; i < static_cast<u32>(ConsoleRegion::Count); i++)
|
||||
m_ui.region->addItem(tr(Settings::GetConsoleRegionDisplayName(static_cast<ConsoleRegion>(i))));
|
||||
{
|
||||
m_ui.region->addItem(
|
||||
qApp->translate("ConsoleRegion", Settings::GetConsoleRegionDisplayName(static_cast<ConsoleRegion>(i))));
|
||||
}
|
||||
|
||||
for (u32 i = 0; i < static_cast<u32>(CPUExecutionMode::Count); i++)
|
||||
m_ui.cpuExecutionMode->addItem(tr(Settings::GetCPUExecutionModeDisplayName(static_cast<CPUExecutionMode>(i))));
|
||||
{
|
||||
m_ui.cpuExecutionMode->addItem(
|
||||
qApp->translate("CPUExecutionMode", Settings::GetCPUExecutionModeDisplayName(static_cast<CPUExecutionMode>(i))));
|
||||
}
|
||||
|
||||
SettingWidgetBinder::BindWidgetToEnumSetting(m_host_interface, m_ui.region, "Console", "Region",
|
||||
&Settings::ParseConsoleRegionName, &Settings::GetConsoleRegionName,
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include <QtCore/QSignalBlocker>
|
||||
#include <QtCore/QTimer>
|
||||
#include <QtGui/QCursor>
|
||||
#include <QtGui/QGuiApplication>
|
||||
#include <QtGui/QKeyEvent>
|
||||
#include <QtWidgets/QFileDialog>
|
||||
#include <QtWidgets/QInputDialog>
|
||||
@ -48,7 +49,7 @@ void ControllerSettingsWidget::onProfileLoaded()
|
||||
ControllerType ctype = Settings::ParseControllerTypeName(
|
||||
m_host_interface
|
||||
->GetStringSettingValue(QStringLiteral("Controller%1").arg(i + 1).toStdString().c_str(),
|
||||
QStringLiteral("Type").toStdString().c_str())
|
||||
QStringLiteral("Type").toStdString().c_str())
|
||||
.c_str())
|
||||
.value_or(ControllerType::None);
|
||||
|
||||
@ -86,7 +87,7 @@ void ControllerSettingsWidget::createPortSettingsUi(int index, PortSettingsUI* u
|
||||
for (int i = 0; i < static_cast<int>(ControllerType::Count); i++)
|
||||
{
|
||||
ui->controller_type->addItem(
|
||||
QString::fromUtf8(Settings::GetControllerTypeDisplayName(static_cast<ControllerType>(i))));
|
||||
qApp->translate("ControllerType", Settings::GetControllerTypeDisplayName(static_cast<ControllerType>(i))));
|
||||
}
|
||||
ControllerType ctype =
|
||||
Settings::ParseControllerTypeName(
|
||||
|
@ -212,6 +212,7 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="translations\duckstation-qt_es.ts" />
|
||||
<None Include="translations\duckstation-qt_it.ts" />
|
||||
</ItemGroup>
|
||||
<Target Name="CopyCommonDataFiles" AfterTargets="Build" Inputs="@(CommonDataFiles)" Outputs="@(CommonDataFiles -> '$(BinaryOutputDir)%(RecursiveDir)%(Filename)%(Extension)')">
|
||||
<Message Text="Copying common data files" Importance="High" />
|
||||
|
@ -113,15 +113,28 @@
|
||||
<Image Include="duckstation-qt.ico" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<QtTs Include="translations\duckstation-qt_de.ts" />
|
||||
<QtTs Include="translations\duckstation-qt_he.ts" />
|
||||
<QtTs Include="translations\duckstation-qt_pt-br.ts" />
|
||||
<QtTs Include="translations\duckstation-qt_pt-pt.ts" />
|
||||
<QtTs Include="translations\duckstation-qt_zh-cn.ts" />
|
||||
<QtTs Include="translations\duckstation-qt_de.ts">
|
||||
<Filter>translations</Filter>
|
||||
</QtTs>
|
||||
<QtTs Include="translations\duckstation-qt_he.ts">
|
||||
<Filter>translations</Filter>
|
||||
</QtTs>
|
||||
<QtTs Include="translations\duckstation-qt_pt-br.ts">
|
||||
<Filter>translations</Filter>
|
||||
</QtTs>
|
||||
<QtTs Include="translations\duckstation-qt_pt-pt.ts">
|
||||
<Filter>translations</Filter>
|
||||
</QtTs>
|
||||
<QtTs Include="translations\duckstation-qt_zh-cn.ts">
|
||||
<Filter>translations</Filter>
|
||||
</QtTs>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="translations\duckstation-qt_es.ts">
|
||||
<Filter>translations</Filter>
|
||||
</None>
|
||||
<None Include="translations\duckstation-qt_it.ts">
|
||||
<Filter>translations</Filter>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
</Project>
|
@ -74,6 +74,11 @@ void GamePropertiesDialog::populate(const GameListEntry* ge)
|
||||
}
|
||||
|
||||
populateTracksInfo(ge->path);
|
||||
|
||||
m_game_code = ge->code;
|
||||
m_game_title = ge->title;
|
||||
m_game_settings = ge->settings;
|
||||
populateGameSettings();
|
||||
}
|
||||
|
||||
void GamePropertiesDialog::populateCompatibilityInfo(const std::string& game_code)
|
||||
@ -99,12 +104,50 @@ void GamePropertiesDialog::populateCompatibilityInfo(const std::string& game_cod
|
||||
void GamePropertiesDialog::setupAdditionalUi()
|
||||
{
|
||||
for (u8 i = 0; i < static_cast<u8>(DiscRegion::Count); i++)
|
||||
m_ui.region->addItem(tr(Settings::GetDiscRegionDisplayName(static_cast<DiscRegion>(i))));
|
||||
m_ui.region->addItem(qApp->translate("DiscRegion", Settings::GetDiscRegionDisplayName(static_cast<DiscRegion>(i))));
|
||||
|
||||
for (int i = 0; i < static_cast<int>(GameListCompatibilityRating::Count); i++)
|
||||
{
|
||||
m_ui.compatibility->addItem(
|
||||
tr(GameList::GetGameListCompatibilityRatingString(static_cast<GameListCompatibilityRating>(i))));
|
||||
qApp->translate("GameListCompatibilityRating",
|
||||
GameList::GetGameListCompatibilityRatingString(static_cast<GameListCompatibilityRating>(i))));
|
||||
}
|
||||
|
||||
m_ui.userAspectRatio->addItem(tr("(unchanged)"));
|
||||
for (u32 i = 0; i < static_cast<u32>(DisplayAspectRatio::Count); i++)
|
||||
{
|
||||
m_ui.userAspectRatio->addItem(
|
||||
QString::fromUtf8(Settings::GetDisplayAspectRatioName(static_cast<DisplayAspectRatio>(i))));
|
||||
}
|
||||
|
||||
m_ui.userCropMode->addItem(tr("(unchanged)"));
|
||||
for (u32 i = 0; i < static_cast<u32>(DisplayCropMode::Count); i++)
|
||||
{
|
||||
m_ui.userCropMode->addItem(
|
||||
qApp->translate("DisplayCropMode", Settings::GetDisplayCropModeDisplayName(static_cast<DisplayCropMode>(i))));
|
||||
}
|
||||
|
||||
m_ui.userControllerType1->addItem(tr("(unchanged)"));
|
||||
for (u32 i = 0; i < static_cast<u32>(ControllerType::Count); i++)
|
||||
{
|
||||
m_ui.userControllerType1->addItem(
|
||||
qApp->translate("ControllerType", Settings::GetControllerTypeDisplayName(static_cast<ControllerType>(i))));
|
||||
}
|
||||
|
||||
m_ui.userControllerType2->addItem(tr("(unchanged)"));
|
||||
for (u32 i = 0; i < static_cast<u32>(ControllerType::Count); i++)
|
||||
{
|
||||
m_ui.userControllerType2->addItem(
|
||||
qApp->translate("ControllerType", Settings::GetControllerTypeDisplayName(static_cast<ControllerType>(i))));
|
||||
}
|
||||
|
||||
QGridLayout* traits_layout = new QGridLayout(m_ui.compatibilityTraits);
|
||||
for (u32 i = 0; i < static_cast<u32>(GameSettings::Trait::Count); i++)
|
||||
{
|
||||
m_trait_checkboxes[i] = new QCheckBox(
|
||||
qApp->translate("GameSettingsTrait", GameSettings::GetTraitDisplayName(static_cast<GameSettings::Trait>(i))),
|
||||
m_ui.compatibilityTraits);
|
||||
traits_layout->addWidget(m_trait_checkboxes[i], i / 2, i % 2);
|
||||
}
|
||||
|
||||
setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
|
||||
@ -133,7 +176,7 @@ void GamePropertiesDialog::populateTracksInfo(const std::string& image_path)
|
||||
{"Audio", "Mode 1", "Mode 1/Raw", "Mode 2", "Mode 2/Form 1", "Mode 2/Form 2", "Mode 2/Mix", "Mode 2/Raw"}};
|
||||
|
||||
m_ui.tracks->clearContents();
|
||||
m_image_path = image_path;
|
||||
m_path = image_path;
|
||||
|
||||
std::unique_ptr<CDImage> image = CDImage::Open(image_path.c_str());
|
||||
if (!image)
|
||||
@ -147,14 +190,74 @@ void GamePropertiesDialog::populateTracksInfo(const std::string& image_path)
|
||||
const CDImage::TrackMode mode = image->GetTrackMode(static_cast<u8>(track));
|
||||
const int row = static_cast<int>(track - 1u);
|
||||
m_ui.tracks->insertRow(row);
|
||||
m_ui.tracks->setItem(row, 0, new QTableWidgetItem(tr("%1").arg(track)));
|
||||
m_ui.tracks->setItem(row, 1, new QTableWidgetItem(tr(track_mode_strings[static_cast<u32>(mode)])));
|
||||
m_ui.tracks->setItem(row, 0, new QTableWidgetItem(QStringLiteral("%1").arg(track)));
|
||||
m_ui.tracks->setItem(row, 1, new QTableWidgetItem(track_mode_strings[static_cast<u32>(mode)]));
|
||||
m_ui.tracks->setItem(row, 2, new QTableWidgetItem(MSFTotString(position)));
|
||||
m_ui.tracks->setItem(row, 3, new QTableWidgetItem(MSFTotString(length)));
|
||||
m_ui.tracks->setItem(row, 4, new QTableWidgetItem(tr("<not computed>")));
|
||||
}
|
||||
}
|
||||
|
||||
void GamePropertiesDialog::populateGameSettings()
|
||||
{
|
||||
const GameSettings::Entry& gs = m_game_settings;
|
||||
|
||||
for (u32 i = 0; i < static_cast<u32>(GameSettings::Trait::Count); i++)
|
||||
{
|
||||
QSignalBlocker sb(m_trait_checkboxes[i]);
|
||||
m_trait_checkboxes[i]->setChecked(gs.HasTrait(static_cast<GameSettings::Trait>(i)));
|
||||
}
|
||||
|
||||
if (gs.display_active_start_offset.has_value())
|
||||
{
|
||||
QSignalBlocker sb(m_ui.displayActiveStartOffset);
|
||||
m_ui.displayActiveStartOffset->setValue(static_cast<int>(gs.display_active_start_offset.value()));
|
||||
}
|
||||
if (gs.display_active_end_offset.has_value())
|
||||
{
|
||||
QSignalBlocker sb(m_ui.displayActiveEndOffset);
|
||||
m_ui.displayActiveEndOffset->setValue(static_cast<int>(gs.display_active_end_offset.value()));
|
||||
}
|
||||
|
||||
if (gs.display_crop_mode.has_value())
|
||||
{
|
||||
QSignalBlocker sb(m_ui.userCropMode);
|
||||
m_ui.userCropMode->setCurrentIndex(static_cast<int>(gs.display_crop_mode.value()) + 1);
|
||||
}
|
||||
if (gs.display_aspect_ratio.has_value())
|
||||
{
|
||||
QSignalBlocker sb(m_ui.userAspectRatio);
|
||||
m_ui.userAspectRatio->setCurrentIndex(static_cast<int>(gs.display_aspect_ratio.value()) + 1);
|
||||
}
|
||||
|
||||
if (gs.controller_1_type.has_value())
|
||||
{
|
||||
QSignalBlocker sb(m_ui.userControllerType1);
|
||||
m_ui.userControllerType1->setCurrentIndex(static_cast<int>(gs.controller_1_type.value()) + 1);
|
||||
}
|
||||
if (gs.controller_2_type.has_value())
|
||||
{
|
||||
QSignalBlocker sb(m_ui.userControllerType2);
|
||||
m_ui.userControllerType2->setCurrentIndex(static_cast<int>(gs.controller_2_type.value()) + 1);
|
||||
}
|
||||
if (gs.gpu_widescreen_hack.has_value())
|
||||
{
|
||||
QSignalBlocker sb(m_ui.userControllerType2);
|
||||
m_ui.userWidescreenHack->setCheckState(Qt::Checked);
|
||||
}
|
||||
else
|
||||
{
|
||||
QSignalBlocker sb(m_ui.userControllerType2);
|
||||
m_ui.userWidescreenHack->setCheckState(Qt::PartiallyChecked);
|
||||
}
|
||||
}
|
||||
|
||||
void GamePropertiesDialog::saveGameSettings()
|
||||
{
|
||||
m_host_interface->getGameList()->UpdateGameSettings(m_path, m_game_code, m_game_title, m_game_settings, true, true);
|
||||
m_host_interface->applySettings(true);
|
||||
}
|
||||
|
||||
void GamePropertiesDialog::closeEvent(QCloseEvent* ev)
|
||||
{
|
||||
deleteLater();
|
||||
@ -186,6 +289,69 @@ void GamePropertiesDialog::connectUi()
|
||||
connect(m_ui.exportCompatibilityInfo, &QPushButton::clicked, this,
|
||||
&GamePropertiesDialog::onExportCompatibilityInfoClicked);
|
||||
connect(m_ui.close, &QPushButton::clicked, this, &QDialog::close);
|
||||
|
||||
connect(m_ui.userAspectRatio, QOverload<int>::of(&QComboBox::currentIndexChanged), [this](int index) {
|
||||
if (index <= 0)
|
||||
m_game_settings.display_aspect_ratio.reset();
|
||||
else
|
||||
m_game_settings.display_aspect_ratio = static_cast<DisplayAspectRatio>(index - 1);
|
||||
saveGameSettings();
|
||||
});
|
||||
|
||||
connect(m_ui.userCropMode, QOverload<int>::of(&QComboBox::currentIndexChanged), [this](int index) {
|
||||
if (index <= 0)
|
||||
m_game_settings.display_crop_mode.reset();
|
||||
else
|
||||
m_game_settings.display_crop_mode = static_cast<DisplayCropMode>(index - 1);
|
||||
saveGameSettings();
|
||||
});
|
||||
|
||||
connect(m_ui.userControllerType1, QOverload<int>::of(&QComboBox::currentIndexChanged), [this](int index) {
|
||||
if (index <= 0)
|
||||
m_game_settings.controller_1_type.reset();
|
||||
else
|
||||
m_game_settings.controller_1_type = static_cast<ControllerType>(index - 1);
|
||||
saveGameSettings();
|
||||
});
|
||||
|
||||
connect(m_ui.userControllerType2, QOverload<int>::of(&QComboBox::currentIndexChanged), [this](int index) {
|
||||
if (index <= 0)
|
||||
m_game_settings.controller_2_type.reset();
|
||||
else
|
||||
m_game_settings.controller_2_type = static_cast<ControllerType>(index - 1);
|
||||
saveGameSettings();
|
||||
});
|
||||
|
||||
connect(m_ui.userWidescreenHack, &QCheckBox::stateChanged, [this](int state) {
|
||||
if (state == Qt::PartiallyChecked)
|
||||
m_game_settings.gpu_widescreen_hack.reset();
|
||||
else
|
||||
m_game_settings.gpu_widescreen_hack = (state == Qt::Checked);
|
||||
saveGameSettings();
|
||||
});
|
||||
|
||||
for (u32 i = 0; i < static_cast<u32>(GameSettings::Trait::Count); i++)
|
||||
{
|
||||
connect(m_trait_checkboxes[i], &QCheckBox::toggled, [this, i](bool checked) {
|
||||
m_game_settings.SetTrait(static_cast<GameSettings::Trait>(i), checked);
|
||||
saveGameSettings();
|
||||
});
|
||||
}
|
||||
|
||||
connect(m_ui.displayActiveStartOffset, QOverload<int>::of(&QSpinBox::valueChanged), [this](int value) {
|
||||
if (value == 0)
|
||||
m_game_settings.display_active_start_offset.reset();
|
||||
else
|
||||
m_game_settings.display_active_start_offset = static_cast<s16>(value);
|
||||
saveGameSettings();
|
||||
});
|
||||
connect(m_ui.displayActiveEndOffset, QOverload<int>::of(&QSpinBox::valueChanged), [this](int value) {
|
||||
if (value == 0)
|
||||
m_game_settings.display_active_end_offset.reset();
|
||||
else
|
||||
m_game_settings.display_active_end_offset = static_cast<s16>(value);
|
||||
saveGameSettings();
|
||||
});
|
||||
}
|
||||
|
||||
void GamePropertiesDialog::fillEntryFromUi(GameListCompatibilityEntry* entry)
|
||||
@ -263,10 +429,10 @@ void GamePropertiesDialog::onExportCompatibilityInfoClicked()
|
||||
|
||||
void GamePropertiesDialog::computeTrackHashes()
|
||||
{
|
||||
if (m_image_path.empty())
|
||||
if (m_path.empty())
|
||||
return;
|
||||
|
||||
std::unique_ptr<CDImage> image = CDImage::Open(m_image_path.c_str());
|
||||
std::unique_ptr<CDImage> image = CDImage::Open(m_path.c_str());
|
||||
if (!image)
|
||||
return;
|
||||
|
||||
|
@ -1,6 +1,8 @@
|
||||
#pragma once
|
||||
#include "core/game_settings.h"
|
||||
#include "ui_gamepropertiesdialog.h"
|
||||
#include <QtWidgets/QDialog>
|
||||
#include <array>
|
||||
|
||||
struct GameListEntry;
|
||||
struct GameListCompatibilityEntry;
|
||||
@ -40,15 +42,22 @@ private:
|
||||
void connectUi();
|
||||
void populateCompatibilityInfo(const std::string& game_code);
|
||||
void populateTracksInfo(const std::string& image_path);
|
||||
void populateGameSettings();
|
||||
void saveGameSettings();
|
||||
void fillEntryFromUi(GameListCompatibilityEntry* entry);
|
||||
void computeTrackHashes();
|
||||
void onResize();
|
||||
|
||||
Ui::GamePropertiesDialog m_ui;
|
||||
std::array<QCheckBox*, static_cast<u32>(GameSettings::Trait::Count)> m_trait_checkboxes{};
|
||||
|
||||
QtHostInterface* m_host_interface;
|
||||
|
||||
std::string m_image_path;
|
||||
std::string m_path;
|
||||
std::string m_game_code;
|
||||
std::string m_game_title;
|
||||
|
||||
GameSettings::Entry m_game_settings;
|
||||
|
||||
bool m_compatibility_info_changed = false;
|
||||
bool m_tracks_hashed = false;
|
||||
|
@ -6,171 +6,346 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>722</width>
|
||||
<height>466</height>
|
||||
<width>793</width>
|
||||
<height>647</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Dialog</string>
|
||||
</property>
|
||||
<property name="windowIcon">
|
||||
<iconset resource="resources/icons.qrc">
|
||||
<iconset>
|
||||
<normaloff>:/icons/duck.png</normaloff>:/icons/duck.png</iconset>
|
||||
</property>
|
||||
<layout class="QFormLayout" name="formLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>Image Path:</string>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QTabWidget" name="tabWidget">
|
||||
<property name="currentIndex">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="tab">
|
||||
<attribute name="title">
|
||||
<string>Properties</string>
|
||||
</attribute>
|
||||
<layout class="QFormLayout" name="formLayout_2">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>Image Path:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLineEdit" name="imagePath">
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Game Code:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLineEdit" name="gameCode">
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Title:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QLineEdit" name="title">
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>Region:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QComboBox" name="region">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="label_7">
|
||||
<property name="text">
|
||||
<string>Compatibility:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="QComboBox" name="compatibility"/>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<widget class="QLabel" name="label_6">
|
||||
<property name="text">
|
||||
<string>Upscaling Issues:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="1">
|
||||
<widget class="QLineEdit" name="upscalingIssues"/>
|
||||
</item>
|
||||
<item row="6" column="0">
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="text">
|
||||
<string>Comments:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="1">
|
||||
<widget class="QLineEdit" name="comments"/>
|
||||
</item>
|
||||
<item row="7" column="0">
|
||||
<widget class="QLabel" name="label_9">
|
||||
<property name="text">
|
||||
<string>Version Tested:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="1">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<item>
|
||||
<widget class="QLineEdit" name="versionTested"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="setToCurrent">
|
||||
<property name="text">
|
||||
<string>Set to Current</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="8" column="0" colspan="2">
|
||||
<widget class="QLabel" name="label_8">
|
||||
<property name="text">
|
||||
<string>Tracks:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="9" column="0" colspan="2">
|
||||
<widget class="QTableWidget" name="tracks">
|
||||
<property name="editTriggers">
|
||||
<set>QAbstractItemView::NoEditTriggers</set>
|
||||
</property>
|
||||
<property name="cornerButtonEnabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<attribute name="verticalHeaderVisible">
|
||||
<bool>false</bool>
|
||||
</attribute>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>#</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Mode</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Start</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Length</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Hash</string>
|
||||
</property>
|
||||
</column>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="tab_3">
|
||||
<attribute name="title">
|
||||
<string>User Settings</string>
|
||||
</attribute>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_4">
|
||||
<property name="title">
|
||||
<string>GPU Settings</string>
|
||||
</property>
|
||||
<layout class="QFormLayout" name="formLayout_5">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_17">
|
||||
<property name="text">
|
||||
<string>Crop Mode:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QComboBox" name="userCropMode"/>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_18">
|
||||
<property name="text">
|
||||
<string>Aspect Ratio:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QComboBox" name="userAspectRatio"/>
|
||||
</item>
|
||||
<item row="2" column="0" colspan="2">
|
||||
<widget class="QCheckBox" name="userWidescreenHack">
|
||||
<property name="text">
|
||||
<string>Widescreen Hack</string>
|
||||
</property>
|
||||
<property name="tristate">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_3">
|
||||
<property name="title">
|
||||
<string>Controller Settings</string>
|
||||
</property>
|
||||
<layout class="QFormLayout" name="formLayout_4">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_15">
|
||||
<property name="text">
|
||||
<string>Controller 1 Type:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QComboBox" name="userControllerType1"/>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_16">
|
||||
<property name="text">
|
||||
<string>Controller 2 Type:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QComboBox" name="userControllerType2"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="tab_2">
|
||||
<attribute name="title">
|
||||
<string>Compatibility Settings</string>
|
||||
</attribute>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<widget class="QGroupBox" name="compatibilityTraits">
|
||||
<property name="title">
|
||||
<string>Traits</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="compatibilityOverrides">
|
||||
<property name="title">
|
||||
<string>Overrides</string>
|
||||
</property>
|
||||
<layout class="QFormLayout" name="formLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_10">
|
||||
<property name="text">
|
||||
<string>Display Active Offset:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QSpinBox" name="displayActiveStartOffset">
|
||||
<property name="minimum">
|
||||
<number>-5000</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>5000</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>0</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSpinBox" name="displayActiveEndOffset">
|
||||
<property name="minimum">
|
||||
<number>-5000</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>5000</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>0</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLineEdit" name="imagePath">
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Game Code:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLineEdit" name="gameCode">
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Title:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QLineEdit" name="title">
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>Region:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QComboBox" name="region">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="label_7">
|
||||
<property name="text">
|
||||
<string>Compatibility:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="QComboBox" name="compatibility"/>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<widget class="QLabel" name="label_6">
|
||||
<property name="text">
|
||||
<string>Upscaling Issues:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="1">
|
||||
<widget class="QLineEdit" name="upscalingIssues"/>
|
||||
</item>
|
||||
<item row="6" column="0">
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="text">
|
||||
<string>Comments:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="1">
|
||||
<widget class="QLineEdit" name="comments"/>
|
||||
</item>
|
||||
<item row="7" column="0">
|
||||
<widget class="QLabel" name="label_9">
|
||||
<property name="text">
|
||||
<string>Version Tested:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="1">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<item>
|
||||
<widget class="QLineEdit" name="versionTested"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="setToCurrent">
|
||||
<property name="text">
|
||||
<string>Set to Current</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="8" column="0">
|
||||
<widget class="QLabel" name="label_8">
|
||||
<property name="text">
|
||||
<string>Tracks:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="1">
|
||||
<widget class="QTableWidget" name="tracks">
|
||||
<property name="editTriggers">
|
||||
<set>QAbstractItemView::NoEditTriggers</set>
|
||||
</property>
|
||||
<property name="cornerButtonEnabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<attribute name="verticalHeaderVisible">
|
||||
<bool>false</bool>
|
||||
</attribute>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>#</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Mode</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Start</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Length</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Hash</string>
|
||||
</property>
|
||||
</column>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="10" column="0" colspan="2">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
|
@ -16,12 +16,15 @@ GeneralSettingsWidget::GeneralSettingsWidget(QtHostInterface* host_interface, QW
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(m_host_interface, m_ui.confirmPowerOff, "Main", "ConfirmPowerOff", true);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(m_host_interface, m_ui.loadDevicesFromSaveStates, "Main",
|
||||
"LoadDevicesFromSaveStates", false);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(m_host_interface, m_ui.applyGameSettings, "Main", "ApplyGameSettings",
|
||||
true);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(m_host_interface, m_ui.showOSDMessages, "Display", "ShowOSDMessages",
|
||||
true);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(m_host_interface, m_ui.showFPS, "Display", "ShowFPS", false);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(m_host_interface, m_ui.showVPS, "Display", "ShowVPS", false);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(m_host_interface, m_ui.showSpeed, "Display", "ShowSpeed", false);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(m_host_interface, m_ui.showResolution, "Display", "ShowResolution", false);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(m_host_interface, m_ui.showResolution, "Display", "ShowResolution",
|
||||
false);
|
||||
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(m_host_interface, m_ui.enableSpeedLimiter, "Main", "SpeedLimiterEnabled",
|
||||
true);
|
||||
@ -57,6 +60,10 @@ GeneralSettingsWidget::GeneralSettingsWidget(QtHostInterface* host_interface, QW
|
||||
tr("When enabled, memory cards and controllers will be overwritten when save states are loaded. This can "
|
||||
"result in lost saves, and controller type mismatches. For deterministic save states, enable this option, "
|
||||
"otherwise leave disabled."));
|
||||
dialog->registerWidgetHelp(
|
||||
m_ui.applyGameSettings, tr("Apply Per-Game Settings"), tr("Checked"),
|
||||
tr("When enabled, per-game settings will be applied, and incompatible enhancements will be disabled. You should "
|
||||
"leave this option enabled except when testing enhancements with incompatible games."));
|
||||
dialog->registerWidgetHelp(
|
||||
m_ui.enableSpeedLimiter, tr("Enable Speed Limiter"), tr("Checked"),
|
||||
tr("Throttles the emulation speed to the chosen speed above. If unchecked, the emulator will "
|
||||
@ -82,26 +89,33 @@ GeneralSettingsWidget::GeneralSettingsWidget(QtHostInterface* host_interface, QW
|
||||
tr("Shows the current emulation speed of the system in the top-right corner of the display as a percentage."));
|
||||
|
||||
// Since this one is compile-time selected, we don't put it in the .ui file.
|
||||
const int last_row_count = m_ui.formLayout_4->rowCount();
|
||||
int current_col = 1;
|
||||
int current_row = m_ui.formLayout_4->rowCount() - current_col;
|
||||
#ifdef WITH_DISCORD_PRESENCE
|
||||
{
|
||||
QCheckBox* enableDiscordPresence = new QCheckBox(tr("Enable Discord Presence"), m_ui.groupBox_4);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(m_host_interface, enableDiscordPresence, "Main",
|
||||
"EnableDiscordPresence");
|
||||
m_ui.formLayout_4->addWidget(enableDiscordPresence, last_row_count, 0);
|
||||
m_ui.formLayout_4->addWidget(enableDiscordPresence, current_row, current_col);
|
||||
dialog->registerWidgetHelp(enableDiscordPresence, tr("Enable Discord Presence"), tr("Unchecked"),
|
||||
tr("Shows the game you are currently playing as part of your profile in Discord."));
|
||||
current_col++;
|
||||
current_row += (current_col / 2);
|
||||
current_col %= 2;
|
||||
}
|
||||
#endif
|
||||
if (AutoUpdaterDialog::isSupported())
|
||||
{
|
||||
QCheckBox* enableDiscordPresence = new QCheckBox(tr("Enable Automatic Update Check"), m_ui.groupBox_4);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(m_host_interface, enableDiscordPresence, "AutoUpdater",
|
||||
"CheckAtStartup");
|
||||
m_ui.formLayout_4->addWidget(enableDiscordPresence, last_row_count, 1);
|
||||
"CheckAtStartup", true);
|
||||
m_ui.formLayout_4->addWidget(enableDiscordPresence, current_row, current_col);
|
||||
dialog->registerWidgetHelp(enableDiscordPresence, tr("Enable Automatic Update Check"), tr("Checked"),
|
||||
tr("Automatically checks for updates to the program on startup. Updates can be deferred "
|
||||
"until later or skipped entirely."));
|
||||
current_col++;
|
||||
current_row += (current_col / 2);
|
||||
current_col %= 2;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -32,6 +32,20 @@
|
||||
<string>Behaviour</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="formLayout_4">
|
||||
<item row="0" column="1">
|
||||
<widget class="QCheckBox" name="confirmPowerOff">
|
||||
<property name="text">
|
||||
<string>Confirm Power Off</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QCheckBox" name="renderToMain">
|
||||
<property name="text">
|
||||
<string>Render To Main Window</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QCheckBox" name="pauseOnStart">
|
||||
<property name="text">
|
||||
@ -39,10 +53,10 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QCheckBox" name="confirmPowerOff">
|
||||
<item row="2" column="0">
|
||||
<widget class="QCheckBox" name="startFullscreen">
|
||||
<property name="text">
|
||||
<string>Confirm Power Off</string>
|
||||
<string>Start Fullscreen</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@ -60,17 +74,10 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QCheckBox" name="startFullscreen">
|
||||
<item row="3" column="0">
|
||||
<widget class="QCheckBox" name="applyGameSettings">
|
||||
<property name="text">
|
||||
<string>Start Fullscreen</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QCheckBox" name="renderToMain">
|
||||
<property name="text">
|
||||
<string>Render To Main Window</string>
|
||||
<string>Apply Per-Game Settings</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
@ -44,6 +44,7 @@ GPUSettingsWidget::GPUSettingsWidget(QtHostInterface* host_interface, QWidget* p
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(m_host_interface, m_ui.pgxpTextureCorrection, "GPU",
|
||||
"PGXPTextureCorrection", true);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(m_host_interface, m_ui.pgxpVertexCache, "GPU", "PGXPVertexCache", false);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(m_host_interface, m_ui.pgxpCPUMode, "GPU", "PGXPCPUMode", false);
|
||||
|
||||
connect(m_ui.resolutionScale, QOverload<int>::of(&QComboBox::currentIndexChanged), this,
|
||||
&GPUSettingsWidget::updateScaledDitheringEnabled);
|
||||
@ -128,7 +129,8 @@ GPUSettingsWidget::GPUSettingsWidget(QtHostInterface* host_interface, QWidget* p
|
||||
m_ui.widescreenHack, tr("Widescreen Hack"), tr("Unchecked"),
|
||||
tr("Scales vertex positions in screen-space to a widescreen aspect ratio, essentially "
|
||||
"increasing the field of view from 4:3 to 16:9 in 3D games. <br>For 2D games, or games which "
|
||||
"use pre-rendered backgrounds, this enhancement will not work as expected. <b><u>May not be compatible with all games.</u></b>"));
|
||||
"use pre-rendered backgrounds, this enhancement will not work as expected. <b><u>May not be compatible with all "
|
||||
"games.</u></b>"));
|
||||
dialog->registerWidgetHelp(
|
||||
m_ui.pgxpEnable, tr("Geometry Correction"), tr("Unchecked"),
|
||||
tr("Reduces \"wobbly\" polygons and \"warping\" textures that are common in PS1 games. <br>Only "
|
||||
@ -142,6 +144,10 @@ GPUSettingsWidget::GPUSettingsWidget(QtHostInterface* host_interface, QWidget* p
|
||||
dialog->registerWidgetHelp(m_ui.pgxpVertexCache, tr("Vertex Cache"), tr("Unchecked"),
|
||||
tr("Uses screen coordinates as a fallback when tracking vertices through memory fails. "
|
||||
"May improve PGXP compatibility."));
|
||||
dialog->registerWidgetHelp(
|
||||
m_ui.pgxpCPUMode, tr("CPU Mode"), tr("Unchecked"),
|
||||
tr("Tries to track vertex manipulation through the CPU. Some games require this option for PGXP to be effective. "
|
||||
"Very slow, and incompatible with the recompiler."));
|
||||
}
|
||||
|
||||
GPUSettingsWidget::~GPUSettingsWidget() = default;
|
||||
@ -157,7 +163,10 @@ void GPUSettingsWidget::updateScaledDitheringEnabled()
|
||||
void GPUSettingsWidget::setupAdditionalUi()
|
||||
{
|
||||
for (u32 i = 0; i < static_cast<u32>(GPURenderer::Count); i++)
|
||||
m_ui.renderer->addItem(QString::fromUtf8(Settings::GetRendererDisplayName(static_cast<GPURenderer>(i))));
|
||||
{
|
||||
m_ui.renderer->addItem(
|
||||
qApp->translate("GPURenderer", Settings::GetRendererDisplayName(static_cast<GPURenderer>(i))));
|
||||
}
|
||||
|
||||
for (u32 i = 0; i < static_cast<u32>(DisplayAspectRatio::Count); i++)
|
||||
{
|
||||
@ -168,7 +177,7 @@ void GPUSettingsWidget::setupAdditionalUi()
|
||||
for (u32 i = 0; i < static_cast<u32>(DisplayCropMode::Count); i++)
|
||||
{
|
||||
m_ui.displayCropMode->addItem(
|
||||
QString::fromUtf8(Settings::GetDisplayCropModeDisplayName(static_cast<DisplayCropMode>(i))));
|
||||
qApp->translate("DisplayCropMode", Settings::GetDisplayCropModeDisplayName(static_cast<DisplayCropMode>(i))));
|
||||
}
|
||||
|
||||
std::array<QString, GPU::MAX_RESOLUTION_SCALE + 1> resolution_suffixes = {{
|
||||
@ -255,4 +264,5 @@ void GPUSettingsWidget::updatePGXPSettingsEnabled()
|
||||
m_ui.pgxpCulling->setEnabled(enabled);
|
||||
m_ui.pgxpTextureCorrection->setEnabled(enabled);
|
||||
m_ui.pgxpVertexCache->setEnabled(enabled);
|
||||
m_ui.pgxpCPUMode->setEnabled(enabled);
|
||||
}
|
||||
|
@ -215,6 +215,13 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="pgxpCPUMode">
|
||||
<property name="text">
|
||||
<string>CPU Mode</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
|
@ -4,6 +4,7 @@
|
||||
#include "inputbindingwidgets.h"
|
||||
#include "qthostinterface.h"
|
||||
#include "qtutils.h"
|
||||
#include <QtCore/QCoreApplication>
|
||||
#include <QtCore/QTimer>
|
||||
#include <QtGui/QKeyEvent>
|
||||
#include <QtWidgets/QGridLayout>
|
||||
@ -63,7 +64,7 @@ void HotkeySettingsWidget::createButtons()
|
||||
|
||||
std::string section_name("Hotkeys");
|
||||
std::string key_name(hi.name.GetCharArray());
|
||||
layout->addWidget(new QLabel(QString::fromUtf8(hi.display_name), container), target_row, 0);
|
||||
layout->addWidget(new QLabel(qApp->translate("Hotkeys", hi.display_name), container), target_row, 0);
|
||||
layout->addWidget(
|
||||
new InputButtonBindingWidget(m_host_interface, std::move(section_name), std::move(key_name), container),
|
||||
target_row, 1);
|
||||
|
@ -310,6 +310,34 @@ void MainWindow::onRemoveDiscActionTriggered()
|
||||
m_host_interface->changeDisc(QString());
|
||||
}
|
||||
|
||||
void MainWindow::onViewToolbarActionToggled(bool checked)
|
||||
{
|
||||
m_host_interface->SetBoolSettingValue("UI", "ShowToolbar", checked);
|
||||
m_ui.toolBar->setVisible(checked);
|
||||
}
|
||||
|
||||
void MainWindow::onViewStatusBarActionToggled(bool checked)
|
||||
{
|
||||
m_host_interface->SetBoolSettingValue("UI", "ShowStatusBar", checked);
|
||||
m_ui.statusBar->setVisible(checked);
|
||||
}
|
||||
|
||||
void MainWindow::onViewGameListActionTriggered()
|
||||
{
|
||||
if (m_emulation_running)
|
||||
m_host_interface->pauseSystem(true);
|
||||
switchToGameListView();
|
||||
}
|
||||
|
||||
void MainWindow::onViewSystemDisplayTriggered()
|
||||
{
|
||||
if (m_emulation_running)
|
||||
{
|
||||
switchToEmulationView();
|
||||
m_host_interface->pauseSystem(false);
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::onGitHubRepositoryActionTriggered()
|
||||
{
|
||||
QtUtils::OpenURL(this, "https://github.com/stenzek/duckstation/");
|
||||
@ -431,6 +459,14 @@ void MainWindow::setupAdditionalUi()
|
||||
{
|
||||
setWindowTitle(getWindowTitle());
|
||||
|
||||
const bool toolbar_visible = m_host_interface->GetBoolSettingValue("UI", "ShowToolbar", true);
|
||||
m_ui.actionViewToolbar->setChecked(toolbar_visible);
|
||||
m_ui.toolBar->setVisible(toolbar_visible);
|
||||
|
||||
const bool status_bar_visible = m_host_interface->GetBoolSettingValue("UI", "ShowStatusBar", true);
|
||||
m_ui.actionViewStatusBar->setChecked(status_bar_visible);
|
||||
m_ui.statusBar->setVisible(status_bar_visible);
|
||||
|
||||
m_game_list_widget = new GameListWidget(m_ui.mainContainer);
|
||||
m_game_list_widget->initialize(m_host_interface);
|
||||
m_ui.mainContainer->insertWidget(0, m_game_list_widget);
|
||||
@ -451,6 +487,8 @@ void MainWindow::setupAdditionalUi()
|
||||
m_status_frame_time_widget->setFixedSize(190, 16);
|
||||
m_status_frame_time_widget->hide();
|
||||
|
||||
updateDebugMenuVisibility();
|
||||
|
||||
for (u32 i = 0; i < static_cast<u32>(CPUExecutionMode::Count); i++)
|
||||
{
|
||||
const CPUExecutionMode mode = static_cast<CPUExecutionMode>(i);
|
||||
@ -507,6 +545,7 @@ void MainWindow::updateEmulationActions(bool starting, bool running)
|
||||
m_ui.actionPause->setDisabled(starting || !running);
|
||||
m_ui.actionChangeDisc->setDisabled(starting || !running);
|
||||
m_ui.actionScreenshot->setDisabled(starting || !running);
|
||||
m_ui.actionViewSystemDisplay->setEnabled(starting || running);
|
||||
m_ui.menuChangeDisc->setDisabled(starting || !running);
|
||||
|
||||
m_ui.actionSaveState->setDisabled(starting || !running);
|
||||
@ -615,6 +654,10 @@ void MainWindow::connectSignals()
|
||||
[this]() { doSettings(SettingsDialog::Category::AudioSettings); });
|
||||
connect(m_ui.actionAdvancedSettings, &QAction::triggered,
|
||||
[this]() { doSettings(SettingsDialog::Category::AdvancedSettings); });
|
||||
connect(m_ui.actionViewToolbar, &QAction::toggled, this, &MainWindow::onViewToolbarActionToggled);
|
||||
connect(m_ui.actionViewStatusBar, &QAction::toggled, this, &MainWindow::onViewStatusBarActionToggled);
|
||||
connect(m_ui.actionViewGameList, &QAction::triggered, this, &MainWindow::onViewGameListActionTriggered);
|
||||
connect(m_ui.actionViewSystemDisplay, &QAction::triggered, this, &MainWindow::onViewSystemDisplayTriggered);
|
||||
connect(m_ui.actionGitHubRepository, &QAction::triggered, this, &MainWindow::onGitHubRepositoryActionTriggered);
|
||||
connect(m_ui.actionIssueTracker, &QAction::triggered, this, &MainWindow::onIssueTrackerActionTriggered);
|
||||
connect(m_ui.actionDiscordServer, &QAction::triggered, this, &MainWindow::onDiscordServerActionTriggered);
|
||||
@ -847,6 +890,12 @@ void MainWindow::startupUpdateCheck()
|
||||
checkForUpdates(false);
|
||||
}
|
||||
|
||||
void MainWindow::updateDebugMenuVisibility()
|
||||
{
|
||||
const bool visible = m_host_interface->GetBoolSettingValue("Main", "ShowDebugMenu", false);
|
||||
m_ui.menuDebug->menuAction()->setVisible(visible);
|
||||
}
|
||||
|
||||
void MainWindow::checkForUpdates(bool display_message)
|
||||
{
|
||||
if (!AutoUpdaterDialog::isSupported())
|
||||
|
@ -29,6 +29,10 @@ public:
|
||||
/// Performs update check if enabled in settings.
|
||||
void startupUpdateCheck();
|
||||
|
||||
public Q_SLOTS:
|
||||
/// Updates debug menu visibility (hides if disabled).
|
||||
void updateDebugMenuVisibility();
|
||||
|
||||
private Q_SLOTS:
|
||||
void reportError(const QString& message);
|
||||
void reportMessage(const QString& message);
|
||||
@ -58,6 +62,10 @@ private Q_SLOTS:
|
||||
void onChangeDiscFromPlaylistMenuAboutToShow();
|
||||
void onChangeDiscFromPlaylistMenuAboutToHide();
|
||||
void onRemoveDiscActionTriggered();
|
||||
void onViewToolbarActionToggled(bool checked);
|
||||
void onViewStatusBarActionToggled(bool checked);
|
||||
void onViewGameListActionTriggered();
|
||||
void onViewSystemDisplayTriggered();
|
||||
void onGitHubRepositoryActionTriggered();
|
||||
void onIssueTrackerActionTriggered();
|
||||
void onDiscordServerActionTriggered();
|
||||
|
@ -30,7 +30,7 @@
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>754</width>
|
||||
<height>22</height>
|
||||
<height>30</height>
|
||||
</rect>
|
||||
</property>
|
||||
<widget class="QMenu" name="menuSystem">
|
||||
@ -161,8 +161,19 @@
|
||||
<addaction name="actionDebugShowTimersState"/>
|
||||
<addaction name="actionDebugShowMDECState"/>
|
||||
</widget>
|
||||
<widget class="QMenu" name="menu_View">
|
||||
<property name="title">
|
||||
<string>&View</string>
|
||||
</property>
|
||||
<addaction name="actionViewToolbar"/>
|
||||
<addaction name="actionViewStatusBar"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="actionViewGameList"/>
|
||||
<addaction name="actionViewSystemDisplay"/>
|
||||
</widget>
|
||||
<addaction name="menuSystem"/>
|
||||
<addaction name="menuSettings"/>
|
||||
<addaction name="menu_View"/>
|
||||
<addaction name="menuDebug"/>
|
||||
<addaction name="menuHelp"/>
|
||||
</widget>
|
||||
@ -560,6 +571,41 @@
|
||||
<string>Resumes the last save state created.</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionViewToolbar">
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Toolbar</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionViewStatusBar">
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>&Status Bar</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionViewGameList">
|
||||
<property name="text">
|
||||
<string>&Game List</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionViewSystemDisplay">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>System &Display</string>
|
||||
</property>
|
||||
</action>
|
||||
</widget>
|
||||
<resources>
|
||||
<include location="resources/icons.qrc"/>
|
||||
|
@ -76,7 +76,7 @@ void MemoryCardSettingsWidget::createPortSettingsUi(SettingsDialog* dialog, int
|
||||
for (int i = 0; i < static_cast<int>(MemoryCardType::Count); i++)
|
||||
{
|
||||
ui->memory_card_type->addItem(
|
||||
QString::fromUtf8(Settings::GetMemoryCardTypeDisplayName(static_cast<MemoryCardType>(i))));
|
||||
qApp->translate("MemoryCardType", Settings::GetMemoryCardTypeDisplayName(static_cast<MemoryCardType>(i))));
|
||||
}
|
||||
|
||||
const MemoryCardType default_value = (index == 0) ? MemoryCardType::PerGameTitle : MemoryCardType::None;
|
||||
|
@ -34,7 +34,10 @@
|
||||
Log_SetChannel(QtHostInterface);
|
||||
|
||||
#ifdef WIN32
|
||||
#include "common/windows_headers.h"
|
||||
#include "frontend-common/d3d11_host_display.h"
|
||||
#include <KnownFolders.h>
|
||||
#include <ShlObj.h>
|
||||
#endif
|
||||
|
||||
QtHostInterface::QtHostInterface(QObject* parent) : QObject(parent), CommonHostInterface()
|
||||
@ -58,6 +61,7 @@ std::vector<std::pair<QString, QString>> QtHostInterface::getAvailableLanguageLi
|
||||
{QStringLiteral("Deutsch"), QStringLiteral("de")},
|
||||
{QStringLiteral("Español"), QStringLiteral("es")},
|
||||
{QStringLiteral("עברית"), QStringLiteral("he")},
|
||||
{QStringLiteral("Italiano"), QStringLiteral("it")},
|
||||
{QStringLiteral("Português (Pt)"), QStringLiteral("pt-pt")},
|
||||
{QStringLiteral("Português (Br)"), QStringLiteral("pt-br")},
|
||||
{QStringLiteral("简体中文"), QStringLiteral("zh-cn")}};
|
||||
@ -279,16 +283,18 @@ void QtHostInterface::setDefaultSettings()
|
||||
m_settings_interface->Save();
|
||||
|
||||
CommonHostInterface::LoadSettings(*m_settings_interface.get());
|
||||
CommonHostInterface::ApplyGameSettings(false);
|
||||
CommonHostInterface::FixIncompatibleSettings(false);
|
||||
}
|
||||
|
||||
CheckForSettingsChanges(old_settings);
|
||||
}
|
||||
|
||||
void QtHostInterface::applySettings()
|
||||
void QtHostInterface::applySettings(bool display_osd_messages /* = false */)
|
||||
{
|
||||
if (!isOnWorkerThread())
|
||||
{
|
||||
QMetaObject::invokeMethod(this, "applySettings", Qt::QueuedConnection);
|
||||
QMetaObject::invokeMethod(this, "applySettings", Qt::QueuedConnection, Q_ARG(bool, display_osd_messages));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -296,6 +302,8 @@ void QtHostInterface::applySettings()
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> guard(m_settings_mutex);
|
||||
CommonHostInterface::LoadSettings(*m_settings_interface.get());
|
||||
CommonHostInterface::ApplyGameSettings(display_osd_messages);
|
||||
CommonHostInterface::FixIncompatibleSettings(display_osd_messages);
|
||||
}
|
||||
|
||||
CheckForSettingsChanges(old_settings);
|
||||
@ -648,6 +656,7 @@ void QtHostInterface::OnSystemPerformanceCountersUpdated()
|
||||
void QtHostInterface::OnRunningGameChanged()
|
||||
{
|
||||
CommonHostInterface::OnRunningGameChanged();
|
||||
applySettings(true);
|
||||
|
||||
if (!System::IsShutdown())
|
||||
{
|
||||
@ -672,6 +681,7 @@ void QtHostInterface::LoadSettings()
|
||||
|
||||
CommonHostInterface::CheckSettings(*m_settings_interface.get());
|
||||
CommonHostInterface::LoadSettings(*m_settings_interface.get());
|
||||
CommonHostInterface::FixIncompatibleSettings(false);
|
||||
}
|
||||
|
||||
void QtHostInterface::SetDefaultSettings(SettingsInterface& si)
|
||||
@ -1179,6 +1189,49 @@ void QtHostInterface::wakeThread()
|
||||
QMetaObject::invokeMethod(m_worker_thread_event_loop, "quit", Qt::QueuedConnection);
|
||||
}
|
||||
|
||||
static std::string GetFontPath(const char* name)
|
||||
{
|
||||
#ifdef WIN32
|
||||
PWSTR folder_path;
|
||||
if (FAILED(SHGetKnownFolderPath(FOLDERID_Fonts, 0, nullptr, &folder_path)))
|
||||
return StringUtil::StdStringFromFormat("C:\\Windows\\Fonts\\%s", name);
|
||||
|
||||
std::string font_path(StringUtil::WideStringToUTF8String(folder_path));
|
||||
CoTaskMemFree(folder_path);
|
||||
font_path += "\\";
|
||||
font_path += name;
|
||||
return font_path;
|
||||
#else
|
||||
return name;
|
||||
#endif
|
||||
}
|
||||
|
||||
static bool AddImGuiFont(const std::string& language, float size, float framebuffer_scale)
|
||||
{
|
||||
std::string path;
|
||||
const ImWchar* range = nullptr;
|
||||
#ifdef WIN32
|
||||
if (language == "jp")
|
||||
{
|
||||
path = GetFontPath("msgothic.ttc");
|
||||
range = ImGui::GetIO().Fonts->GetGlyphRangesJapanese();
|
||||
}
|
||||
else if (language == "zh-cn")
|
||||
{
|
||||
path = GetFontPath("msyh.ttc");
|
||||
range = ImGui::GetIO().Fonts->GetGlyphRangesChineseSimplifiedCommon();
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!path.empty())
|
||||
{
|
||||
return (ImGui::GetIO().Fonts->AddFontFromFileTTF(path.c_str(), size * framebuffer_scale, nullptr, range) !=
|
||||
nullptr);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void QtHostInterface::createImGuiContext(float framebuffer_scale)
|
||||
{
|
||||
ImGui::CreateContext();
|
||||
@ -1190,7 +1243,10 @@ void QtHostInterface::createImGuiContext(float framebuffer_scale)
|
||||
ImGui::GetStyle().ScaleAllSizes(framebuffer_scale);
|
||||
|
||||
ImGui::StyleColorsDarker();
|
||||
ImGui::AddRobotoRegularFont(15.0f * framebuffer_scale);
|
||||
|
||||
std::string language = GetStringSettingValue("Main", "Language", "");
|
||||
if (!AddImGuiFont(language, 15.0f, framebuffer_scale))
|
||||
ImGui::AddRobotoRegularFont(15.0f * framebuffer_scale);
|
||||
}
|
||||
|
||||
void QtHostInterface::destroyImGuiContext()
|
||||
@ -1198,6 +1254,24 @@ void QtHostInterface::destroyImGuiContext()
|
||||
ImGui::DestroyContext();
|
||||
}
|
||||
|
||||
TinyString QtHostInterface::TranslateString(const char* context, const char* str) const
|
||||
{
|
||||
const QString translated(m_translator->translate(context, str));
|
||||
if (translated.isEmpty())
|
||||
return TinyString(str);
|
||||
|
||||
return TinyString(translated.toUtf8().constData());
|
||||
}
|
||||
|
||||
std::string QtHostInterface::TranslateStdString(const char* context, const char* str) const
|
||||
{
|
||||
const QString translated(m_translator->translate(context, str));
|
||||
if (translated.isEmpty())
|
||||
return std::string(str);
|
||||
|
||||
return translated.toStdString();
|
||||
}
|
||||
|
||||
QtHostInterface::Thread::Thread(QtHostInterface* parent) : QThread(parent), m_parent(parent) {}
|
||||
|
||||
QtHostInterface::Thread::~Thread() = default;
|
||||
|
@ -64,6 +64,9 @@ public:
|
||||
void SetStringListSettingValue(const char* section, const char* key, const std::vector<std::string>& values);
|
||||
void RemoveSettingValue(const char* section, const char* key);
|
||||
|
||||
TinyString TranslateString(const char* context, const char* str) const;
|
||||
std::string TranslateStdString(const char* context, const char* str) const;
|
||||
|
||||
ALWAYS_INLINE const GameList* getGameList() const { return m_game_list.get(); }
|
||||
ALWAYS_INLINE GameList* getGameList() { return m_game_list.get(); }
|
||||
void refreshGameList(bool invalidate_cache = false, bool invalidate_database = false);
|
||||
@ -129,7 +132,7 @@ Q_SIGNALS:
|
||||
|
||||
public Q_SLOTS:
|
||||
void setDefaultSettings();
|
||||
void applySettings();
|
||||
void applySettings(bool display_osd_messages = false);
|
||||
void updateInputMap();
|
||||
void applyInputProfile(const QString& profile_path);
|
||||
void onDisplayWindowKeyEvent(int key, bool pressed);
|
||||
|
2110
src/duckstation-qt/translations/duckstation-qt_it.ts
Normal file
2110
src/duckstation-qt/translations/duckstation-qt_it.ts
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,6 +1,10 @@
|
||||
..\..\dep\msvc\qt\5.15.0\msvc2017_64\bin\lupdate.exe ./ -ts translations\duckstation-qt_de.ts
|
||||
..\..\dep\msvc\qt\5.15.0\msvc2017_64\bin\lupdate.exe ./ -ts translations\duckstation-qt_he.ts
|
||||
..\..\dep\msvc\qt\5.15.0\msvc2017_64\bin\lupdate.exe ./ -ts translations\duckstation-qt_pt-br.ts
|
||||
..\..\dep\msvc\qt\5.15.0\msvc2017_64\bin\lupdate.exe ./ -ts translations\duckstation-qt_pt-pt.ts
|
||||
..\..\dep\msvc\qt\5.15.0\msvc2017_64\bin\lupdate.exe ./ -ts translations\duckstation-qt_zh-cn.ts
|
||||
set LUPDATE=..\..\dep\msvc\qt\5.15.0\msvc2017_64\bin\lupdate.exe ./ ../core/ ../frontend-common/ -tr-function-alias translate+=TranslateString -tr-function-alias translate+=TranslateStdString -tr-function-alias QT_TRANSLATE_NOOP+=TRANSLATABLE
|
||||
|
||||
%LUPDATE% -ts translations\duckstation-qt_de.ts
|
||||
%LUPDATE% -ts translations\duckstation-qt_es.ts
|
||||
%LUPDATE% -ts translations\duckstation-qt_he.ts
|
||||
%LUPDATE% -ts translations\duckstation-qt_it.ts
|
||||
%LUPDATE% -ts translations\duckstation-qt_pt-br.ts
|
||||
%LUPDATE% -ts translations\duckstation-qt_pt-pt.ts
|
||||
%LUPDATE% -ts translations\duckstation-qt_zh-cn.ts
|
||||
pause
|
||||
|
Reference in New Issue
Block a user