From 36c476505461227ac68a785f8d33865f2cb08465 Mon Sep 17 00:00:00 2001 From: FearlessTobi Date: Tue, 1 May 2018 19:57:01 +0200 Subject: [PATCH] citra_qt: Add a game region column --- src/citra_qt/game_list.cpp | 2 ++ src/citra_qt/game_list.h | 1 + src/citra_qt/game_list_p.h | 48 ++++++++++++++++++++++++++++++++++++++ src/core/loader/smdh.cpp | 16 +++++++++++++ src/core/loader/smdh.h | 14 +++++++++++ 5 files changed, 81 insertions(+) diff --git a/src/citra_qt/game_list.cpp b/src/citra_qt/game_list.cpp index 1bd387b75..3043db2c1 100644 --- a/src/citra_qt/game_list.cpp +++ b/src/citra_qt/game_list.cpp @@ -231,6 +231,7 @@ GameList::GameList(GMainWindow* parent) : QWidget{parent} { item_model->insertColumns(0, COLUMN_COUNT); item_model->setHeaderData(COLUMN_NAME, Qt::Horizontal, "Name"); item_model->setHeaderData(COLUMN_COMPATIBILITY, Qt::Horizontal, "Compatibility"); + item_model->setHeaderData(COLUMN_REGION, Qt::Horizontal, "Region"); item_model->setHeaderData(COLUMN_FILE_TYPE, Qt::Horizontal, "File type"); item_model->setHeaderData(COLUMN_SIZE, Qt::Horizontal, "Size"); @@ -492,6 +493,7 @@ void GameListWorker::AddFstEntriesToGameList(const std::string& dir_path, unsign emit EntryReady({ new GameListItemPath(QString::fromStdString(physical_name), smdh, program_id), new GameListItemCompat(compatibility), + new GameListItemRegion(smdh), new GameListItem( QString::fromStdString(Loader::GetFileTypeString(loader->GetFileType()))), new GameListItemSize(FileUtil::GetSize(physical_name)), diff --git a/src/citra_qt/game_list.h b/src/citra_qt/game_list.h index 376dc8474..3fabd5088 100644 --- a/src/citra_qt/game_list.h +++ b/src/citra_qt/game_list.h @@ -31,6 +31,7 @@ public: enum { COLUMN_NAME, COLUMN_COMPATIBILITY, + COLUMN_REGION, COLUMN_FILE_TYPE, COLUMN_SIZE, COLUMN_COUNT, // Number of columns diff --git a/src/citra_qt/game_list_p.h b/src/citra_qt/game_list_p.h index 208d3bd53..5e2134ae5 100644 --- a/src/citra_qt/game_list_p.h +++ b/src/citra_qt/game_list_p.h @@ -73,6 +73,38 @@ static QString GetQStringShortTitleFromSMDH(const Loader::SMDH& smdh, return QString::fromUtf16(smdh.GetShortTitle(language).data()); } +/** + * Gets the game region from SMDH data. + * @param smdh SMDH data + * @return QString region + */ +static QString GetRegionFromSMDH(const Loader::SMDH& smdh) { + const Loader::SMDH::GameRegion region = smdh.GetRegion(); + + switch (region) { + case Loader::SMDH::GameRegion::Invalid: + return QObject::tr("Invalid region"); + case Loader::SMDH::GameRegion::Japan: + return QObject::tr("Japan"); + case Loader::SMDH::GameRegion::NorthAmerica: + return QObject::tr("North America"); + case Loader::SMDH::GameRegion::Europe: + return QObject::tr("Europe"); + case Loader::SMDH::GameRegion::Australia: + return QObject::tr("Australia"); + case Loader::SMDH::GameRegion::China: + return QObject::tr("China"); + case Loader::SMDH::GameRegion::Korea: + return QObject::tr("Korea"); + case Loader::SMDH::GameRegion::Taiwan: + return QObject::tr("Taiwan"); + case Loader::SMDH::GameRegion::RegionFree: + return QObject::tr("Region free"); + default: + return QObject::tr("Invalid Region"); + } +} + struct CompatStatus { QString color; const char* text; @@ -168,6 +200,22 @@ public: } }; +class GameListItemRegion : public GameListItem { +public: + GameListItemRegion() = default; + explicit GameListItemRegion(const std::vector& smdh_data) { + if (!Loader::IsValidSMDH(smdh_data)) { + setText(QObject::tr("Invalid region")); + return; + } + + Loader::SMDH smdh; + memcpy(&smdh, smdh_data.data(), sizeof(Loader::SMDH)); + + setText(GetRegionFromSMDH(smdh)); + } +}; + /** * A specialization of GameListItem for size values. * This class ensures that for every numerical size value it holds (in bytes), a correct diff --git a/src/core/loader/smdh.cpp b/src/core/loader/smdh.cpp index f53dab770..3392739c5 100644 --- a/src/core/loader/smdh.cpp +++ b/src/core/loader/smdh.cpp @@ -48,4 +48,20 @@ std::array SMDH::GetShortTitle(Loader::SMDH::TitleLanguage language) return titles[static_cast(language)].short_title; } +SMDH::GameRegion SMDH::GetRegion() const { + if (region_lockout == 0x7fffffff) { + return GameRegion::RegionFree; + } + + constexpr u32 REGION_COUNT = 7; + u32 region = 0; + for (; region < REGION_COUNT; ++region) { + if (region_lockout & (1 << region)) { + return static_cast(region); + } + } + + return GameRegion::Invalid; +} + } // namespace Loader diff --git a/src/core/loader/smdh.h b/src/core/loader/smdh.h index 8e0b658a0..0da1cf855 100644 --- a/src/core/loader/smdh.h +++ b/src/core/loader/smdh.h @@ -62,6 +62,18 @@ struct SMDH { TraditionalChinese = 11 }; + enum class GameRegion { + Invalid = -1, + Japan = 0, + NorthAmerica = 1, + Europe = 2, + Australia = 3, + China = 4, + Korea = 5, + Taiwan = 6, + RegionFree = 7, + }; + /** * Gets game icon from SMDH * @param large If true, returns large icon (48x48), otherwise returns small icon (24x24) @@ -75,6 +87,8 @@ struct SMDH { * @return UTF-16 array of the short title */ std::array GetShortTitle(Loader::SMDH::TitleLanguage language) const; + + GameRegion GetRegion() const; }; static_assert(sizeof(SMDH) == 0x36C0, "SMDH structure size is wrong");