Merge pull request #8875 from JosJuice/nkit-warning
DolphinQt: Show a warning when launching an NKit disc image
This commit is contained in:
commit
9d44df0f0b
|
@ -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,22 +988,18 @@ void VolumeVerifier::CheckMisc()
|
|||
}
|
||||
}
|
||||
|
||||
if (IsDisc(m_volume.GetVolumeType()))
|
||||
if (m_volume.IsNKit())
|
||||
{
|
||||
constexpr u32 NKIT_MAGIC = 0x4E4B4954; // "NKIT"
|
||||
if (m_volume.ReadSwapped<u32>(0x200, PARTITION_NONE) == NKIT_MAGIC)
|
||||
{
|
||||
AddProblem(
|
||||
Severity::Low,
|
||||
Common::GetStringT("This disc image is in the NKit format. It is not a good dump in its "
|
||||
"current form, but it might become a good dump if converted back. "
|
||||
"The CRC32 of this file might match the CRC32 of a good dump even "
|
||||
"though the files are not identical."));
|
||||
}
|
||||
|
||||
if (StringBeginsWith(game_id_unencrypted, "R8P"))
|
||||
CheckSuperPaperMario();
|
||||
AddProblem(
|
||||
Severity::Low,
|
||||
Common::GetStringT("This disc image is in the NKit format. It is not a good dump in its "
|
||||
"current form, but it might become a good dump if converted back. "
|
||||
"The CRC32 of this file might match the CRC32 of a good dump even "
|
||||
"though the files are not identical."));
|
||||
}
|
||||
|
||||
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