diff options
author | Jesse Talavera-Greenberg <jesse@jesse.tg> | 2023-10-11 11:20:05 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-10-11 17:20:05 +0200 |
commit | d4e51f80601f57399db49f1010c45427bd2bf3c4 (patch) | |
tree | 206985e7bedfc1755941eeba26d6605d4e03fa0a /src/frontend | |
parent | b2fcff97c186cc9db263089acd4810ea7d58517d (diff) |
Refactor DSi_NAND (#1844)
* Refactor diskio's contents
- Change ff_disk_read_cb/write_cb into a std::function instead of a raw pointer
- Add const specifiers as needed
* Refactor DSi_NAND to manage the file system's mounted lifetime with RAII
* Split NANDMount into NANDMount and NANDImage
- NANDImage is used for information about the NAND that doesn't require decryption or filesystem access
- NANDMount is used to actually access the file system
- Both classes manage their respective resources (the NAND file handle and the NAND's mount) with RAII
- Also split the file loading into another function that I will remove in a later PR
* Make NANDMount immovable
* Remove NAND-loading code that I had sectioned off into a function
- Incomplete copypasta
- I must have gotten distracted
* Tidy up NANDImage's initialization
- Don't unmount the disk image if the constructor fails (that's NANDMount's job now)
- Only assign CurFile if the constructor succeeds
* Add some const-correctness
* Move DSi NAND initialization to the frontend
- The NANDImage is now installed via a unique_ptr in DSi
* Remove Platform::DSi_NANDPath
- Not Config::DSiNANDPath; that can still be configured as usual
- The core no longer needs to care
Diffstat (limited to 'src/frontend')
-rw-r--r-- | src/frontend/qt_sdl/Platform.cpp | 2 | ||||
-rw-r--r-- | src/frontend/qt_sdl/ROMManager.cpp | 51 | ||||
-rw-r--r-- | src/frontend/qt_sdl/ROMManager.h | 2 | ||||
-rw-r--r-- | src/frontend/qt_sdl/TitleManagerDialog.cpp | 51 | ||||
-rw-r--r-- | src/frontend/qt_sdl/TitleManagerDialog.h | 15 |
5 files changed, 92 insertions, 29 deletions
diff --git a/src/frontend/qt_sdl/Platform.cpp b/src/frontend/qt_sdl/Platform.cpp index 0574d5d..7f6e1d5 100644 --- a/src/frontend/qt_sdl/Platform.cpp +++ b/src/frontend/qt_sdl/Platform.cpp @@ -250,8 +250,6 @@ std::string GetConfigString(ConfigEntry entry) { switch (entry) { - case DSi_NANDPath: return Config::DSiNANDPath; - case DLDI_ImagePath: return Config::DLDISDPath; case DLDI_FolderPath: return Config::DLDIFolderPath; diff --git a/src/frontend/qt_sdl/ROMManager.cpp b/src/frontend/qt_sdl/ROMManager.cpp index 49f4c45..206332b 100644 --- a/src/frontend/qt_sdl/ROMManager.cpp +++ b/src/frontend/qt_sdl/ROMManager.cpp @@ -595,6 +595,10 @@ void Reset() LoadBIOSFiles(); InstallFirmware(); + if (Config::ConsoleType == 1) + { + InstallNAND(&DSi::ARM7iBIOS[0x8308]); + } NDS::Reset(); SetBatteryLevels(); @@ -657,6 +661,9 @@ bool LoadBIOS() if (!InstallFirmware()) return false; + if (Config::ConsoleType == 1 && !InstallNAND(&DSi::ARM7iBIOS[0x8308])) + return false; + if (NDS::NeedsDirectBoot()) return false; @@ -948,6 +955,47 @@ void LoadUserSettingsFromConfig(SPI_Firmware::Firmware& firmware) firmware.UpdateChecksums(); } +static Platform::FileHandle* OpenNANDFile() noexcept +{ + std::string nandpath = Config::DSiNANDPath; + std::string instnand = nandpath + Platform::InstanceFileSuffix(); + + FileHandle* nandfile = Platform::OpenLocalFile(instnand, FileMode::ReadWriteExisting); + if ((!nandfile) && (Platform::InstanceID() > 0)) + { + FileHandle* orig = Platform::OpenLocalFile(nandpath, FileMode::Read); + if (!orig) + { + Log(LogLevel::Error, "Failed to open DSi NAND\n"); + return nullptr; + } + + QFile::copy(QString::fromStdString(nandpath), QString::fromStdString(instnand)); + + nandfile = Platform::OpenLocalFile(instnand, FileMode::ReadWriteExisting); + } + + return nandfile; +} + +bool InstallNAND(const u8* es_keyY) +{ + Platform::FileHandle* nandfile = OpenNANDFile(); + if (!nandfile) + return false; + + if (auto nand = std::make_unique<DSi_NAND::NANDImage>(nandfile, es_keyY); *nand) + { + DSi::NANDImage = std::move(nand); + return true; + } + else + { + DSi::NANDImage = nullptr; + return false; + } +} + bool InstallFirmware() { using namespace SPI_Firmware; @@ -1089,6 +1137,9 @@ bool LoadROM(QStringList filepath, bool reset) NDS::SetConsoleType(Config::ConsoleType); NDS::EjectCart(); LoadBIOSFiles(); + if (Config::ConsoleType == 1) + InstallNAND(&DSi::ARM7iBIOS[0x8308]); + NDS::Reset(); SetBatteryLevels(); } diff --git a/src/frontend/qt_sdl/ROMManager.h b/src/frontend/qt_sdl/ROMManager.h index 5faef1a..2eeed0a 100644 --- a/src/frontend/qt_sdl/ROMManager.h +++ b/src/frontend/qt_sdl/ROMManager.h @@ -22,6 +22,7 @@ #include "types.h" #include "SaveManager.h" #include "AREngine.h" +#include "DSi_NAND.h" #include <string> #include <memory> @@ -40,6 +41,7 @@ bool LoadBIOS(); void ClearBackupState(); bool InstallFirmware(); +bool InstallNAND(const u8* es_keyY); bool LoadROM(QStringList filepath, bool reset); void EjectCart(); bool CartInserted(); diff --git a/src/frontend/qt_sdl/TitleManagerDialog.cpp b/src/frontend/qt_sdl/TitleManagerDialog.cpp index d5147fc..84bd1ef 100644 --- a/src/frontend/qt_sdl/TitleManagerDialog.cpp +++ b/src/frontend/qt_sdl/TitleManagerDialog.cpp @@ -32,13 +32,13 @@ using namespace Platform; -bool TitleManagerDialog::NANDInited = false; +std::unique_ptr<DSi_NAND::NANDImage> TitleManagerDialog::nand = nullptr; TitleManagerDialog* TitleManagerDialog::currentDlg = nullptr; extern std::string EmuDirectory; -TitleManagerDialog::TitleManagerDialog(QWidget* parent) : QDialog(parent), ui(new Ui::TitleManagerDialog) +TitleManagerDialog::TitleManagerDialog(QWidget* parent, DSi_NAND::NANDImage& image) : QDialog(parent), ui(new Ui::TitleManagerDialog), nandmount(image) { ui->setupUi(this); setAttribute(Qt::WA_DeleteOnClose); @@ -47,7 +47,7 @@ TitleManagerDialog::TitleManagerDialog(QWidget* parent) : QDialog(parent), ui(ne const u32 category = 0x00030004; std::vector<u32> titlelist; - DSi_NAND::ListTitles(category, titlelist); + nandmount.ListTitles(category, titlelist); for (std::vector<u32>::iterator it = titlelist.begin(); it != titlelist.end(); it++) { @@ -109,7 +109,7 @@ void TitleManagerDialog::createTitleItem(u32 category, u32 titleid) NDSHeader header; NDSBanner banner; - DSi_NAND::GetTitleInfo(category, titleid, version, &header, &banner); + nandmount.GetTitleInfo(category, titleid, version, &header, &banner); u32 icondata[32*32]; ROMManager::ROMIcon(banner.Icon, banner.Palette, icondata); @@ -137,7 +137,7 @@ void TitleManagerDialog::createTitleItem(u32 category, u32 titleid) bool TitleManagerDialog::openNAND() { - NANDInited = false; + nand = nullptr; FileHandle* bios7i = Platform::OpenLocalFile(Config::DSiBIOS7Path, FileMode::Read); if (!bios7i) @@ -148,22 +148,25 @@ bool TitleManagerDialog::openNAND() FileRead(es_keyY, 16, 1, bios7i); CloseFile(bios7i); - if (!DSi_NAND::Init(es_keyY)) - { + FileHandle* nandfile = Platform::OpenLocalFile(Config::DSiNANDPath, FileMode::ReadWriteExisting); + if (!nandfile) + return false; + + nand = std::make_unique<DSi_NAND::NANDImage>(nandfile, es_keyY); + if (!*nand) + { // If loading and mounting the NAND image failed... + nand = nullptr; return false; + // NOTE: The NANDImage takes ownership of the FileHandle, + // so it will be closed even if the NANDImage constructor fails. } - NANDInited = true; return true; } void TitleManagerDialog::closeNAND() { - if (NANDInited) - { - DSi_NAND::DeInit(); - NANDInited = false; - } + nand = nullptr; } void TitleManagerDialog::done(int r) @@ -175,7 +178,7 @@ void TitleManagerDialog::done(int r) void TitleManagerDialog::on_btnImportTitle_clicked() { - TitleImportDialog* importdlg = new TitleImportDialog(this, importAppPath, &importTmdData, importReadOnly); + TitleImportDialog* importdlg = new TitleImportDialog(this, importAppPath, &importTmdData, importReadOnly, nandmount); importdlg->open(); connect(importdlg, &TitleImportDialog::finished, this, &TitleManagerDialog::onImportTitleFinished); @@ -190,14 +193,16 @@ void TitleManagerDialog::onImportTitleFinished(int res) titleid[0] = importTmdData.GetCategory(); titleid[1] = importTmdData.GetID(); + assert(nand != nullptr); + assert(*nand); // remove anything that might hinder the install - DSi_NAND::DeleteTitle(titleid[0], titleid[1]); + nandmount.DeleteTitle(titleid[0], titleid[1]); - bool importres = DSi_NAND::ImportTitle(importAppPath.toStdString().c_str(), importTmdData, importReadOnly); + bool importres = nandmount.ImportTitle(importAppPath.toStdString().c_str(), importTmdData, importReadOnly); if (!importres) { // remove a potential half-completed install - DSi_NAND::DeleteTitle(titleid[0], titleid[1]); + nandmount.DeleteTitle(titleid[0], titleid[1]); QMessageBox::critical(this, "Import title - melonDS", @@ -224,7 +229,7 @@ void TitleManagerDialog::on_btnDeleteTitle_clicked() return; u64 titleid = cur->data(Qt::UserRole).toULongLong(); - DSi_NAND::DeleteTitle((u32)(titleid >> 32), (u32)titleid); + nandmount.DeleteTitle((u32)(titleid >> 32), (u32)titleid); delete cur; } @@ -317,7 +322,7 @@ void TitleManagerDialog::onImportTitleData() } u64 titleid = cur->data(Qt::UserRole).toULongLong(); - bool res = DSi_NAND::ImportTitleData((u32)(titleid >> 32), (u32)titleid, type, file.toStdString().c_str()); + bool res = nandmount.ImportTitleData((u32)(titleid >> 32), (u32)titleid, type, file.toStdString().c_str()); if (!res) { QMessageBox::critical(this, @@ -370,7 +375,7 @@ void TitleManagerDialog::onExportTitleData() if (file.isEmpty()) return; u64 titleid = cur->data(Qt::UserRole).toULongLong(); - bool res = DSi_NAND::ExportTitleData((u32)(titleid >> 32), (u32)titleid, type, file.toStdString().c_str()); + bool res = nandmount.ExportTitleData((u32)(titleid >> 32), (u32)titleid, type, file.toStdString().c_str()); if (!res) { QMessageBox::critical(this, @@ -380,8 +385,8 @@ void TitleManagerDialog::onExportTitleData() } -TitleImportDialog::TitleImportDialog(QWidget* parent, QString& apppath, const DSi_TMD::TitleMetadata* tmd, bool& readonly) -: QDialog(parent), ui(new Ui::TitleImportDialog), appPath(apppath), tmdData(tmd), readOnly(readonly) +TitleImportDialog::TitleImportDialog(QWidget* parent, QString& apppath, const DSi_TMD::TitleMetadata* tmd, bool& readonly, DSi_NAND::NANDMount& nandmount) +: QDialog(parent), ui(new Ui::TitleImportDialog), appPath(apppath), tmdData(tmd), readOnly(readonly), nandmount(nandmount) { ui->setupUi(this); setAttribute(Qt::WA_DeleteOnClose); @@ -455,7 +460,7 @@ void TitleImportDialog::accept() } } - if (DSi_NAND::TitleExists(titleid[1], titleid[0])) + if (nandmount.TitleExists(titleid[1], titleid[0])) { if (QMessageBox::question(this, "Import title - melonDS", diff --git a/src/frontend/qt_sdl/TitleManagerDialog.h b/src/frontend/qt_sdl/TitleManagerDialog.h index fc92fd8..5182e1d 100644 --- a/src/frontend/qt_sdl/TitleManagerDialog.h +++ b/src/frontend/qt_sdl/TitleManagerDialog.h @@ -19,6 +19,7 @@ #ifndef TITLEMANAGERDIALOG_H #define TITLEMANAGERDIALOG_H +#include <memory> #include <QDialog> #include <QMessageBox> #include <QListWidget> @@ -30,6 +31,7 @@ #include <QNetworkAccessManager> #include "DSi_TMD.h" +#include "DSi_NAND.h" namespace Ui { @@ -44,10 +46,10 @@ class TitleManagerDialog : public QDialog Q_OBJECT public: - explicit TitleManagerDialog(QWidget* parent); + explicit TitleManagerDialog(QWidget* parent, DSi_NAND::NANDImage& image); ~TitleManagerDialog(); - static bool NANDInited; + static std::unique_ptr<DSi_NAND::NANDImage> nand; static bool openNAND(); static void closeNAND(); @@ -68,7 +70,10 @@ public: return nullptr; } - currentDlg = new TitleManagerDialog(parent); + assert(nand != nullptr); + assert(*nand); + + currentDlg = new TitleManagerDialog(parent, *nand); currentDlg->open(); return currentDlg; } @@ -89,6 +94,7 @@ private slots: void onExportTitleData(); private: + DSi_NAND::NANDMount nandmount; Ui::TitleManagerDialog* ui; QString importAppPath; @@ -106,7 +112,7 @@ class TitleImportDialog : public QDialog Q_OBJECT public: - explicit TitleImportDialog(QWidget* parent, QString& apppath, const DSi_TMD::TitleMetadata* tmd, bool& readonly); + explicit TitleImportDialog(QWidget* parent, QString& apppath, const DSi_TMD::TitleMetadata* tmd, bool& readonly, DSi_NAND::NANDMount& nand); ~TitleImportDialog(); private slots: @@ -119,6 +125,7 @@ private slots: private: Ui::TitleImportDialog* ui; + DSi_NAND::NANDMount& nandmount; QButtonGroup* grpTmdSource; |