diff --git a/src/duckstation-qt/gamepropertiesdialog.cpp b/src/duckstation-qt/gamepropertiesdialog.cpp index 781507532..05bcfd92e 100644 --- a/src/duckstation-qt/gamepropertiesdialog.cpp +++ b/src/duckstation-qt/gamepropertiesdialog.cpp @@ -1,8 +1,10 @@ #include "gamepropertiesdialog.h" #include "common/cd_image.h" +#include "common/cd_image_hasher.h" #include "core/game_list.h" #include "core/settings.h" #include "qthostinterface.h" +#include "qtprogresscallback.h" #include "qtutils.h" #include "scmversion/scmversion.h" #include @@ -71,7 +73,7 @@ void GamePropertiesDialog::populate(const GameListEntry* ge) populateCompatibilityInfo(ge->code); } - populateTracksInfo(ge->path.c_str()); + populateTracksInfo(ge->path); } void GamePropertiesDialog::populateCompatibilityInfo(const std::string& game_code) @@ -125,14 +127,15 @@ static QString MSFTotString(const CDImage::Position& position) .arg(static_cast(position.ToLBA())); } -void GamePropertiesDialog::populateTracksInfo(const char* image_path) +void GamePropertiesDialog::populateTracksInfo(const std::string& image_path) { static constexpr std::array track_mode_strings = { {"Audio", "Mode 1", "Mode 1/Raw", "Mode 2", "Mode 2/Form 1", "Mode 2/Form 2", "Mode 2/Mix", "Mode 2/Raw"}}; m_ui.tracks->clearContents(); + m_image_path = image_path; - std::unique_ptr image = CDImage::Open(image_path); + std::unique_ptr image = CDImage::Open(image_path.c_str()); if (!image) return; @@ -230,7 +233,10 @@ void GamePropertiesDialog::onSetVersionTestedToCurrentClicked() void GamePropertiesDialog::onComputeHashClicked() { - QMessageBox::critical(this, tr("Not yet implemented"), tr("Not yet implemented")); + if (m_tracks_hashed) + return; + + computeTrackHashes(); } void GamePropertiesDialog::onVerifyDumpClicked() @@ -254,3 +260,36 @@ void GamePropertiesDialog::onExportCompatibilityInfoClicked() if (copy_to_clipboard) QGuiApplication::clipboard()->setText(xml); } + +void GamePropertiesDialog::computeTrackHashes() +{ + if (m_image_path.empty()) + return; + + std::unique_ptr image = CDImage::Open(m_image_path.c_str()); + if (!image) + return; + + QtProgressCallback progress_callback(this); + progress_callback.SetProgressRange(image->GetTrackCount()); + + for (u8 track = 1; track <= image->GetTrackCount(); track++) + { + progress_callback.SetProgressValue(track - 1); + progress_callback.PushState(); + + CDImageHasher::Hash hash; + if (!CDImageHasher::GetTrackHash(image.get(), track, &hash, &progress_callback)) + { + progress_callback.PopState(); + break; + } + + QString hash_string(QString::fromStdString(CDImageHasher::HashToString(hash))); + + QTableWidgetItem* item = m_ui.tracks->item(track - 1, 4); + item->setText(hash_string); + + progress_callback.PopState(); + } +} diff --git a/src/duckstation-qt/gamepropertiesdialog.h b/src/duckstation-qt/gamepropertiesdialog.h index 7ec6f2151..724fd785f 100644 --- a/src/duckstation-qt/gamepropertiesdialog.h +++ b/src/duckstation-qt/gamepropertiesdialog.h @@ -1,6 +1,5 @@ #pragma once #include "ui_gamepropertiesdialog.h" -#include #include struct GameListEntry; @@ -40,13 +39,17 @@ private: void setupAdditionalUi(); void connectUi(); void populateCompatibilityInfo(const std::string& game_code); - void populateTracksInfo(const char* image_path); + void populateTracksInfo(const std::string& image_path); void fillEntryFromUi(GameListCompatibilityEntry* entry); + void computeTrackHashes(); void onResize(); Ui::GamePropertiesDialog m_ui; QtHostInterface* m_host_interface; + std::string m_image_path; + bool m_compatibility_info_changed = false; + bool m_tracks_hashed = false; }; diff --git a/src/duckstation-qt/qtprogresscallback.cpp b/src/duckstation-qt/qtprogresscallback.cpp index b4c1597b2..a184275eb 100644 --- a/src/duckstation-qt/qtprogresscallback.cpp +++ b/src/duckstation-qt/qtprogresscallback.cpp @@ -22,6 +22,9 @@ bool QtProgressCallback::IsCancelled() const void QtProgressCallback::SetCancellable(bool cancellable) { + if (m_cancellable == cancellable) + return; + BaseProgressCallback::SetCancellable(cancellable); m_dialog.setCancelButtonText(cancellable ? tr("Cancel") : QString()); } @@ -35,17 +38,17 @@ void QtProgressCallback::SetStatusText(const char* text) void QtProgressCallback::SetProgressRange(u32 range) { BaseProgressCallback::SetProgressRange(range); - m_dialog.setRange(0, static_cast(range)); + m_dialog.setRange(0, m_progress_range); } void QtProgressCallback::SetProgressValue(u32 value) { BaseProgressCallback::SetProgressValue(value); - if (m_dialog.value() == static_cast(value)) + if (m_dialog.value() == m_progress_range) return; - m_dialog.setValue(value); + m_dialog.setValue(m_progress_value); QCoreApplication::processEvents(); }