DolphinQt: Show a warning when launching an NKit disc image
It is my opinion that nobody should use NKit disc images without being aware of the drawbacks of them. Since it seems like almost nobody who is using NKit disc images knows what NKit is (hmm, now how could that have happened...?), I am adding a warning to Dolphin so that you can't run NKit disc images without finding out about the drawbacks. In case someone really does want to use NKit disc images, the warning has a "Don't show this again" option. Unfortunately, I can't retroactively add the warning where it's most needed: in Dolphin 5.0, which does not support Wii NKit disc images.
This commit is contained in:
parent
b354e343a7
commit
2e8c5b4521
|
@ -142,6 +142,7 @@ const Info<std::string> MAIN_FS_PATH{{System::Main, "General", "NANDRootPath"},
|
|||
const Info<std::string> MAIN_SD_PATH{{System::Main, "General", "WiiSDCardPath"}, ""};
|
||||
|
||||
// Main.Network
|
||||
|
||||
const Info<bool> MAIN_NETWORK_SSL_DUMP_READ{{System::Main, "Network", "SSLDumpRead"}, false};
|
||||
const Info<bool> MAIN_NETWORK_SSL_DUMP_WRITE{{System::Main, "Network", "SSLDumpWrite"}, false};
|
||||
const Info<bool> MAIN_NETWORK_SSL_VERIFY_CERTIFICATES{
|
||||
|
@ -149,4 +150,8 @@ const Info<bool> MAIN_NETWORK_SSL_VERIFY_CERTIFICATES{
|
|||
const Info<bool> MAIN_NETWORK_SSL_DUMP_ROOT_CA{{System::Main, "Network", "SSLDumpRootCA"}, false};
|
||||
const Info<bool> MAIN_NETWORK_SSL_DUMP_PEER_CERT{{System::Main, "Network", "SSLDumpPeerCert"},
|
||||
false};
|
||||
|
||||
// Main.Interface
|
||||
|
||||
const Info<bool> MAIN_SKIP_NKIT_WARNING{{System::Main, "Interface", "SkipNKitWarning"}, false};
|
||||
} // namespace Config
|
||||
|
|
|
@ -126,4 +126,8 @@ extern const Info<bool> MAIN_NETWORK_SSL_DUMP_WRITE;
|
|||
extern const Info<bool> MAIN_NETWORK_SSL_VERIFY_CERTIFICATES;
|
||||
extern const Info<bool> MAIN_NETWORK_SSL_DUMP_ROOT_CA;
|
||||
extern const Info<bool> MAIN_NETWORK_SSL_DUMP_PEER_CERT;
|
||||
|
||||
// Main.Interface
|
||||
|
||||
extern const Info<bool> MAIN_SKIP_NKIT_WARNING;
|
||||
} // namespace Config
|
||||
|
|
|
@ -32,7 +32,7 @@ bool IsSettingSaveable(const Config::Location& config_location)
|
|||
}
|
||||
}
|
||||
|
||||
static constexpr std::array<const Config::Location*, 12> s_setting_saveable = {
|
||||
static constexpr std::array<const Config::Location*, 13> s_setting_saveable = {
|
||||
// Main.Core
|
||||
|
||||
&Config::MAIN_DEFAULT_ISO.location,
|
||||
|
@ -47,6 +47,10 @@ bool IsSettingSaveable(const Config::Location& config_location)
|
|||
&Config::MAIN_MEM2_SIZE.location,
|
||||
&Config::MAIN_GFX_BACKEND.location,
|
||||
|
||||
// Main.Interface
|
||||
|
||||
&Config::MAIN_SKIP_NKIT_WARNING.location,
|
||||
|
||||
// UI.General
|
||||
|
||||
&Config::MAIN_USE_DISCORD_PRESENCE.location,
|
||||
|
|
|
@ -116,6 +116,7 @@ public:
|
|||
}
|
||||
virtual Platform GetVolumeType() const = 0;
|
||||
virtual bool IsDatelDisc() const = 0;
|
||||
virtual bool IsNKit() const = 0;
|
||||
virtual bool SupportsIntegrityCheck() const { return false; }
|
||||
virtual bool CheckH3TableIntegrity(const Partition& partition) const { return false; }
|
||||
virtual bool CheckBlockIntegrity(u64 block_index, const std::vector<u8>& encrypted_data,
|
||||
|
|
|
@ -84,4 +84,10 @@ std::optional<u8> VolumeDisc::GetDiscNumber(const Partition& partition) const
|
|||
return ReadSwapped<u8>(6, partition);
|
||||
}
|
||||
|
||||
bool VolumeDisc::IsNKit() const
|
||||
{
|
||||
constexpr u32 NKIT_MAGIC = 0x4E4B4954; // "NKIT"
|
||||
return ReadSwapped<u32>(0x200, PARTITION_NONE) == NKIT_MAGIC;
|
||||
}
|
||||
|
||||
} // namespace DiscIO
|
||||
|
|
|
@ -22,6 +22,7 @@ public:
|
|||
std::string GetInternalName(const Partition& partition = PARTITION_NONE) const override;
|
||||
std::string GetApploaderDate(const Partition& partition) const override;
|
||||
std::optional<u8> GetDiscNumber(const Partition& partition = PARTITION_NONE) const override;
|
||||
bool IsNKit() const override;
|
||||
|
||||
protected:
|
||||
Region RegionCodeToRegion(std::optional<u32> region_code) const;
|
||||
|
|
|
@ -988,10 +988,7 @@ void VolumeVerifier::CheckMisc()
|
|||
}
|
||||
}
|
||||
|
||||
if (IsDisc(m_volume.GetVolumeType()))
|
||||
{
|
||||
constexpr u32 NKIT_MAGIC = 0x4E4B4954; // "NKIT"
|
||||
if (m_volume.ReadSwapped<u32>(0x200, PARTITION_NONE) == NKIT_MAGIC)
|
||||
if (m_volume.IsNKit())
|
||||
{
|
||||
AddProblem(
|
||||
Severity::Low,
|
||||
|
@ -1001,9 +998,8 @@ void VolumeVerifier::CheckMisc()
|
|||
"though the files are not identical."));
|
||||
}
|
||||
|
||||
if (StringBeginsWith(game_id_unencrypted, "R8P"))
|
||||
if (IsDisc(m_volume.GetVolumeType()) && StringBeginsWith(game_id_unencrypted, "R8P"))
|
||||
CheckSuperPaperMario();
|
||||
}
|
||||
}
|
||||
|
||||
void VolumeVerifier::CheckSuperPaperMario()
|
||||
|
|
|
@ -289,6 +289,11 @@ bool VolumeWAD::IsDatelDisc() const
|
|||
return false;
|
||||
}
|
||||
|
||||
bool VolumeWAD::IsNKit() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
std::map<Language, std::string> VolumeWAD::GetLongNames() const
|
||||
{
|
||||
if (!m_tmd.IsValid() || !IOS::ES::IsChannel(m_tmd.GetTitleId()))
|
||||
|
|
|
@ -60,6 +60,7 @@ public:
|
|||
}
|
||||
Platform GetVolumeType() const override;
|
||||
bool IsDatelDisc() const override;
|
||||
bool IsNKit() const override;
|
||||
Region GetRegion() const override;
|
||||
Country GetCountry(const Partition& partition = PARTITION_NONE) const override;
|
||||
|
||||
|
|
|
@ -37,6 +37,8 @@ add_executable(dolphin-emu
|
|||
MainWindow.h
|
||||
MenuBar.cpp
|
||||
MenuBar.h
|
||||
NKitWarningDialog.cpp
|
||||
NKitWarningDialog.h
|
||||
RenderWidget.cpp
|
||||
RenderWidget.h
|
||||
Resources.cpp
|
||||
|
|
|
@ -178,6 +178,7 @@
|
|||
<QtMoc Include="NetPlay\NetPlayDialog.h" />
|
||||
<QtMoc Include="NetPlay\NetPlaySetupDialog.h" />
|
||||
<QtMoc Include="NetPlay\PadMappingDialog.h" />
|
||||
<QtMoc Include="NKitWarningDialog.h" />
|
||||
<QtMoc Include="QtUtils\AspectRatioWidget.h" />
|
||||
<QtMoc Include="QtUtils\BlockUserInputFilter.h" />
|
||||
<QtMoc Include="QtUtils\DoubleClickEventFilter.h" />
|
||||
|
@ -290,6 +291,7 @@
|
|||
<ClCompile Include="$(QtMocOutPrefix)NetPlaySetupDialog.cpp" />
|
||||
<ClCompile Include="$(QtMocOutPrefix)NewBreakpointDialog.cpp" />
|
||||
<ClCompile Include="$(QtMocOutPrefix)NewPatchDialog.cpp" />
|
||||
<ClCompile Include="$(QtMocOutPrefix)NKitWarningDialog.cpp" />
|
||||
<ClCompile Include="$(QtMocOutPrefix)PadMappingDialog.cpp" />
|
||||
<ClCompile Include="$(QtMocOutPrefix)ParallelProgressDialog.cpp" />
|
||||
<ClCompile Include="$(QtMocOutPrefix)UTF8CodePointCountValidator.cpp" />
|
||||
|
@ -394,6 +396,7 @@
|
|||
<ClCompile Include="DiscordJoinRequestDialog.cpp" />
|
||||
<ClCompile Include="FIFO\FIFOAnalyzer.cpp" />
|
||||
<ClCompile Include="FIFO\FIFOPlayerWindow.cpp" />
|
||||
<ClCompile Include="NKitWarningDialog.cpp" />
|
||||
<ClCompile Include="QtUtils\WinIconHelper.cpp" />
|
||||
<ClCompile Include="ResourcePackManager.cpp" />
|
||||
<ClCompile Include="TAS\GCTASInputWindow.cpp" />
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
|
||||
#include <future>
|
||||
#include <optional>
|
||||
#include <variant>
|
||||
|
||||
#if defined(__unix__) || defined(__unix) || defined(__APPLE__)
|
||||
#include <signal.h>
|
||||
|
@ -83,6 +84,7 @@
|
|||
#include "DolphinQt/HotkeyScheduler.h"
|
||||
#include "DolphinQt/MainWindow.h"
|
||||
#include "DolphinQt/MenuBar.h"
|
||||
#include "DolphinQt/NKitWarningDialog.h"
|
||||
#include "DolphinQt/NetPlay/NetPlayBrowser.h"
|
||||
#include "DolphinQt/NetPlay/NetPlayDialog.h"
|
||||
#include "DolphinQt/NetPlay/NetPlaySetupDialog.h"
|
||||
|
@ -952,6 +954,15 @@ void MainWindow::StartGame(const std::vector<std::string>& paths,
|
|||
|
||||
void MainWindow::StartGame(std::unique_ptr<BootParameters>&& parameters)
|
||||
{
|
||||
if (std::holds_alternative<BootParameters::Disc>(parameters->parameters))
|
||||
{
|
||||
if (std::get<BootParameters::Disc>(parameters->parameters).volume->IsNKit())
|
||||
{
|
||||
if (!NKitWarningDialog::ShowUnlessDisabled())
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// If we're running, only start a new game once we've stopped the last.
|
||||
if (Core::GetState() != Core::State::Uninitialized)
|
||||
{
|
||||
|
|
|
@ -0,0 +1,87 @@
|
|||
// Copyright 2020 Dolphin Emulator Project
|
||||
// Licensed under GPLv2+
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include "DolphinQt/NKitWarningDialog.h"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QCheckBox>
|
||||
#include <QHBoxLayout>
|
||||
#include <QIcon>
|
||||
#include <QLabel>
|
||||
#include <QPushButton>
|
||||
#include <QStyle>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
#include "Common/Config/Config.h"
|
||||
#include "Core/Config/MainSettings.h"
|
||||
#include "DolphinQt/Resources.h"
|
||||
|
||||
bool NKitWarningDialog::ShowUnlessDisabled(QWidget* parent)
|
||||
{
|
||||
if (Config::Get(Config::MAIN_SKIP_NKIT_WARNING))
|
||||
return true;
|
||||
else
|
||||
return NKitWarningDialog(parent).exec() == QDialog::Accepted;
|
||||
}
|
||||
|
||||
NKitWarningDialog::NKitWarningDialog(QWidget* parent) : QDialog(parent)
|
||||
{
|
||||
setWindowTitle(tr("NKit Warning"));
|
||||
setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
|
||||
setWindowIcon(Resources::GetAppIcon());
|
||||
|
||||
QVBoxLayout* main_layout = new QVBoxLayout;
|
||||
|
||||
QLabel* warning = new QLabel(
|
||||
tr("You are about to run an NKit disc image. NKit disc images cause problems that don't "
|
||||
"happen with normal disc images. These problems include:\n"
|
||||
"\n"
|
||||
"• The emulated loading times are longer\n"
|
||||
"• You can't use NetPlay with people who have normal disc images\n"
|
||||
"• Input recordings are not compatible between NKit disc images and normal disc images\n"
|
||||
"• Savestates are not compatible between NKit disc images and normal disc images\n"
|
||||
"• Some games crash, such as Super Paper Mario\n"
|
||||
"• Wii games don't work at all in older versions of Dolphin and in many other programs\n"
|
||||
"\n"
|
||||
"Are you sure you want to continue anyway?\n"));
|
||||
warning->setWordWrap(true);
|
||||
main_layout->addWidget(warning);
|
||||
|
||||
QCheckBox* checkbox_accept = new QCheckBox(tr("I am aware of the risks and want to continue"));
|
||||
main_layout->addWidget(checkbox_accept);
|
||||
|
||||
QCheckBox* checkbox_skip = new QCheckBox(tr("Don't show this again"));
|
||||
main_layout->addWidget(checkbox_skip);
|
||||
|
||||
QHBoxLayout* button_layout = new QHBoxLayout;
|
||||
QPushButton* ok = new QPushButton(tr("OK"));
|
||||
button_layout->addWidget(ok);
|
||||
QPushButton* cancel = new QPushButton(tr("Cancel"));
|
||||
button_layout->addWidget(cancel);
|
||||
main_layout->addLayout(button_layout);
|
||||
|
||||
QHBoxLayout* top_layout = new QHBoxLayout;
|
||||
|
||||
QIcon icon = QApplication::style()->standardIcon(QStyle::SP_MessageBoxWarning);
|
||||
QLabel* icon_label = new QLabel;
|
||||
icon_label->setPixmap(icon.pixmap(100));
|
||||
icon_label->setAlignment(Qt::AlignTop);
|
||||
top_layout->addWidget(icon_label);
|
||||
top_layout->addSpacing(10);
|
||||
|
||||
top_layout->addLayout(main_layout);
|
||||
|
||||
setLayout(top_layout);
|
||||
|
||||
connect(ok, &QPushButton::clicked, this, &QDialog::accept);
|
||||
connect(cancel, &QPushButton::clicked, this, &QDialog::reject);
|
||||
|
||||
ok->setEnabled(false);
|
||||
connect(checkbox_accept, &QCheckBox::stateChanged,
|
||||
[&ok](int state) { ok->setEnabled(state == Qt::Checked); });
|
||||
|
||||
connect(this, &QDialog::accepted, [checkbox_skip] {
|
||||
Config::SetBase(Config::MAIN_SKIP_NKIT_WARNING, checkbox_skip->isChecked());
|
||||
});
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
// Copyright 2020 Dolphin Emulator Project
|
||||
// Licensed under GPLv2+
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QDialog>
|
||||
#include <QWidget>
|
||||
|
||||
class NKitWarningDialog final : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
static bool ShowUnlessDisabled(QWidget* parent = nullptr);
|
||||
|
||||
private:
|
||||
explicit NKitWarningDialog(QWidget* parent = nullptr);
|
||||
};
|
Loading…
Reference in New Issue