summaryrefslogtreecommitdiff
path: root/src/yuzu
diff options
context:
space:
mode:
Diffstat (limited to 'src/yuzu')
-rw-r--r--src/yuzu/CMakeLists.txt14
-rw-r--r--src/yuzu/aboutdialog.ui3
-rw-r--r--src/yuzu/applets/qt_profile_select.cpp1
-rw-r--r--src/yuzu/bootmanager.cpp24
-rw-r--r--src/yuzu/configuration/config.cpp4
-rw-r--r--src/yuzu/configuration/configure_audio.ui4
-rw-r--r--src/yuzu/configuration/configure_camera.cpp20
-rw-r--r--src/yuzu/configuration/configure_debug.cpp2
-rw-r--r--src/yuzu/configuration/configure_debug.h4
-rw-r--r--src/yuzu/configuration/configure_debug.ui7
-rw-r--r--src/yuzu/configuration/configure_graphics_advanced.cpp8
-rw-r--r--src/yuzu/configuration/configure_graphics_advanced.h1
-rw-r--r--src/yuzu/configuration/configure_graphics_advanced.ui12
-rw-r--r--src/yuzu/configuration/configure_input_player.cpp25
-rw-r--r--src/yuzu/configuration/configure_tas.ui3
-rw-r--r--src/yuzu/configuration/configure_ui.cpp1
-rw-r--r--src/yuzu/game_list.cpp40
-rw-r--r--src/yuzu/game_list.h3
-rw-r--r--src/yuzu/game_list_p.h5
-rw-r--r--src/yuzu/loading_screen.cpp4
-rw-r--r--src/yuzu/main.cpp126
-rw-r--r--src/yuzu/main.h7
-rw-r--r--src/yuzu/multiplayer/chat_room.cpp39
-rw-r--r--src/yuzu/multiplayer/client_room.cpp3
-rw-r--r--src/yuzu/multiplayer/direct_connect.cpp27
-rw-r--r--src/yuzu/multiplayer/direct_connect.h7
-rw-r--r--src/yuzu/multiplayer/direct_connect.ui2
-rw-r--r--src/yuzu/multiplayer/host_room.cpp23
-rw-r--r--src/yuzu/multiplayer/host_room.h6
-rw-r--r--src/yuzu/multiplayer/lobby.cpp22
-rw-r--r--src/yuzu/multiplayer/lobby.h9
-rw-r--r--src/yuzu/multiplayer/message.cpp17
-rw-r--r--src/yuzu/multiplayer/message.h12
-rw-r--r--src/yuzu/multiplayer/state.cpp28
-rw-r--r--src/yuzu/multiplayer/state.h9
-rw-r--r--src/yuzu/multiplayer/validation.h2
-rw-r--r--src/yuzu/uisettings.h5
37 files changed, 397 insertions, 132 deletions
diff --git a/src/yuzu/CMakeLists.txt b/src/yuzu/CMakeLists.txt
index f6b389ede..50007338f 100644
--- a/src/yuzu/CMakeLists.txt
+++ b/src/yuzu/CMakeLists.txt
@@ -221,6 +221,9 @@ if (ENABLE_QT_TRANSLATION)
# Update source TS file if enabled
if (GENERATE_QT_TRANSLATION)
get_target_property(SRCS yuzu SOURCES)
+ # these calls to qt_create_translation also creates a rule to generate en.qm which conflicts with providing english plurals
+ # so we have to set a OUTPUT_LOCATION so that we don't have multiple rules to generate en.qm
+ set_source_files_properties(${YUZU_QT_LANGUAGES}/en.ts PROPERTIES OUTPUT_LOCATION "${CMAKE_CURRENT_BINARY_DIR}/translations")
qt_create_translation(QM_FILES
${SRCS}
${UIS}
@@ -229,7 +232,13 @@ if (ENABLE_QT_TRANSLATION)
-source-language en_US
-target-language en_US
)
- add_custom_target(translation ALL DEPENDS ${YUZU_QT_LANGUAGES}/en.ts)
+
+ # Generate plurals into dist/english_plurals/generated_en.ts so it can be used to revise dist/english_plurals/en.ts
+ set(GENERATED_PLURALS_FILE ${PROJECT_SOURCE_DIR}/dist/english_plurals/generated_en.ts)
+ set_source_files_properties(${GENERATED_PLURALS_FILE} PROPERTIES OUTPUT_LOCATION "${CMAKE_CURRENT_BINARY_DIR}/plurals")
+ qt_create_translation(QM_FILES ${SRCS} ${UIS} ${GENERATED_PLURALS_FILE} OPTIONS -pluralonly -source-language en_US -target-language en_US)
+
+ add_custom_target(translation ALL DEPENDS ${YUZU_QT_LANGUAGES}/en.ts ${GENERATED_PLURALS_FILE})
endif()
# Find all TS files except en.ts
@@ -239,6 +248,9 @@ if (ENABLE_QT_TRANSLATION)
# Compile TS files to QM files
qt_add_translation(LANGUAGES_QM ${LANGUAGES_TS})
+ # Compile english plurals TS file to en.qm
+ qt_add_translation(LANGUAGES_QM ${PROJECT_SOURCE_DIR}/dist/english_plurals/en.ts)
+
# Build a QRC file from the QM file list
set(LANGUAGES_QRC ${CMAKE_CURRENT_BINARY_DIR}/languages.qrc)
file(WRITE ${LANGUAGES_QRC} "<RCC><qresource prefix=\"languages\">\n")
diff --git a/src/yuzu/aboutdialog.ui b/src/yuzu/aboutdialog.ui
index c4ffb293e..aea82809d 100644
--- a/src/yuzu/aboutdialog.ui
+++ b/src/yuzu/aboutdialog.ui
@@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>616</width>
- <height>261</height>
+ <height>294</height>
</rect>
</property>
<property name="windowTitle">
@@ -165,6 +165,7 @@ p, li { white-space: pre-wrap; }
</widget>
<resources>
<include location="../../dist/qt_themes_default/default/default.qrc"/>
+ <include location="../../dist/qt_themes/default/default.qrc"/>
</resources>
<connections>
<connection>
diff --git a/src/yuzu/applets/qt_profile_select.cpp b/src/yuzu/applets/qt_profile_select.cpp
index 826c6c224..c8bcfb223 100644
--- a/src/yuzu/applets/qt_profile_select.cpp
+++ b/src/yuzu/applets/qt_profile_select.cpp
@@ -100,6 +100,7 @@ QtProfileSelectionDialog::QtProfileSelectionDialog(Core::HID::HIDCore& hid_core,
}
QKeyEvent* event = new QKeyEvent(QEvent::KeyPress, key, Qt::NoModifier);
QCoreApplication::postEvent(tree_view, event);
+ SelectUser(tree_view->currentIndex());
});
const auto& profiles = profile_manager->GetAllUsers();
diff --git a/src/yuzu/bootmanager.cpp b/src/yuzu/bootmanager.cpp
index ef3bdfb1a..d3fbdb09d 100644
--- a/src/yuzu/bootmanager.cpp
+++ b/src/yuzu/bootmanager.cpp
@@ -815,6 +815,12 @@ void GRenderWindow::InitializeCamera() {
if (Settings::values.ir_sensor_device.GetValue() == cameraInfo.deviceName().toStdString() ||
Settings::values.ir_sensor_device.GetValue() == "Auto") {
camera = std::make_unique<QCamera>(cameraInfo);
+ if (!camera->isCaptureModeSupported(QCamera::CaptureMode::CaptureViewfinder) &&
+ !camera->isCaptureModeSupported(QCamera::CaptureMode::CaptureStillImage)) {
+ LOG_ERROR(Frontend,
+ "Camera doesn't support CaptureViewfinder or CaptureStillImage");
+ continue;
+ }
camera_found = true;
break;
}
@@ -825,10 +831,22 @@ void GRenderWindow::InitializeCamera() {
}
camera_capture = std::make_unique<QCameraImageCapture>(camera.get());
+
+ if (!camera_capture->isCaptureDestinationSupported(
+ QCameraImageCapture::CaptureDestination::CaptureToBuffer)) {
+ LOG_ERROR(Frontend, "Camera doesn't support saving to buffer");
+ return;
+ }
+
+ camera_capture->setCaptureDestination(QCameraImageCapture::CaptureDestination::CaptureToBuffer);
connect(camera_capture.get(), &QCameraImageCapture::imageCaptured, this,
&GRenderWindow::OnCameraCapture);
camera->unload();
- camera->setCaptureMode(QCamera::CaptureViewfinder);
+ if (camera->isCaptureModeSupported(QCamera::CaptureMode::CaptureViewfinder)) {
+ camera->setCaptureMode(QCamera::CaptureViewfinder);
+ } else if (camera->isCaptureModeSupported(QCamera::CaptureMode::CaptureStillImage)) {
+ camera->setCaptureMode(QCamera::CaptureStillImage);
+ }
camera->load();
camera->start();
@@ -1089,8 +1107,8 @@ QStringList GRenderWindow::GetUnsupportedGLExtensions() const {
}
if (!unsupported_ext.empty()) {
- LOG_ERROR(Frontend, "GPU does not support all required extensions: {}",
- glGetString(GL_RENDERER));
+ const std::string gl_renderer{reinterpret_cast<const char*>(glGetString(GL_RENDERER))};
+ LOG_ERROR(Frontend, "GPU does not support all required extensions: {}", gl_renderer);
}
for (const QString& ext : unsupported_ext) {
LOG_ERROR(Frontend, "Unsupported GL extension: {}", ext.toStdString());
diff --git a/src/yuzu/configuration/config.cpp b/src/yuzu/configuration/config.cpp
index 58f1239bf..8ecd87150 100644
--- a/src/yuzu/configuration/config.cpp
+++ b/src/yuzu/configuration/config.cpp
@@ -73,7 +73,7 @@ const std::array<int, 2> Config::default_ringcon_analogs{{
const std::array<UISettings::Shortcut, 22> Config::default_hotkeys{{
{QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Audio Mute/Unmute")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("Ctrl+M"), QStringLiteral("Home+Dpad_Right"), Qt::WindowShortcut}},
{QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Audio Volume Down")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("-"), QStringLiteral("Home+Dpad_Down"), Qt::ApplicationShortcut}},
- {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Audio Volume Up")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("+"), QStringLiteral("Home+Dpad_Up"), Qt::ApplicationShortcut}},
+ {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Audio Volume Up")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("="), QStringLiteral("Home+Dpad_Up"), Qt::ApplicationShortcut}},
{QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Capture Screenshot")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("Ctrl+P"), QStringLiteral("Screenshot"), Qt::WidgetWithChildrenShortcut}},
{QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Change Adapting Filter")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("F8"), QStringLiteral("Home+L"), Qt::ApplicationShortcut}},
{QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Change Docked Mode")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("F10"), QStringLiteral("Home+X"), Qt::ApplicationShortcut}},
@@ -684,6 +684,7 @@ void Config::ReadRendererValues() {
ReadGlobalSetting(Settings::values.shader_backend);
ReadGlobalSetting(Settings::values.use_asynchronous_shaders);
ReadGlobalSetting(Settings::values.use_fast_gpu_time);
+ ReadGlobalSetting(Settings::values.use_pessimistic_flushes);
ReadGlobalSetting(Settings::values.bg_red);
ReadGlobalSetting(Settings::values.bg_green);
ReadGlobalSetting(Settings::values.bg_blue);
@@ -1300,6 +1301,7 @@ void Config::SaveRendererValues() {
Settings::values.shader_backend.UsingGlobal());
WriteGlobalSetting(Settings::values.use_asynchronous_shaders);
WriteGlobalSetting(Settings::values.use_fast_gpu_time);
+ WriteGlobalSetting(Settings::values.use_pessimistic_flushes);
WriteGlobalSetting(Settings::values.bg_red);
WriteGlobalSetting(Settings::values.bg_green);
WriteGlobalSetting(Settings::values.bg_blue);
diff --git a/src/yuzu/configuration/configure_audio.ui b/src/yuzu/configuration/configure_audio.ui
index a5bcee415..6034d8581 100644
--- a/src/yuzu/configuration/configure_audio.ui
+++ b/src/yuzu/configuration/configure_audio.ui
@@ -120,10 +120,10 @@
</sizepolicy>
</property>
<property name="maximum">
- <number>100</number>
+ <number>200</number>
</property>
<property name="pageStep">
- <number>10</number>
+ <number>5</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
diff --git a/src/yuzu/configuration/configure_camera.cpp b/src/yuzu/configuration/configure_camera.cpp
index 73cdcf3f2..2a61de2a1 100644
--- a/src/yuzu/configuration/configure_camera.cpp
+++ b/src/yuzu/configuration/configure_camera.cpp
@@ -42,6 +42,12 @@ void ConfigureCamera::PreviewCamera() {
LOG_INFO(Frontend, "Selected Camera {} {}", cameraInfo.description().toStdString(),
cameraInfo.deviceName().toStdString());
camera = std::make_unique<QCamera>(cameraInfo);
+ if (!camera->isCaptureModeSupported(QCamera::CaptureMode::CaptureViewfinder) &&
+ !camera->isCaptureModeSupported(QCamera::CaptureMode::CaptureStillImage)) {
+ LOG_ERROR(Frontend,
+ "Camera doesn't support CaptureViewfinder or CaptureStillImage");
+ continue;
+ }
camera_found = true;
break;
}
@@ -57,10 +63,22 @@ void ConfigureCamera::PreviewCamera() {
}
camera_capture = std::make_unique<QCameraImageCapture>(camera.get());
+
+ if (!camera_capture->isCaptureDestinationSupported(
+ QCameraImageCapture::CaptureDestination::CaptureToBuffer)) {
+ LOG_ERROR(Frontend, "Camera doesn't support saving to buffer");
+ return;
+ }
+
+ camera_capture->setCaptureDestination(QCameraImageCapture::CaptureDestination::CaptureToBuffer);
connect(camera_capture.get(), &QCameraImageCapture::imageCaptured, this,
&ConfigureCamera::DisplayCapturedFrame);
camera->unload();
- camera->setCaptureMode(QCamera::CaptureViewfinder);
+ if (camera->isCaptureModeSupported(QCamera::CaptureMode::CaptureViewfinder)) {
+ camera->setCaptureMode(QCamera::CaptureViewfinder);
+ } else if (camera->isCaptureModeSupported(QCamera::CaptureMode::CaptureStillImage)) {
+ camera->setCaptureMode(QCamera::CaptureStillImage);
+ }
camera->load();
camera->start();
diff --git a/src/yuzu/configuration/configure_debug.cpp b/src/yuzu/configuration/configure_debug.cpp
index e16d127a8..04d397750 100644
--- a/src/yuzu/configuration/configure_debug.cpp
+++ b/src/yuzu/configuration/configure_debug.cpp
@@ -14,7 +14,7 @@
#include "yuzu/uisettings.h"
ConfigureDebug::ConfigureDebug(const Core::System& system_, QWidget* parent)
- : QWidget(parent), ui{std::make_unique<Ui::ConfigureDebug>()}, system{system_} {
+ : QScrollArea(parent), ui{std::make_unique<Ui::ConfigureDebug>()}, system{system_} {
ui->setupUi(this);
SetConfiguration();
diff --git a/src/yuzu/configuration/configure_debug.h b/src/yuzu/configuration/configure_debug.h
index 64d68ab8f..42d30f170 100644
--- a/src/yuzu/configuration/configure_debug.h
+++ b/src/yuzu/configuration/configure_debug.h
@@ -4,7 +4,7 @@
#pragma once
#include <memory>
-#include <QWidget>
+#include <QScrollArea>
namespace Core {
class System;
@@ -14,7 +14,7 @@ namespace Ui {
class ConfigureDebug;
}
-class ConfigureDebug : public QWidget {
+class ConfigureDebug : public QScrollArea {
Q_OBJECT
public:
diff --git a/src/yuzu/configuration/configure_debug.ui b/src/yuzu/configuration/configure_debug.ui
index 4c16274fc..47b8b80f1 100644
--- a/src/yuzu/configuration/configure_debug.ui
+++ b/src/yuzu/configuration/configure_debug.ui
@@ -1,7 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>ConfigureDebug</class>
- <widget class="QWidget" name="ConfigureDebug">
+ <widget class="QScrollArea" name="ConfigureDebug">
+ <property name="widgetResizable">
+ <bool>true</bool>
+ </property>
+ <widget class="QWidget">
<layout class="QVBoxLayout" name="verticalLayout_1">
<item>
<layout class="QVBoxLayout" name="verticalLayout_2">
@@ -322,6 +326,7 @@
</item>
</layout>
</widget>
+ </widget>
<tabstops>
<tabstop>log_filter_edit</tabstop>
<tabstop>toggle_console</tabstop>
diff --git a/src/yuzu/configuration/configure_graphics_advanced.cpp b/src/yuzu/configuration/configure_graphics_advanced.cpp
index 7c3196c83..01f074699 100644
--- a/src/yuzu/configuration/configure_graphics_advanced.cpp
+++ b/src/yuzu/configuration/configure_graphics_advanced.cpp
@@ -28,6 +28,7 @@ void ConfigureGraphicsAdvanced::SetConfiguration() {
ui->use_vsync->setChecked(Settings::values.use_vsync.GetValue());
ui->use_asynchronous_shaders->setChecked(Settings::values.use_asynchronous_shaders.GetValue());
ui->use_fast_gpu_time->setChecked(Settings::values.use_fast_gpu_time.GetValue());
+ ui->use_pessimistic_flushes->setChecked(Settings::values.use_pessimistic_flushes.GetValue());
if (Settings::IsConfiguringGlobal()) {
ui->gpu_accuracy->setCurrentIndex(
@@ -55,6 +56,8 @@ void ConfigureGraphicsAdvanced::ApplyConfiguration() {
use_asynchronous_shaders);
ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_fast_gpu_time,
ui->use_fast_gpu_time, use_fast_gpu_time);
+ ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_pessimistic_flushes,
+ ui->use_pessimistic_flushes, use_pessimistic_flushes);
}
void ConfigureGraphicsAdvanced::changeEvent(QEvent* event) {
@@ -77,6 +80,8 @@ void ConfigureGraphicsAdvanced::SetupPerGameUI() {
ui->use_asynchronous_shaders->setEnabled(
Settings::values.use_asynchronous_shaders.UsingGlobal());
ui->use_fast_gpu_time->setEnabled(Settings::values.use_fast_gpu_time.UsingGlobal());
+ ui->use_pessimistic_flushes->setEnabled(
+ Settings::values.use_pessimistic_flushes.UsingGlobal());
ui->anisotropic_filtering_combobox->setEnabled(
Settings::values.max_anisotropy.UsingGlobal());
@@ -89,6 +94,9 @@ void ConfigureGraphicsAdvanced::SetupPerGameUI() {
use_asynchronous_shaders);
ConfigurationShared::SetColoredTristate(ui->use_fast_gpu_time,
Settings::values.use_fast_gpu_time, use_fast_gpu_time);
+ ConfigurationShared::SetColoredTristate(ui->use_pessimistic_flushes,
+ Settings::values.use_pessimistic_flushes,
+ use_pessimistic_flushes);
ConfigurationShared::SetColoredComboBox(
ui->gpu_accuracy, ui->label_gpu_accuracy,
static_cast<int>(Settings::values.gpu_accuracy.GetValue(true)));
diff --git a/src/yuzu/configuration/configure_graphics_advanced.h b/src/yuzu/configuration/configure_graphics_advanced.h
index 1ef7bd916..12e816905 100644
--- a/src/yuzu/configuration/configure_graphics_advanced.h
+++ b/src/yuzu/configuration/configure_graphics_advanced.h
@@ -39,6 +39,7 @@ private:
ConfigurationShared::CheckState use_vsync;
ConfigurationShared::CheckState use_asynchronous_shaders;
ConfigurationShared::CheckState use_fast_gpu_time;
+ ConfigurationShared::CheckState use_pessimistic_flushes;
const Core::System& system;
};
diff --git a/src/yuzu/configuration/configure_graphics_advanced.ui b/src/yuzu/configuration/configure_graphics_advanced.ui
index 96de0b3d1..87a121471 100644
--- a/src/yuzu/configuration/configure_graphics_advanced.ui
+++ b/src/yuzu/configuration/configure_graphics_advanced.ui
@@ -75,7 +75,7 @@
<string>VSync prevents the screen from tearing, but some graphics cards have lower performance with VSync enabled. Keep it enabled if you don't notice a performance difference.</string>
</property>
<property name="text">
- <string>Use VSync (OpenGL only)</string>
+ <string>Use VSync</string>
</property>
</widget>
</item>
@@ -100,6 +100,16 @@
</widget>
</item>
<item>
+ <widget class="QCheckBox" name="use_pessimistic_flushes">
+ <property name="toolTip">
+ <string>Enables pessimistic buffer flushes. This option will force unmodified buffers to be flushed, which can cost performance.</string>
+ </property>
+ <property name="text">
+ <string>Use pessimistic buffer flushes (Hack)</string>
+ </property>
+ </widget>
+ </item>
+ <item>
<widget class="QWidget" name="af_layout" native="true">
<layout class="QHBoxLayout" name="horizontalLayout_1">
<property name="leftMargin">
diff --git a/src/yuzu/configuration/configure_input_player.cpp b/src/yuzu/configuration/configure_input_player.cpp
index 00bee85b2..9e5a40fe7 100644
--- a/src/yuzu/configuration/configure_input_player.cpp
+++ b/src/yuzu/configuration/configure_input_player.cpp
@@ -161,6 +161,7 @@ QString ConfigureInputPlayer::ButtonToText(const Common::ParamPackage& param) {
const QString toggle = QString::fromStdString(param.Get("toggle", false) ? "~" : "");
const QString inverted = QString::fromStdString(param.Get("inverted", false) ? "!" : "");
+ const QString invert = QString::fromStdString(param.Get("invert", "+") == "-" ? "-" : "");
const auto common_button_name = input_subsystem->GetButtonName(param);
// Retrieve the names from Qt
@@ -184,7 +185,7 @@ QString ConfigureInputPlayer::ButtonToText(const Common::ParamPackage& param) {
}
if (param.Has("axis")) {
const QString axis = QString::fromStdString(param.Get("axis", ""));
- return QObject::tr("%1%2Axis %3").arg(toggle, inverted, axis);
+ return QObject::tr("%1%2Axis %3").arg(toggle, invert, axis);
}
if (param.Has("axis_x") && param.Has("axis_y") && param.Has("axis_z")) {
const QString axis_x = QString::fromStdString(param.Get("axis_x", ""));
@@ -362,18 +363,18 @@ ConfigureInputPlayer::ConfigureInputPlayer(QWidget* parent, std::size_t player_i
button_map[button_id]->setText(tr("[not set]"));
});
if (param.Has("code") || param.Has("button") || param.Has("hat")) {
- context_menu.addAction(tr("Toggle button"), [&] {
- const bool toggle_value = !param.Get("toggle", false);
- param.Set("toggle", toggle_value);
- button_map[button_id]->setText(ButtonToText(param));
- emulated_controller->SetButtonParam(button_id, param);
- });
context_menu.addAction(tr("Invert button"), [&] {
const bool invert_value = !param.Get("inverted", false);
param.Set("inverted", invert_value);
button_map[button_id]->setText(ButtonToText(param));
emulated_controller->SetButtonParam(button_id, param);
});
+ context_menu.addAction(tr("Toggle button"), [&] {
+ const bool toggle_value = !param.Get("toggle", false);
+ param.Set("toggle", toggle_value);
+ button_map[button_id]->setText(ButtonToText(param));
+ emulated_controller->SetButtonParam(button_id, param);
+ });
}
if (param.Has("axis")) {
context_menu.addAction(tr("Invert axis"), [&] {
@@ -398,6 +399,12 @@ ConfigureInputPlayer::ConfigureInputPlayer(QWidget* parent, std::size_t player_i
}
emulated_controller->SetButtonParam(button_id, param);
});
+ context_menu.addAction(tr("Toggle axis"), [&] {
+ const bool toggle_value = !param.Get("toggle", false);
+ param.Set("toggle", toggle_value);
+ button_map[button_id]->setText(ButtonToText(param));
+ emulated_controller->SetButtonParam(button_id, param);
+ });
}
context_menu.exec(button_map[button_id]->mapToGlobal(menu_location));
});
@@ -1410,7 +1417,7 @@ void ConfigureInputPlayer::HandleClick(
ui->controllerFrame->BeginMappingAnalog(button_id);
}
- timeout_timer->start(2500); // Cancel after 2.5 seconds
+ timeout_timer->start(4000); // Cancel after 4 seconds
poll_timer->start(25); // Check for new inputs every 25ms
}
@@ -1475,7 +1482,7 @@ void ConfigureInputPlayer::keyPressEvent(QKeyEvent* event) {
void ConfigureInputPlayer::CreateProfile() {
const auto profile_name =
- LimitableInputDialog::GetText(this, tr("New Profile"), tr("Enter a profile name:"), 1, 20,
+ LimitableInputDialog::GetText(this, tr("New Profile"), tr("Enter a profile name:"), 1, 30,
LimitableInputDialog::InputLimiter::Filesystem);
if (profile_name.isEmpty()) {
diff --git a/src/yuzu/configuration/configure_tas.ui b/src/yuzu/configuration/configure_tas.ui
index cf88a5bf0..625af0c89 100644
--- a/src/yuzu/configuration/configure_tas.ui
+++ b/src/yuzu/configuration/configure_tas.ui
@@ -16,6 +16,9 @@
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Reads controller input from scripts in the same format as TAS-nx scripts.&lt;br/&gt;For a more detailed explanation, please consult the &lt;a href=&quot;https://yuzu-emu.org/help/feature/tas/&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#039be5;&quot;&gt;help page&lt;/span&gt;&lt;/a&gt; on the yuzu website.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
+ <property name="openExternalLinks">
+ <bool>true</bool>
+ </property>
</widget>
</item>
<item row="1" column="0" colspan="4">
diff --git a/src/yuzu/configuration/configure_ui.cpp b/src/yuzu/configuration/configure_ui.cpp
index 2e98ede8e..48f71b53c 100644
--- a/src/yuzu/configuration/configure_ui.cpp
+++ b/src/yuzu/configuration/configure_ui.cpp
@@ -219,6 +219,7 @@ void ConfigureUi::InitializeLanguageComboBox() {
for (const auto& lang : languages) {
if (QString::fromLatin1(lang.id) == QStringLiteral("en")) {
ui->language_combobox->addItem(lang.name, QStringLiteral("en"));
+ language_files.removeOne(QStringLiteral("en.qm"));
continue;
}
for (int i = 0; i < language_files.size(); ++i) {
diff --git a/src/yuzu/game_list.cpp b/src/yuzu/game_list.cpp
index 041e6ac11..b127badc2 100644
--- a/src/yuzu/game_list.cpp
+++ b/src/yuzu/game_list.cpp
@@ -126,10 +126,8 @@ GameListSearchField::GameListSearchField(GameList* parent) : QWidget{parent} {
layout_filter = new QHBoxLayout;
layout_filter->setContentsMargins(8, 8, 8, 8);
label_filter = new QLabel;
- label_filter->setText(tr("Filter:"));
edit_filter = new QLineEdit;
edit_filter->clear();
- edit_filter->setPlaceholderText(tr("Enter pattern to filter"));
edit_filter->installEventFilter(key_release_eater);
edit_filter->setClearButtonEnabled(true);
connect(edit_filter, &QLineEdit::textChanged, parent, &GameList::OnTextChanged);
@@ -149,6 +147,7 @@ GameListSearchField::GameListSearchField(GameList* parent) : QWidget{parent} {
layout_filter->addWidget(label_filter_result);
layout_filter->addWidget(button_filter_close);
setLayout(layout_filter);
+ RetranslateUI();
}
/**
@@ -286,7 +285,7 @@ void GameList::OnUpdateThemedIcons() {
}
case GameListItemType::AddDir:
child->setData(
- QIcon::fromTheme(QStringLiteral("plus"))
+ QIcon::fromTheme(QStringLiteral("list-add"))
.pixmap(icon_size)
.scaled(icon_size, icon_size, Qt::IgnoreAspectRatio, Qt::SmoothTransformation),
Qt::DecorationRole);
@@ -333,13 +332,9 @@ GameList::GameList(FileSys::VirtualFilesystem vfs_, FileSys::ManualContentProvid
tree_view->setStyleSheet(QStringLiteral("QTreeView{ border: none; }"));
item_model->insertColumns(0, COLUMN_COUNT);
- item_model->setHeaderData(COLUMN_NAME, Qt::Horizontal, tr("Name"));
- item_model->setHeaderData(COLUMN_COMPATIBILITY, Qt::Horizontal, tr("Compatibility"));
+ RetranslateUI();
- item_model->setHeaderData(COLUMN_ADD_ONS, Qt::Horizontal, tr("Add-ons"));
tree_view->setColumnHidden(COLUMN_ADD_ONS, !UISettings::values.show_add_ons);
- item_model->setHeaderData(COLUMN_FILE_TYPE, Qt::Horizontal, tr("File type"));
- item_model->setHeaderData(COLUMN_SIZE, Qt::Horizontal, tr("Size"));
item_model->setSortRole(GameListItemPath::SortRole);
connect(main_window, &GMainWindow::UpdateThemedIcons, this, &GameList::OnUpdateThemedIcons);
@@ -753,6 +748,35 @@ void GameList::LoadCompatibilityList() {
}
}
+void GameList::changeEvent(QEvent* event) {
+ if (event->type() == QEvent::LanguageChange) {
+ RetranslateUI();
+ }
+
+ QWidget::changeEvent(event);
+}
+
+void GameList::RetranslateUI() {
+ item_model->setHeaderData(COLUMN_NAME, Qt::Horizontal, tr("Name"));
+ item_model->setHeaderData(COLUMN_COMPATIBILITY, Qt::Horizontal, tr("Compatibility"));
+ item_model->setHeaderData(COLUMN_ADD_ONS, Qt::Horizontal, tr("Add-ons"));
+ item_model->setHeaderData(COLUMN_FILE_TYPE, Qt::Horizontal, tr("File type"));
+ item_model->setHeaderData(COLUMN_SIZE, Qt::Horizontal, tr("Size"));
+}
+
+void GameListSearchField::changeEvent(QEvent* event) {
+ if (event->type() == QEvent::LanguageChange) {
+ RetranslateUI();
+ }
+
+ QWidget::changeEvent(event);
+}
+
+void GameListSearchField::RetranslateUI() {
+ label_filter->setText(tr("Filter:"));
+ edit_filter->setPlaceholderText(tr("Enter pattern to filter"));
+}
+
QStandardItemModel* GameList::GetModel() const {
return item_model;
}
diff --git a/src/yuzu/game_list.h b/src/yuzu/game_list.h
index f783283c9..cdf085019 100644
--- a/src/yuzu/game_list.h
+++ b/src/yuzu/game_list.h
@@ -140,6 +140,9 @@ private:
void AddPermDirPopup(QMenu& context_menu, QModelIndex selected);
void AddFavoritesPopup(QMenu& context_menu);
+ void changeEvent(QEvent*) override;
+ void RetranslateUI();
+
std::shared_ptr<FileSys::VfsFilesystem> vfs;
FileSys::ManualContentProvider* provider;
GameListSearchField* search_field;
diff --git a/src/yuzu/game_list_p.h b/src/yuzu/game_list_p.h
index e7667cf60..6198d1e4e 100644
--- a/src/yuzu/game_list_p.h
+++ b/src/yuzu/game_list_p.h
@@ -294,7 +294,7 @@ public:
const int icon_size = UISettings::values.folder_icon_size.GetValue();
- setData(QIcon::fromTheme(QStringLiteral("plus"))
+ setData(QIcon::fromTheme(QStringLiteral("list-add"))
.pixmap(icon_size)
.scaled(icon_size, icon_size, Qt::IgnoreAspectRatio, Qt::SmoothTransformation),
Qt::DecorationRole);
@@ -353,6 +353,9 @@ public:
void setFocus();
private:
+ void changeEvent(QEvent*) override;
+ void RetranslateUI();
+
class KeyReleaseEater : public QObject {
public:
explicit KeyReleaseEater(GameList* gamelist_, QObject* parent = nullptr);
diff --git a/src/yuzu/loading_screen.cpp b/src/yuzu/loading_screen.cpp
index e273744fd..e263a07a7 100644
--- a/src/yuzu/loading_screen.cpp
+++ b/src/yuzu/loading_screen.cpp
@@ -147,6 +147,10 @@ void LoadingScreen::OnLoadProgress(VideoCore::LoadCallbackStage stage, std::size
ui->progress_bar->setMaximum(static_cast<int>(total));
previous_total = total;
}
+ // Reset the progress bar ranges if compilation is done
+ if (stage == VideoCore::LoadCallbackStage::Complete) {
+ ui->progress_bar->setRange(0, 0);
+ }
QString estimate;
// If theres a drastic slowdown in the rate, then display an estimate
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp
index f8c234082..a85adc072 100644
--- a/src/yuzu/main.cpp
+++ b/src/yuzu/main.cpp
@@ -257,6 +257,18 @@ static QString PrettyProductName() {
return QSysInfo::prettyProductName();
}
+bool GMainWindow::CheckDarkMode() {
+#ifdef __linux__
+ const QPalette test_palette(qApp->palette());
+ const QColor text_color = test_palette.color(QPalette::Active, QPalette::Text);
+ const QColor window_color = test_palette.color(QPalette::Active, QPalette::Window);
+ return (text_color.value() > window_color.value());
+#else
+ // TODO: Windows
+ return false;
+#endif // __linux__
+}
+
GMainWindow::GMainWindow(bool has_broken_vulkan)
: ui{std::make_unique<Ui::MainWindow>()}, system{std::make_unique<Core::System>()},
input_subsystem{std::make_shared<InputCommon::InputSubsystem>()},
@@ -274,6 +286,13 @@ GMainWindow::GMainWindow(bool has_broken_vulkan)
ui->setupUi(this);
statusBar()->hide();
+ // Check dark mode before a theme is loaded
+ os_dark_mode = CheckDarkMode();
+ startup_icon_theme = QIcon::themeName();
+ // fallback can only be set once, colorful theme icons are okay on both light/dark
+ QIcon::setFallbackThemeName(QStringLiteral("colorful"));
+ QIcon::setFallbackSearchPaths(QStringList(QStringLiteral(":/icons")));
+
default_theme_paths = QIcon::themeSearchPaths();
UpdateUITheme();
@@ -473,8 +492,6 @@ GMainWindow::~GMainWindow() {
delete render_window;
}
- system->GetRoomNetwork().Shutdown();
-
#ifdef __linux__
::close(sig_interrupt_fds[0]);
::close(sig_interrupt_fds[1]);
@@ -843,7 +860,7 @@ void GMainWindow::InitializeWidgets() {
});
multiplayer_state = new MultiplayerState(this, game_list->GetModel(), ui->action_Leave_Room,
- ui->action_Show_Room, system->GetRoomNetwork());
+ ui->action_Show_Room, *system);
multiplayer_state->setVisible(false);
// Create status bar
@@ -1075,7 +1092,7 @@ void GMainWindow::InitializeHotkeys() {
connect_shortcut(QStringLiteral("Audio Mute/Unmute"),
[] { Settings::values.audio_muted = !Settings::values.audio_muted; });
connect_shortcut(QStringLiteral("Audio Volume Down"), [] {
- const auto current_volume = static_cast<int>(Settings::values.volume.GetValue());
+ const auto current_volume = static_cast<s32>(Settings::values.volume.GetValue());
int step = 5;
if (current_volume <= 30) {
step = 2;
@@ -1083,11 +1100,10 @@ void GMainWindow::InitializeHotkeys() {
if (current_volume <= 6) {
step = 1;
}
- const auto new_volume = std::max(current_volume - step, 0);
- Settings::values.volume.SetValue(static_cast<u8>(new_volume));
+ Settings::values.volume.SetValue(std::max(current_volume - step, 0));
});
connect_shortcut(QStringLiteral("Audio Volume Up"), [] {
- const auto current_volume = static_cast<int>(Settings::values.volume.GetValue());
+ const auto current_volume = static_cast<s32>(Settings::values.volume.GetValue());
int step = 5;
if (current_volume < 30) {
step = 2;
@@ -1095,8 +1111,7 @@ void GMainWindow::InitializeHotkeys() {
if (current_volume < 6) {
step = 1;
}
- const auto new_volume = std::min(current_volume + step, 100);
- Settings::values.volume.SetValue(static_cast<u8>(new_volume));
+ Settings::values.volume.SetValue(current_volume + step);
});
connect_shortcut(QStringLiteral("Toggle Framerate Limit"), [] {
Settings::values.use_speed_limit.SetValue(!Settings::values.use_speed_limit.GetValue());
@@ -1588,17 +1603,18 @@ bool GMainWindow::LoadROM(const QString& filename, u64 program_id, std::size_t p
return true;
}
-void GMainWindow::SelectAndSetCurrentUser() {
+bool GMainWindow::SelectAndSetCurrentUser() {
QtProfileSelectionDialog dialog(system->HIDCore(), this);
dialog.setWindowFlags(Qt::Dialog | Qt::CustomizeWindowHint | Qt::WindowTitleHint |
Qt::WindowSystemMenuHint | Qt::WindowCloseButtonHint);
dialog.setWindowModality(Qt::WindowModal);
if (dialog.exec() == QDialog::Rejected) {
- return;
+ return false;
}
Settings::values.current_user = dialog.GetIndex();
+ return true;
}
void GMainWindow::BootGame(const QString& filename, u64 program_id, std::size_t program_index,
@@ -1632,11 +1648,14 @@ void GMainWindow::BootGame(const QString& filename, u64 program_id, std::size_t
Settings::LogSettings();
if (UISettings::values.select_user_on_boot) {
- SelectAndSetCurrentUser();
+ if (SelectAndSetCurrentUser() == false) {
+ return;
+ }
}
- if (!LoadROM(filename, program_id, program_index))
+ if (!LoadROM(filename, program_id, program_index)) {
return;
+ }
system->SetShuttingDown(false);
@@ -3334,7 +3353,8 @@ void GMainWindow::MigrateConfigFiles() {
}
const auto origin = config_dir_fs_path / filename;
const auto destination = config_dir_fs_path / "custom" / filename;
- LOG_INFO(Frontend, "Migrating config file from {} to {}", origin, destination);
+ LOG_INFO(Frontend, "Migrating config file from {} to {}", origin.string(),
+ destination.string());
if (!Common::FS::RenameFile(origin, destination)) {
// Delete the old config file if one already exists in the new location.
Common::FS::RemoveFile(origin);
@@ -3809,6 +3829,7 @@ void GMainWindow::closeEvent(QCloseEvent* event) {
render_window->close();
multiplayer_state->Close();
+ system->GetRoomNetwork().Shutdown();
QWidget::closeEvent(event);
}
@@ -3930,8 +3951,21 @@ void GMainWindow::filterBarSetChecked(bool state) {
emit(OnToggleFilterBar());
}
+static void AdjustLinkColor() {
+ QPalette new_pal(qApp->palette());
+ if (UISettings::IsDarkTheme()) {
+ new_pal.setColor(QPalette::Link, QColor(0, 190, 255, 255));
+ } else {
+ new_pal.setColor(QPalette::Link, QColor(0, 140, 200, 255));
+ }
+ if (qApp->palette().color(QPalette::Link) != new_pal.color(QPalette::Link)) {
+ qApp->setPalette(new_pal);
+ }
+}
+
void GMainWindow::UpdateUITheme() {
- const QString default_theme = QStringLiteral("default");
+ const QString default_theme =
+ QString::fromUtf8(UISettings::themes[static_cast<size_t>(Config::default_theme)].second);
QString current_theme = UISettings::values.theme;
QStringList theme_paths(default_theme_paths);
@@ -3939,6 +3973,23 @@ void GMainWindow::UpdateUITheme() {
current_theme = default_theme;
}
+#ifdef _WIN32
+ QIcon::setThemeName(current_theme);
+ AdjustLinkColor();
+#else
+ if (current_theme == QStringLiteral("default") || current_theme == QStringLiteral("colorful")) {
+ QIcon::setThemeName(current_theme == QStringLiteral("colorful") ? current_theme
+ : startup_icon_theme);
+ QIcon::setThemeSearchPaths(theme_paths);
+ if (CheckDarkMode()) {
+ current_theme = QStringLiteral("default_dark");
+ }
+ } else {
+ QIcon::setThemeName(current_theme);
+ QIcon::setThemeSearchPaths(QStringList(QStringLiteral(":/icons")));
+ AdjustLinkColor();
+ }
+#endif
if (current_theme != default_theme) {
QString theme_uri{QStringLiteral(":%1/style.qss").arg(current_theme)};
QFile f(theme_uri);
@@ -3961,25 +4012,9 @@ void GMainWindow::UpdateUITheme() {
qApp->setStyleSheet({});
setStyleSheet({});
}
-
- QPalette new_pal(qApp->palette());
- if (UISettings::IsDarkTheme()) {
- new_pal.setColor(QPalette::Link, QColor(0, 190, 255, 255));
- } else {
- new_pal.setColor(QPalette::Link, QColor(0, 140, 200, 255));
- }
- qApp->setPalette(new_pal);
-
- QIcon::setThemeName(current_theme);
- QIcon::setThemeSearchPaths(theme_paths);
}
void GMainWindow::LoadTranslation() {
- // If the selected language is English, no need to install any translation
- if (UISettings::values.language == QStringLiteral("en")) {
- return;
- }
-
bool loaded;
if (UISettings::values.language.isEmpty()) {
@@ -4022,6 +4057,26 @@ void GMainWindow::SetDiscordEnabled([[maybe_unused]] bool state) {
discord_rpc->Update();
}
+void GMainWindow::changeEvent(QEvent* event) {
+#ifdef __linux__
+ // PaletteChange event appears to only reach so far into the GUI, explicitly asking to
+ // UpdateUITheme is a decent work around
+ if (event->type() == QEvent::PaletteChange) {
+ const QPalette test_palette(qApp->palette());
+ const QString current_theme = UISettings::values.theme;
+ // Keeping eye on QPalette::Window to avoid looping. QPalette::Text might be useful too
+ static QColor last_window_color;
+ const QColor window_color = test_palette.color(QPalette::Active, QPalette::Window);
+ if (last_window_color != window_color && (current_theme == QStringLiteral("default") ||
+ current_theme == QStringLiteral("colorful"))) {
+ UpdateUITheme();
+ }
+ last_window_color = window_color;
+ }
+#endif // __linux__
+ QWidget::changeEvent(event);
+}
+
#ifdef main
#undef main
#endif
@@ -4067,6 +4122,15 @@ int main(int argc, char* argv[]) {
QCoreApplication::setAttribute(Qt::AA_DontCheckOpenGLContextThreadAffinity);
QApplication app(argc, argv);
+ // Workaround for QTBUG-85409, for Suzhou numerals the number 1 is actually \u3021
+ // so we can see if we get \u3008 instead
+ // TL;DR all other number formats are consecutive in unicode code points
+ // This bug is fixed in Qt6, specifically 6.0.0-alpha1
+ const QLocale locale = QLocale::system();
+ if (QStringLiteral("\u3008") == locale.toString(1)) {
+ QLocale::setDefault(QLocale::system().name());
+ }
+
// Qt changes the locale and causes issues in float conversion using std::to_string() when
// generating shaders
setlocale(LC_ALL, "C");
diff --git a/src/yuzu/main.h b/src/yuzu/main.h
index 23b67a14e..1ae2b93d9 100644
--- a/src/yuzu/main.h
+++ b/src/yuzu/main.h
@@ -218,7 +218,7 @@ private:
void SetDiscordEnabled(bool state);
void LoadAmiibo(const QString& filename);
- void SelectAndSetCurrentUser();
+ bool SelectAndSetCurrentUser();
/**
* Stores the filename in the recently loaded files list.
@@ -251,6 +251,7 @@ private:
bool ConfirmForceLockedExit();
void RequestGameExit();
void RequestGameResume();
+ void changeEvent(QEvent* event) override;
void closeEvent(QCloseEvent* event) override;
#ifdef __linux__
@@ -347,6 +348,7 @@ private:
void OpenURL(const QUrl& url);
void LoadTranslation();
void OpenPerGameConfiguration(u64 title_id, const std::string& file_name);
+ bool CheckDarkMode();
QString GetTasStateDescription() const;
@@ -392,6 +394,9 @@ private:
QTimer mouse_hide_timer;
QTimer mouse_center_timer;
+ QString startup_icon_theme;
+ bool os_dark_mode = false;
+
// FS
std::shared_ptr<FileSys::VfsFilesystem> vfs;
std::unique_ptr<FileSys::ManualContentProvider> provider;
diff --git a/src/yuzu/multiplayer/chat_room.cpp b/src/yuzu/multiplayer/chat_room.cpp
index 5837b36ab..9e672f82e 100644
--- a/src/yuzu/multiplayer/chat_room.cpp
+++ b/src/yuzu/multiplayer/chat_room.cpp
@@ -16,7 +16,7 @@
#include <QUrl>
#include <QtConcurrent/QtConcurrentRun>
#include "common/logging/log.h"
-#include "core/announce_multiplayer_session.h"
+#include "network/announce_multiplayer_session.h"
#include "ui_chat_room.h"
#include "yuzu/game_list_p.h"
#include "yuzu/multiplayer/chat_room.h"
@@ -122,19 +122,22 @@ public:
static const int UsernameRole = Qt::UserRole + 2;
static const int AvatarUrlRole = Qt::UserRole + 3;
static const int GameNameRole = Qt::UserRole + 4;
+ static const int GameVersionRole = Qt::UserRole + 5;
PlayerListItem() = default;
explicit PlayerListItem(const std::string& nickname, const std::string& username,
- const std::string& avatar_url, const std::string& game_name) {
+ const std::string& avatar_url,
+ const AnnounceMultiplayerRoom::GameInfo& game_info) {
setEditable(false);
setData(QString::fromStdString(nickname), NicknameRole);
setData(QString::fromStdString(username), UsernameRole);
setData(QString::fromStdString(avatar_url), AvatarUrlRole);
- if (game_name.empty()) {
+ if (game_info.name.empty()) {
setData(QObject::tr("Not playing a game"), GameNameRole);
} else {
- setData(QString::fromStdString(game_name), GameNameRole);
+ setData(QString::fromStdString(game_info.name), GameNameRole);
}
+ setData(QString::fromStdString(game_info.version), GameVersionRole);
}
QVariant data(int role) const override {
@@ -149,7 +152,13 @@ public:
} else {
name = QStringLiteral("%1 (%2)").arg(nickname, username);
}
- return QStringLiteral("%1\n %2").arg(name, data(GameNameRole).toString());
+ const QString version = data(GameVersionRole).toString();
+ QString version_string;
+ if (!version.isEmpty()) {
+ version_string = QStringLiteral("(%1)").arg(version);
+ }
+ return QStringLiteral("%1\n %2 %3")
+ .arg(name, data(GameNameRole).toString(), version_string);
}
};
@@ -167,6 +176,10 @@ ChatRoom::ChatRoom(QWidget* parent) : QWidget(parent), ui(std::make_unique<Ui::C
ui->chat_history->document()->setMaximumBlockCount(max_chat_lines);
+ auto font = ui->chat_history->font();
+ font.setPointSizeF(10);
+ ui->chat_history->setFont(font);
+
// register the network structs to use in slots and signals
qRegisterMetaType<Network::ChatEntry>();
qRegisterMetaType<Network::StatusMessageEntry>();
@@ -316,21 +329,19 @@ void ChatRoom::OnStatusMessageReceive(const Network::StatusMessageEntry& status_
}
void ChatRoom::OnSendChat() {
- if (auto room = room_network->GetRoomMember().lock()) {
- if (room->GetState() != Network::RoomMember::State::Joined &&
- room->GetState() != Network::RoomMember::State::Moderator) {
-
+ if (auto room_member = room_network->GetRoomMember().lock()) {
+ if (!room_member->IsConnected()) {
return;
}
auto message = ui->chat_message->text().toStdString();
if (!ValidateMessage(message)) {
return;
}
- auto nick = room->GetNickname();
- auto username = room->GetUsername();
+ auto nick = room_member->GetNickname();
+ auto username = room_member->GetUsername();
Network::ChatEntry chat{nick, username, message};
- auto members = room->GetMemberInformation();
+ auto members = room_member->GetMemberInformation();
auto it = std::find_if(members.begin(), members.end(),
[&chat](const Network::RoomMember::MemberInformation& member) {
return member.nickname == chat.nickname &&
@@ -341,7 +352,7 @@ void ChatRoom::OnSendChat() {
}
auto player = std::distance(members.begin(), it);
ChatMessage m(chat, *room_network);
- room->SendChatMessage(message);
+ room_member->SendChatMessage(message);
AppendChatMessage(m.GetPlayerChatMessage(player));
ui->chat_message->clear();
}
@@ -368,7 +379,7 @@ void ChatRoom::SetPlayerList(const Network::RoomMember::MemberList& member_list)
if (member.nickname.empty())
continue;
QStandardItem* name_item = new PlayerListItem(member.nickname, member.username,
- member.avatar_url, member.game_info.name);
+ member.avatar_url, member.game_info);
#ifdef ENABLE_WEB_SERVICE
if (!icon_cache.count(member.avatar_url) && !member.avatar_url.empty()) {
diff --git a/src/yuzu/multiplayer/client_room.cpp b/src/yuzu/multiplayer/client_room.cpp
index a9859ed70..b34a8d004 100644
--- a/src/yuzu/multiplayer/client_room.cpp
+++ b/src/yuzu/multiplayer/client_room.cpp
@@ -10,7 +10,7 @@
#include <QTime>
#include <QtConcurrent/QtConcurrentRun>
#include "common/logging/log.h"
-#include "core/announce_multiplayer_session.h"
+#include "network/announce_multiplayer_session.h"
#include "ui_client_room.h"
#include "yuzu/game_list_p.h"
#include "yuzu/multiplayer/client_room.h"
@@ -74,7 +74,6 @@ void ClientRoomWindow::OnRoomUpdate(const Network::RoomInformation& info) {
void ClientRoomWindow::OnStateChange(const Network::RoomMember::State& state) {
if (state == Network::RoomMember::State::Joined ||
state == Network::RoomMember::State::Moderator) {
-
ui->chat->Clear();
ui->chat->AppendStatusMessage(tr("Connected"));
SetModPerms(state == Network::RoomMember::State::Moderator);
diff --git a/src/yuzu/multiplayer/direct_connect.cpp b/src/yuzu/multiplayer/direct_connect.cpp
index 9000c4531..017063074 100644
--- a/src/yuzu/multiplayer/direct_connect.cpp
+++ b/src/yuzu/multiplayer/direct_connect.cpp
@@ -8,6 +8,8 @@
#include <QString>
#include <QtConcurrent/QtConcurrentRun>
#include "common/settings.h"
+#include "core/core.h"
+#include "core/internal_network/network_interface.h"
#include "network/network.h"
#include "ui_direct_connect.h"
#include "yuzu/main.h"
@@ -20,9 +22,10 @@
enum class ConnectionType : u8 { TraversalServer, IP };
-DirectConnectWindow::DirectConnectWindow(Network::RoomNetwork& room_network_, QWidget* parent)
+DirectConnectWindow::DirectConnectWindow(Core::System& system_, QWidget* parent)
: QDialog(parent, Qt::WindowTitleHint | Qt::WindowCloseButtonHint | Qt::WindowSystemMenuHint),
- ui(std::make_unique<Ui::DirectConnect>()), room_network{room_network_} {
+ ui(std::make_unique<Ui::DirectConnect>()), system{system_}, room_network{
+ system.GetRoomNetwork()} {
ui->setupUi(this);
@@ -53,10 +56,20 @@ void DirectConnectWindow::RetranslateUi() {
}
void DirectConnectWindow::Connect() {
+ if (!Network::GetSelectedNetworkInterface()) {
+ NetworkMessage::ErrorManager::ShowError(
+ NetworkMessage::ErrorManager::NO_INTERFACE_SELECTED);
+ return;
+ }
if (!ui->nickname->hasAcceptableInput()) {
NetworkMessage::ErrorManager::ShowError(NetworkMessage::ErrorManager::USERNAME_NOT_VALID);
return;
}
+ if (system.IsPoweredOn()) {
+ if (!NetworkMessage::WarnGameRunning()) {
+ return;
+ }
+ }
if (const auto member = room_network.GetRoomMember().lock()) {
// Prevent the user from trying to join a room while they are already joining.
if (member->GetState() == Network::RoomMember::State::Joining) {
@@ -97,9 +110,9 @@ void DirectConnectWindow::Connect() {
QFuture<void> f = QtConcurrent::run([&] {
if (auto room_member = room_network.GetRoomMember().lock()) {
auto port = UISettings::values.multiplayer_port.GetValue();
- room_member->Join(ui->nickname->text().toStdString(), "",
- ui->ip->text().toStdString().c_str(), port, 0,
- Network::NoPreferredMac, ui->password->text().toStdString().c_str());
+ room_member->Join(ui->nickname->text().toStdString(),
+ ui->ip->text().toStdString().c_str(), port, 0, Network::NoPreferredIP,
+ ui->password->text().toStdString().c_str());
}
});
watcher->setFuture(f);
@@ -121,9 +134,7 @@ void DirectConnectWindow::OnConnection() {
EndConnecting();
if (auto room_member = room_network.GetRoomMember().lock()) {
- if (room_member->GetState() == Network::RoomMember::State::Joined ||
- room_member->GetState() == Network::RoomMember::State::Moderator) {
-
+ if (room_member->IsConnected()) {
close();
}
}
diff --git a/src/yuzu/multiplayer/direct_connect.h b/src/yuzu/multiplayer/direct_connect.h
index 4e1043053..e39dd1e0d 100644
--- a/src/yuzu/multiplayer/direct_connect.h
+++ b/src/yuzu/multiplayer/direct_connect.h
@@ -12,11 +12,15 @@ namespace Ui {
class DirectConnect;
}
+namespace Core {
+class System;
+}
+
class DirectConnectWindow : public QDialog {
Q_OBJECT
public:
- explicit DirectConnectWindow(Network::RoomNetwork& room_network_, QWidget* parent = nullptr);
+ explicit DirectConnectWindow(Core::System& system_, QWidget* parent = nullptr);
~DirectConnectWindow();
void RetranslateUi();
@@ -39,5 +43,6 @@ private:
QFutureWatcher<void>* watcher;
std::unique_ptr<Ui::DirectConnect> ui;
Validation validation;
+ Core::System& system;
Network::RoomNetwork& room_network;
};
diff --git a/src/yuzu/multiplayer/direct_connect.ui b/src/yuzu/multiplayer/direct_connect.ui
index 681b6bf69..57d6ec25a 100644
--- a/src/yuzu/multiplayer/direct_connect.ui
+++ b/src/yuzu/multiplayer/direct_connect.ui
@@ -83,7 +83,7 @@
<number>5</number>
</property>
<property name="placeholderText">
- <string>24872</string>
+ <string notr="true" extracomment="placeholder string that tells user default port">24872</string>
</property>
</widget>
</item>
diff --git a/src/yuzu/multiplayer/host_room.cpp b/src/yuzu/multiplayer/host_room.cpp
index cb9464b2b..0c6adfd04 100644
--- a/src/yuzu/multiplayer/host_room.cpp
+++ b/src/yuzu/multiplayer/host_room.cpp
@@ -12,7 +12,9 @@
#include <QtConcurrent/QtConcurrentRun>
#include "common/logging/log.h"
#include "common/settings.h"
-#include "core/announce_multiplayer_session.h"
+#include "core/core.h"
+#include "core/internal_network/network_interface.h"
+#include "network/announce_multiplayer_session.h"
#include "ui_host_room.h"
#include "yuzu/game_list_p.h"
#include "yuzu/main.h"
@@ -27,10 +29,11 @@
HostRoomWindow::HostRoomWindow(QWidget* parent, QStandardItemModel* list,
std::shared_ptr<Core::AnnounceMultiplayerSession> session,
- Network::RoomNetwork& room_network_)
+ Core::System& system_)
: QDialog(parent, Qt::WindowTitleHint | Qt::WindowCloseButtonHint | Qt::WindowSystemMenuHint),
ui(std::make_unique<Ui::HostRoom>()),
- announce_multiplayer_session(session), room_network{room_network_} {
+ announce_multiplayer_session(session), system{system_}, room_network{
+ system.GetRoomNetwork()} {
ui->setupUi(this);
// set up validation for all of the fields
@@ -105,6 +108,11 @@ std::unique_ptr<Network::VerifyUser::Backend> HostRoomWindow::CreateVerifyBacken
}
void HostRoomWindow::Host() {
+ if (!Network::GetSelectedNetworkInterface()) {
+ NetworkMessage::ErrorManager::ShowError(
+ NetworkMessage::ErrorManager::NO_INTERFACE_SELECTED);
+ return;
+ }
if (!ui->username->hasAcceptableInput()) {
NetworkMessage::ErrorManager::ShowError(NetworkMessage::ErrorManager::USERNAME_NOT_VALID);
return;
@@ -121,6 +129,11 @@ void HostRoomWindow::Host() {
NetworkMessage::ErrorManager::ShowError(NetworkMessage::ErrorManager::GAME_NOT_SELECTED);
return;
}
+ if (system.IsPoweredOn()) {
+ if (!NetworkMessage::WarnGameRunning()) {
+ return;
+ }
+ }
if (auto member = room_network.GetRoomMember().lock()) {
if (member->GetState() == Network::RoomMember::State::Joining) {
return;
@@ -201,8 +214,8 @@ void HostRoomWindow::Host() {
}
#endif
// TODO: Check what to do with this
- member->Join(ui->username->text().toStdString(), "", "127.0.0.1", port, 0,
- Network::NoPreferredMac, password, token);
+ member->Join(ui->username->text().toStdString(), "127.0.0.1", port, 0,
+ Network::NoPreferredIP, password, token);
// Store settings
UISettings::values.multiplayer_room_nickname = ui->username->text();
diff --git a/src/yuzu/multiplayer/host_room.h b/src/yuzu/multiplayer/host_room.h
index a968042d0..034cb2eef 100644
--- a/src/yuzu/multiplayer/host_room.h
+++ b/src/yuzu/multiplayer/host_room.h
@@ -17,8 +17,9 @@ class HostRoom;
}
namespace Core {
+class System;
class AnnounceMultiplayerSession;
-}
+} // namespace Core
class ConnectionError;
class ComboBoxProxyModel;
@@ -35,7 +36,7 @@ class HostRoomWindow : public QDialog {
public:
explicit HostRoomWindow(QWidget* parent, QStandardItemModel* list,
std::shared_ptr<Core::AnnounceMultiplayerSession> session,
- Network::RoomNetwork& room_network_);
+ Core::System& system_);
~HostRoomWindow();
/**
@@ -54,6 +55,7 @@ private:
QStandardItemModel* game_list;
ComboBoxProxyModel* proxy;
Validation validation;
+ Core::System& system;
Network::RoomNetwork& room_network;
};
diff --git a/src/yuzu/multiplayer/lobby.cpp b/src/yuzu/multiplayer/lobby.cpp
index 23c2f21ab..107d40547 100644
--- a/src/yuzu/multiplayer/lobby.cpp
+++ b/src/yuzu/multiplayer/lobby.cpp
@@ -6,6 +6,8 @@
#include <QtConcurrent/QtConcurrentRun>
#include "common/logging/log.h"
#include "common/settings.h"
+#include "core/core.h"
+#include "core/internal_network/network_interface.h"
#include "network/network.h"
#include "ui_lobby.h"
#include "yuzu/game_list_p.h"
@@ -22,11 +24,11 @@
#endif
Lobby::Lobby(QWidget* parent, QStandardItemModel* list,
- std::shared_ptr<Core::AnnounceMultiplayerSession> session,
- Network::RoomNetwork& room_network_)
+ std::shared_ptr<Core::AnnounceMultiplayerSession> session, Core::System& system_)
: QDialog(parent, Qt::WindowTitleHint | Qt::WindowCloseButtonHint | Qt::WindowSystemMenuHint),
ui(std::make_unique<Ui::Lobby>()),
- announce_multiplayer_session(session), room_network{room_network_} {
+ announce_multiplayer_session(session), system{system_}, room_network{
+ system.GetRoomNetwork()} {
ui->setupUi(this);
// setup the watcher for background connections
@@ -114,6 +116,18 @@ void Lobby::OnExpandRoom(const QModelIndex& index) {
}
void Lobby::OnJoinRoom(const QModelIndex& source) {
+ if (!Network::GetSelectedNetworkInterface()) {
+ NetworkMessage::ErrorManager::ShowError(
+ NetworkMessage::ErrorManager::NO_INTERFACE_SELECTED);
+ return;
+ }
+
+ if (system.IsPoweredOn()) {
+ if (!NetworkMessage::WarnGameRunning()) {
+ return;
+ }
+ }
+
if (const auto member = room_network.GetRoomMember().lock()) {
// Prevent the user from trying to join a room while they are already joining.
if (member->GetState() == Network::RoomMember::State::Joining) {
@@ -169,7 +183,7 @@ void Lobby::OnJoinRoom(const QModelIndex& source) {
}
#endif
if (auto room_member = room_network.GetRoomMember().lock()) {
- room_member->Join(nickname, "", ip.c_str(), port, 0, Network::NoPreferredMac, password,
+ room_member->Join(nickname, ip.c_str(), port, 0, Network::NoPreferredIP, password,
token);
}
});
diff --git a/src/yuzu/multiplayer/lobby.h b/src/yuzu/multiplayer/lobby.h
index 82744ca94..2696aec21 100644
--- a/src/yuzu/multiplayer/lobby.h
+++ b/src/yuzu/multiplayer/lobby.h
@@ -9,7 +9,7 @@
#include <QSortFilterProxyModel>
#include <QStandardItemModel>
#include "common/announce_multiplayer_room.h"
-#include "core/announce_multiplayer_session.h"
+#include "network/announce_multiplayer_session.h"
#include "network/network.h"
#include "yuzu/multiplayer/validation.h"
@@ -20,6 +20,10 @@ class Lobby;
class LobbyModel;
class LobbyFilterProxyModel;
+namespace Core {
+class System;
+}
+
/**
* Listing of all public games pulled from services. The lobby should be simple enough for users to
* find the game they want to play, and join it.
@@ -30,7 +34,7 @@ class Lobby : public QDialog {
public:
explicit Lobby(QWidget* parent, QStandardItemModel* list,
std::shared_ptr<Core::AnnounceMultiplayerSession> session,
- Network::RoomNetwork& room_network_);
+ Core::System& system_);
~Lobby() override;
/**
@@ -94,6 +98,7 @@ private:
std::weak_ptr<Core::AnnounceMultiplayerSession> announce_multiplayer_session;
QFutureWatcher<void>* watcher;
Validation validation;
+ Core::System& system;
Network::RoomNetwork& room_network;
};
diff --git a/src/yuzu/multiplayer/message.cpp b/src/yuzu/multiplayer/message.cpp
index 76ec276ad..758b5b731 100644
--- a/src/yuzu/multiplayer/message.cpp
+++ b/src/yuzu/multiplayer/message.cpp
@@ -43,15 +43,15 @@ const ConnectionError ErrorManager::LOST_CONNECTION(
QT_TR_NOOP("Connection to room lost. Try to reconnect."));
const ConnectionError ErrorManager::HOST_KICKED(
QT_TR_NOOP("You have been kicked by the room host."));
-const ConnectionError ErrorManager::MAC_COLLISION(
- QT_TR_NOOP("MAC address is already in use. Please choose another."));
-const ConnectionError ErrorManager::CONSOLE_ID_COLLISION(QT_TR_NOOP(
- "Your Console ID conflicted with someone else's in the room.\n\nPlease go to Emulation "
- "> Configure > System to regenerate your Console ID."));
+const ConnectionError ErrorManager::IP_COLLISION(
+ QT_TR_NOOP("IP address is already in use. Please choose another."));
const ConnectionError ErrorManager::PERMISSION_DENIED(
QT_TR_NOOP("You do not have enough permission to perform this action."));
const ConnectionError ErrorManager::NO_SUCH_USER(QT_TR_NOOP(
"The user you are trying to kick/ban could not be found.\nThey may have left the room."));
+const ConnectionError ErrorManager::NO_INTERFACE_SELECTED(
+ QT_TR_NOOP("No network interface is selected.\nPlease go to Configure -> System -> Network and "
+ "make a selection."));
static bool WarnMessage(const std::string& title, const std::string& text) {
return QMessageBox::Ok == QMessageBox::warning(nullptr, QObject::tr(title.c_str()),
@@ -63,6 +63,13 @@ void ErrorManager::ShowError(const ConnectionError& e) {
QMessageBox::critical(nullptr, tr("Error"), tr(e.GetString().c_str()));
}
+bool WarnGameRunning() {
+ return WarnMessage(
+ QT_TR_NOOP("Game already running"),
+ QT_TR_NOOP("Joining a room when the game is already running is discouraged "
+ "and can cause the room feature not to work correctly.\nProceed anyway?"));
+}
+
bool WarnCloseRoom() {
return WarnMessage(
QT_TR_NOOP("Leave Room"),
diff --git a/src/yuzu/multiplayer/message.h b/src/yuzu/multiplayer/message.h
index eb5c8d1be..f038b9a1f 100644
--- a/src/yuzu/multiplayer/message.h
+++ b/src/yuzu/multiplayer/message.h
@@ -40,15 +40,23 @@ public:
static const ConnectionError GENERIC_ERROR;
static const ConnectionError LOST_CONNECTION;
static const ConnectionError HOST_KICKED;
- static const ConnectionError MAC_COLLISION;
- static const ConnectionError CONSOLE_ID_COLLISION;
+ static const ConnectionError IP_COLLISION;
static const ConnectionError PERMISSION_DENIED;
static const ConnectionError NO_SUCH_USER;
+ static const ConnectionError NO_INTERFACE_SELECTED;
/**
* Shows a standard QMessageBox with a error message
*/
static void ShowError(const ConnectionError& e);
};
+
+/**
+ * Show a standard QMessageBox with a warning message about joining a room when
+ * the game is already running
+ * return true if the user wants to close the network connection
+ */
+bool WarnGameRunning();
+
/**
* Show a standard QMessageBox with a warning message about leaving the room
* return true if the user wants to close the network connection
diff --git a/src/yuzu/multiplayer/state.cpp b/src/yuzu/multiplayer/state.cpp
index 4149b5232..66e098296 100644
--- a/src/yuzu/multiplayer/state.cpp
+++ b/src/yuzu/multiplayer/state.cpp
@@ -8,6 +8,7 @@
#include <QStandardItemModel>
#include "common/announce_multiplayer_room.h"
#include "common/logging/log.h"
+#include "core/core.h"
#include "yuzu/game_list.h"
#include "yuzu/multiplayer/client_room.h"
#include "yuzu/multiplayer/direct_connect.h"
@@ -19,10 +20,9 @@
#include "yuzu/util/clickable_label.h"
MultiplayerState::MultiplayerState(QWidget* parent, QStandardItemModel* game_list_model_,
- QAction* leave_room_, QAction* show_room_,
- Network::RoomNetwork& room_network_)
+ QAction* leave_room_, QAction* show_room_, Core::System& system_)
: QWidget(parent), game_list_model(game_list_model_), leave_room(leave_room_),
- show_room(show_room_), room_network{room_network_} {
+ show_room(show_room_), system{system_}, room_network{system.GetRoomNetwork()} {
if (auto member = room_network.GetRoomMember().lock()) {
// register the network structs to use in slots and signals
state_callback_handle = member->BindOnStateChanged(
@@ -59,7 +59,9 @@ MultiplayerState::MultiplayerState(QWidget* parent, QStandardItemModel* game_lis
});
}
-MultiplayerState::~MultiplayerState() {
+MultiplayerState::~MultiplayerState() = default;
+
+void MultiplayerState::Close() {
if (state_callback_handle) {
if (auto member = room_network.GetRoomMember().lock()) {
member->Unbind(state_callback_handle);
@@ -71,9 +73,6 @@ MultiplayerState::~MultiplayerState() {
member->Unbind(error_callback_handle);
}
}
-}
-
-void MultiplayerState::Close() {
if (host_room) {
host_room->close();
}
@@ -95,7 +94,6 @@ void MultiplayerState::retranslateUi() {
status_text->setText(tr("Not Connected. Click here to find a room!"));
} else if (current_state == Network::RoomMember::State::Joined ||
current_state == Network::RoomMember::State::Moderator) {
-
status_text->setText(tr("Connected"));
} else {
status_text->setText(tr("Not Connected"));
@@ -151,11 +149,8 @@ void MultiplayerState::OnNetworkError(const Network::RoomMember::Error& error) {
NetworkMessage::ErrorManager::ShowError(
NetworkMessage::ErrorManager::USERNAME_NOT_VALID_SERVER);
break;
- case Network::RoomMember::Error::MacCollision:
- NetworkMessage::ErrorManager::ShowError(NetworkMessage::ErrorManager::MAC_COLLISION);
- break;
- case Network::RoomMember::Error::ConsoleIdCollision:
- NetworkMessage::ErrorManager::ShowError(NetworkMessage::ErrorManager::CONSOLE_ID_COLLISION);
+ case Network::RoomMember::Error::IpCollision:
+ NetworkMessage::ErrorManager::ShowError(NetworkMessage::ErrorManager::IP_COLLISION);
break;
case Network::RoomMember::Error::RoomIsFull:
NetworkMessage::ErrorManager::ShowError(NetworkMessage::ErrorManager::ROOM_IS_FULL);
@@ -213,15 +208,14 @@ static void BringWidgetToFront(QWidget* widget) {
void MultiplayerState::OnViewLobby() {
if (lobby == nullptr) {
- lobby = new Lobby(this, game_list_model, announce_multiplayer_session, room_network);
+ lobby = new Lobby(this, game_list_model, announce_multiplayer_session, system);
}
BringWidgetToFront(lobby);
}
void MultiplayerState::OnCreateRoom() {
if (host_room == nullptr) {
- host_room =
- new HostRoomWindow(this, game_list_model, announce_multiplayer_session, room_network);
+ host_room = new HostRoomWindow(this, game_list_model, announce_multiplayer_session, system);
}
BringWidgetToFront(host_room);
}
@@ -284,7 +278,7 @@ void MultiplayerState::OnOpenNetworkRoom() {
void MultiplayerState::OnDirectConnectToRoom() {
if (direct_connect == nullptr) {
- direct_connect = new DirectConnectWindow(room_network, this);
+ direct_connect = new DirectConnectWindow(system, this);
}
BringWidgetToFront(direct_connect);
}
diff --git a/src/yuzu/multiplayer/state.h b/src/yuzu/multiplayer/state.h
index 9c60712d5..c92496413 100644
--- a/src/yuzu/multiplayer/state.h
+++ b/src/yuzu/multiplayer/state.h
@@ -4,7 +4,7 @@
#pragma once
#include <QWidget>
-#include "core/announce_multiplayer_session.h"
+#include "network/announce_multiplayer_session.h"
#include "network/network.h"
class QStandardItemModel;
@@ -14,12 +14,16 @@ class ClientRoomWindow;
class DirectConnectWindow;
class ClickableLabel;
+namespace Core {
+class System;
+}
+
class MultiplayerState : public QWidget {
Q_OBJECT;
public:
explicit MultiplayerState(QWidget* parent, QStandardItemModel* game_list, QAction* leave_room,
- QAction* show_room, Network::RoomNetwork& room_network_);
+ QAction* show_room, Core::System& system_);
~MultiplayerState();
/**
@@ -86,6 +90,7 @@ private:
Network::RoomMember::CallbackHandle<Network::RoomMember::Error> error_callback_handle;
bool show_notification = false;
+ Core::System& system;
Network::RoomNetwork& room_network;
};
diff --git a/src/yuzu/multiplayer/validation.h b/src/yuzu/multiplayer/validation.h
index 7d48e589d..dabf860be 100644
--- a/src/yuzu/multiplayer/validation.h
+++ b/src/yuzu/multiplayer/validation.h
@@ -10,7 +10,7 @@
class Validation {
public:
Validation()
- : room_name(room_name_regex), nickname(nickname_regex), ip(ip_regex), port(0, 65535) {}
+ : room_name(room_name_regex), nickname(nickname_regex), ip(ip_regex), port(0, UINT16_MAX) {}
~Validation() = default;
diff --git a/src/yuzu/uisettings.h b/src/yuzu/uisettings.h
index 25d1bf1e6..e12d414d9 100644
--- a/src/yuzu/uisettings.h
+++ b/src/yuzu/uisettings.h
@@ -104,11 +104,12 @@ struct Values {
// multiplayer settings
Settings::Setting<QString> multiplayer_nickname{QStringLiteral("yuzu"), "nickname"};
Settings::Setting<QString> multiplayer_ip{{}, "ip"};
- Settings::SwitchableSetting<uint, true> multiplayer_port{24872, 0, 65535, "port"};
+ Settings::SwitchableSetting<uint, true> multiplayer_port{24872, 0, UINT16_MAX, "port"};
Settings::Setting<QString> multiplayer_room_nickname{{}, "room_nickname"};
Settings::Setting<QString> multiplayer_room_name{{}, "room_name"};
Settings::SwitchableSetting<uint, true> multiplayer_max_player{8, 0, 8, "max_player"};
- Settings::SwitchableSetting<uint, true> multiplayer_room_port{24872, 0, 65535, "room_port"};
+ Settings::SwitchableSetting<uint, true> multiplayer_room_port{24872, 0, UINT16_MAX,
+ "room_port"};
Settings::SwitchableSetting<uint, true> multiplayer_host_type{0, 0, 1, "host_type"};
Settings::Setting<qulonglong> multiplayer_game_id{{}, "game_id"};
Settings::Setting<QString> multiplayer_room_description{{}, "room_description"};