summaryrefslogtreecommitdiff
path: root/Source/Core
diff options
context:
space:
mode:
authorAnthony Serna <Helios747@users.noreply.github.com>2016-06-25 10:31:46 -0500
committerGitHub <noreply@github.com>2016-06-25 10:31:46 -0500
commit64cf74abb4158ffabe8b5dce3c1a4d42a82b054f (patch)
tree9ced49cda44840936e4130d2d3a762473705c244 /Source/Core
parent384637bdb82ac2ce1c87984c1b19594b7f3b2ddc (diff)
parentb5104a79f1d39d2d7d160f2bd984f604a5ae2797 (diff)
Merge pull request #3678 from rukai/dolphinQtPropertiesDialog
DQt2: properties dialog - info tab
Diffstat (limited to 'Source/Core')
-rw-r--r--Source/Core/Common/ColorUtil.cpp4
-rw-r--r--Source/Core/Common/ColorUtil.h4
-rw-r--r--Source/Core/DiscIO/Volume.h23
-rw-r--r--Source/Core/DiscIO/VolumeDirectory.cpp14
-rw-r--r--Source/Core/DiscIO/VolumeDirectory.h5
-rw-r--r--Source/Core/DiscIO/VolumeGC.cpp179
-rw-r--r--Source/Core/DiscIO/VolumeGC.h52
-rw-r--r--Source/Core/DiscIO/VolumeWad.cpp5
-rw-r--r--Source/Core/DiscIO/VolumeWad.h5
-rw-r--r--Source/Core/DiscIO/VolumeWiiCrypted.cpp2
-rw-r--r--Source/Core/DiscIO/VolumeWiiCrypted.h2
-rw-r--r--Source/Core/DolphinQt2/CMakeLists.txt3
-rw-r--r--Source/Core/DolphinQt2/Config/FilesystemWidget.cpp9
-rw-r--r--Source/Core/DolphinQt2/Config/FilesystemWidget.h19
-rw-r--r--Source/Core/DolphinQt2/Config/InfoWidget.cpp196
-rw-r--r--Source/Core/DolphinQt2/Config/InfoWidget.h44
-rw-r--r--Source/Core/DolphinQt2/Config/PropertiesDialog.cpp30
-rw-r--r--Source/Core/DolphinQt2/Config/PropertiesDialog.h16
-rw-r--r--Source/Core/DolphinQt2/DolphinQt2.vcxproj9
-rw-r--r--Source/Core/DolphinQt2/DolphinQt2.vcxproj.filters15
-rw-r--r--Source/Core/DolphinQt2/GameList/GameFile.cpp123
-rw-r--r--Source/Core/DolphinQt2/GameList/GameFile.h37
-rw-r--r--Source/Core/DolphinQt2/GameList/GameList.cpp21
-rw-r--r--Source/Core/DolphinQt2/GameList/GameList.h1
-rw-r--r--Source/Core/DolphinQt2/GameList/GameListModel.cpp8
-rw-r--r--Source/Core/DolphinQt2/GameList/GameListModel.h2
-rw-r--r--Source/Core/DolphinQt2/GameList/TableDelegate.cpp17
-rw-r--r--Source/Core/DolphinWX/ISOFile.cpp20
28 files changed, 673 insertions, 192 deletions
diff --git a/Source/Core/Common/ColorUtil.cpp b/Source/Core/Common/ColorUtil.cpp
index a4f01da453..fafdcf227f 100644
--- a/Source/Core/Common/ColorUtil.cpp
+++ b/Source/Core/Common/ColorUtil.cpp
@@ -40,7 +40,7 @@ static u32 Decode5A3(u16 val)
return (a << 24) | (r << 16) | (g << 8) | b;
}
-void decode5A3image(u32* dst, u16* src, int width, int height)
+void decode5A3image(u32* dst, const u16* src, int width, int height)
{
for (int y = 0; y < height; y += 4)
{
@@ -58,7 +58,7 @@ void decode5A3image(u32* dst, u16* src, int width, int height)
}
}
-void decodeCI8image(u32* dst, u8* src, u16* pal, int width, int height)
+void decodeCI8image(u32* dst, const u8* src, u16* pal, int width, int height)
{
for (int y = 0; y < height; y += 4)
{
diff --git a/Source/Core/Common/ColorUtil.h b/Source/Core/Common/ColorUtil.h
index bc2b100dc7..8b17919ec3 100644
--- a/Source/Core/Common/ColorUtil.h
+++ b/Source/Core/Common/ColorUtil.h
@@ -8,7 +8,7 @@
namespace ColorUtil
{
-void decode5A3image(u32* dst, u16* src, int width, int height);
-void decodeCI8image(u32* dst, u8* src, u16* pal, int width, int height);
+void decode5A3image(u32* dst, const u16* src, int width, int height);
+void decodeCI8image(u32* dst, const u8* src, u16* pal, int width, int height);
} // namespace
diff --git a/Source/Core/DiscIO/Volume.h b/Source/Core/DiscIO/Volume.h
index 190376a19d..1ea9d3650f 100644
--- a/Source/Core/DiscIO/Volume.h
+++ b/Source/Core/DiscIO/Volume.h
@@ -19,7 +19,8 @@ namespace DiscIO
class IVolume
{
public:
- // Increment CACHE_REVISION if the enums below are modified (ISOFile.cpp & GameFile.cpp)
+ // Increment CACHE_REVISION if the enums below are modified (ISOFile.cpp &
+ // GameFile.cpp)
enum EPlatform
{
GAMECUBE_DISC = 0,
@@ -85,12 +86,26 @@ public:
virtual std::string GetMakerID() const = 0;
virtual u16 GetRevision() const = 0;
virtual std::string GetInternalName() const = 0;
- virtual std::map<ELanguage, std::string> GetNames(bool prefer_long) const = 0;
+ virtual std::map<ELanguage, std::string> GetShortNames() const
+ {
+ return std::map<ELanguage, std::string>();
+ }
+ virtual std::map<ELanguage, std::string> GetLongNames() const
+ {
+ return std::map<ELanguage, std::string>();
+ }
+ virtual std::map<ELanguage, std::string> GetShortMakers() const
+ {
+ return std::map<ELanguage, std::string>();
+ }
+ virtual std::map<ELanguage, std::string> GetLongMakers() const
+ {
+ return std::map<ELanguage, std::string>();
+ }
virtual std::map<ELanguage, std::string> GetDescriptions() const
{
return std::map<ELanguage, std::string>();
}
- virtual std::string GetCompany() const { return std::string(); }
virtual std::vector<u32> GetBanner(int* width, int* height) const = 0;
virtual u64 GetFSTSize() const = 0;
virtual std::string GetApploaderDate() const = 0;
@@ -116,7 +131,7 @@ protected:
// strnlen to trim NULLs
std::string string(data, strnlen(data, sizeof(data)));
- // There don't seem to be any GC discs with the country set to Taiwan...
+ // There doesn't seem to be any GC discs with the country set to Taiwan...
// But maybe they would use Shift_JIS if they existed? Not sure
bool use_shift_jis = (COUNTRY_JAPAN == GetCountry() || COUNTRY_TAIWAN == GetCountry());
diff --git a/Source/Core/DiscIO/VolumeDirectory.cpp b/Source/Core/DiscIO/VolumeDirectory.cpp
index 8fe2e65cf0..5662fa57c2 100644
--- a/Source/Core/DiscIO/VolumeDirectory.cpp
+++ b/Source/Core/DiscIO/VolumeDirectory.cpp
@@ -63,10 +63,14 @@ bool CVolumeDirectory::Read(u64 _Offset, u64 _Length, u8* _pBuffer, bool decrypt
if (!decrypt && (_Offset + _Length >= 0x400) && m_is_wii)
{
// Fully supporting this would require re-encrypting every file that's read.
- // Only supporting the areas that IOS allows software to read could be more feasible.
- // Currently, only the header (up to 0x400) is supported, though we're cheating a bit
- // with it by reading the header inside the current partition instead. Supporting the
- // header is enough for booting games, but not for running things like the Disc Channel.
+ // Only supporting the areas that IOS allows software to read could be more
+ // feasible.
+ // Currently, only the header (up to 0x400) is supported, though we're
+ // cheating a bit
+ // with it by reading the header inside the current partition instead.
+ // Supporting the
+ // header is enough for booting games, but not for running things like the
+ // Disc Channel.
return false;
}
@@ -183,7 +187,7 @@ std::string CVolumeDirectory::GetInternalName() const
return "";
}
-std::map<IVolume::ELanguage, std::string> CVolumeDirectory::GetNames(bool prefer_long) const
+std::map<IVolume::ELanguage, std::string> CVolumeDirectory::GetLongNames() const
{
std::string name = GetInternalName();
if (name.empty())
diff --git a/Source/Core/DiscIO/VolumeDirectory.h b/Source/Core/DiscIO/VolumeDirectory.h
index 496f1119cb..2a6fb87808 100644
--- a/Source/Core/DiscIO/VolumeDirectory.h
+++ b/Source/Core/DiscIO/VolumeDirectory.h
@@ -19,7 +19,8 @@ struct FSTEntry;
}
//
-// --- this volume type is used for reading files directly from the hard drive ---
+// --- this volume type is used for reading files directly from the hard drive
+// ---
//
namespace DiscIO
@@ -43,7 +44,7 @@ public:
u16 GetRevision() const override { return 0; }
std::string GetInternalName() const override;
- std::map<IVolume::ELanguage, std::string> GetNames(bool prefer_long) const override;
+ std::map<IVolume::ELanguage, std::string> GetLongNames() const override;
std::vector<u32> GetBanner(int* width, int* height) const override;
void SetName(const std::string&);
diff --git a/Source/Core/DiscIO/VolumeGC.cpp b/Source/Core/DiscIO/VolumeGC.cpp
index 2930c6cd33..4c364b941b 100644
--- a/Source/Core/DiscIO/VolumeGC.cpp
+++ b/Source/Core/DiscIO/VolumeGC.cpp
@@ -100,48 +100,46 @@ std::string CVolumeGC::GetInternalName() const
char name[0x60];
if (m_pReader != nullptr && Read(0x20, 0x60, (u8*)name))
return DecodeString(name);
- else
- return "";
+
+ return "";
}
-std::map<IVolume::ELanguage, std::string> CVolumeGC::GetNames(bool prefer_long) const
+std::map<IVolume::ELanguage, std::string> CVolumeGC::GetShortNames() const
{
- return ReadMultiLanguageStrings(false, prefer_long);
+ LoadBannerFile();
+ return m_short_names;
}
-std::map<IVolume::ELanguage, std::string> CVolumeGC::GetDescriptions() const
+std::map<IVolume::ELanguage, std::string> CVolumeGC::GetLongNames() const
{
- return ReadMultiLanguageStrings(true);
+ LoadBannerFile();
+ return m_long_names;
}
-std::string CVolumeGC::GetCompany() const
+std::map<IVolume::ELanguage, std::string> CVolumeGC::GetShortMakers() const
{
- if (!LoadBannerFile())
- return "";
-
- std::string company = DecodeString(m_banner_file.comment[0].longMaker);
+ LoadBannerFile();
+ return m_short_makers;
+}
- if (company.empty())
- company = DecodeString(m_banner_file.comment[0].shortMaker);
+std::map<IVolume::ELanguage, std::string> CVolumeGC::GetLongMakers() const
+{
+ LoadBannerFile();
+ return m_long_makers;
+}
- return company;
+std::map<IVolume::ELanguage, std::string> CVolumeGC::GetDescriptions() const
+{
+ LoadBannerFile();
+ return m_descriptions;
}
std::vector<u32> CVolumeGC::GetBanner(int* width, int* height) const
{
- if (!LoadBannerFile())
- {
- *width = 0;
- *height = 0;
- return std::vector<u32>();
- }
-
- std::vector<u32> image_buffer(GC_BANNER_WIDTH * GC_BANNER_HEIGHT);
- ColorUtil::decode5A3image(image_buffer.data(), m_banner_file.image, GC_BANNER_WIDTH,
- GC_BANNER_HEIGHT);
- *width = GC_BANNER_WIDTH;
- *height = GC_BANNER_HEIGHT;
- return image_buffer;
+ LoadBannerFile();
+ *width = m_image_width;
+ *height = m_image_height;
+ return m_image_buffer;
}
u64 CVolumeGC::GetFSTSize() const
@@ -201,102 +199,93 @@ IVolume::EPlatform CVolumeGC::GetVolumeType() const
return GAMECUBE_DISC;
}
-// Returns true if the loaded banner file is valid,
-// regardless of whether it was loaded by the current call
-bool CVolumeGC::LoadBannerFile() const
+void CVolumeGC::LoadBannerFile() const
{
- // The methods ReadMultiLanguageStrings, GetCompany and GetBanner
- // need to access the opening.bnr file. These methods are
- // usually called one after another. The file is cached in
- // RAM to avoid reading it from the disc several times, but
- // if none of these methods are called, the file is never loaded.
-
// If opening.bnr has been loaded already, return immediately
- if (m_banner_file_type != BANNER_NOT_LOADED)
- return m_banner_file_type != BANNER_INVALID;
+ if (m_banner_loaded)
+ return;
+ GCBanner banner_file;
std::unique_ptr<IFileSystem> file_system(CreateFileSystem(this));
size_t file_size = (size_t)file_system->GetFileSize("opening.bnr");
- if (file_size == BNR1_SIZE || file_size == BNR2_SIZE)
+
+ constexpr int BNR1_MAGIC = 0x31524e42;
+ constexpr int BNR2_MAGIC = 0x32524e42;
+ if (file_size != BNR1_SIZE && file_size != BNR2_SIZE)
{
- file_system->ReadFile("opening.bnr", reinterpret_cast<u8*>(&m_banner_file), file_size);
-
- if (file_size == BNR1_SIZE && m_banner_file.id == 0x31524e42) // "BNR1"
- {
- m_banner_file_type = BANNER_BNR1;
- }
- else if (file_size == BNR2_SIZE && m_banner_file.id == 0x32524e42) // "BNR2"
- {
- m_banner_file_type = BANNER_BNR2;
- }
- else
- {
- m_banner_file_type = BANNER_INVALID;
- WARN_LOG(DISCIO, "Invalid opening.bnr. Type: %0x Size: %0zx", m_banner_file.id, file_size);
- }
+ WARN_LOG(DISCIO, "Invalid opening.bnr. Size: %0zx", file_size);
+ return;
+ }
+
+ file_system->ReadFile("opening.bnr", reinterpret_cast<u8*>(&banner_file), file_size);
+
+ bool is_bnr1;
+ if (banner_file.id == BNR1_MAGIC && file_size == BNR1_SIZE)
+ {
+ is_bnr1 = true;
+ }
+ else if (banner_file.id == BNR2_MAGIC && file_size == BNR2_SIZE)
+ {
+ is_bnr1 = false;
}
else
{
- m_banner_file_type = BANNER_INVALID;
- WARN_LOG(DISCIO, "Invalid opening.bnr. Size: %0zx", file_size);
+ WARN_LOG(DISCIO, "Invalid opening.bnr. Type: %0x Size: %0zx", banner_file.id, file_size);
+ return;
}
- return m_banner_file_type != BANNER_INVALID;
+ ExtractBannerInformation(banner_file, is_bnr1);
+ m_banner_loaded = true;
}
-std::map<IVolume::ELanguage, std::string>
-CVolumeGC::ReadMultiLanguageStrings(bool description, bool prefer_long) const
+void CVolumeGC::ExtractBannerInformation(const GCBanner& banner_file, bool is_bnr1) const
{
- std::map<ELanguage, std::string> strings;
-
- if (!LoadBannerFile())
- return strings;
-
u32 number_of_languages = 0;
ELanguage start_language = LANGUAGE_UNKNOWN;
bool is_japanese = GetCountry() == ECountry::COUNTRY_JAPAN;
- switch (m_banner_file_type)
+ if (is_bnr1) // NTSC
{
- case BANNER_BNR1: // NTSC
number_of_languages = 1;
start_language = is_japanese ? ELanguage::LANGUAGE_JAPANESE : ELanguage::LANGUAGE_ENGLISH;
- break;
-
- case BANNER_BNR2: // PAL
+ }
+ else // PAL
+ {
number_of_languages = 6;
start_language = ELanguage::LANGUAGE_ENGLISH;
- break;
-
- // Shouldn't happen
- case BANNER_INVALID:
- case BANNER_NOT_LOADED:
- break;
}
+ m_image_width = GC_BANNER_WIDTH;
+ m_image_height = GC_BANNER_HEIGHT;
+ m_image_buffer = std::vector<u32>(m_image_width * m_image_height);
+ ColorUtil::decode5A3image(m_image_buffer.data(), banner_file.image, m_image_width,
+ m_image_height);
+
for (u32 i = 0; i < number_of_languages; ++i)
{
- const GCBannerComment& comment = m_banner_file.comment[i];
- std::string string;
-
- if (description)
- {
- string = DecodeString(comment.comment);
- }
- else // Title
- {
- if (prefer_long)
- string = DecodeString(comment.longTitle);
-
- if (string.empty())
- string = DecodeString(comment.shortTitle);
- }
-
- if (!string.empty())
- strings[(ELanguage)(start_language + i)] = string;
- }
+ const GCBannerInformation& info = banner_file.information[i];
+ ELanguage language = static_cast<ELanguage>(start_language + i);
+
+ std::string description = DecodeString(info.description);
+ if (!description.empty())
+ m_descriptions[language] = description;
- return strings;
+ std::string short_name = DecodeString(info.short_name);
+ if (!short_name.empty())
+ m_short_names[language] = short_name;
+
+ std::string long_name = DecodeString(info.long_name);
+ if (!long_name.empty())
+ m_long_names[language] = long_name;
+
+ std::string short_maker = DecodeString(info.short_maker);
+ if (!short_maker.empty())
+ m_short_makers[language] = short_maker;
+
+ std::string long_maker = DecodeString(info.long_maker);
+ if (!long_maker.empty())
+ m_long_makers[language] = long_maker;
+ }
}
} // namespace
diff --git a/Source/Core/DiscIO/VolumeGC.h b/Source/Core/DiscIO/VolumeGC.h
index 0842736d08..4cef2a0e29 100644
--- a/Source/Core/DiscIO/VolumeGC.h
+++ b/Source/Core/DiscIO/VolumeGC.h
@@ -27,9 +27,11 @@ public:
std::string GetMakerID() const override;
u16 GetRevision() const override;
std::string GetInternalName() const override;
- std::map<ELanguage, std::string> GetNames(bool prefer_long) const override;
+ std::map<ELanguage, std::string> GetShortNames() const override;
+ std::map<ELanguage, std::string> GetLongNames() const override;
+ std::map<ELanguage, std::string> GetShortMakers() const override;
+ std::map<ELanguage, std::string> GetLongMakers() const override;
std::map<ELanguage, std::string> GetDescriptions() const override;
- std::string GetCompany() const override;
std::vector<u32> GetBanner(int* width, int* height) const override;
u64 GetFSTSize() const override;
std::string GetApploaderDate() const override;
@@ -42,21 +44,18 @@ public:
u64 GetRawSize() const override;
private:
- bool LoadBannerFile() const;
- std::map<ELanguage, std::string> ReadMultiLanguageStrings(bool description,
- bool prefer_long = true) const;
-
static const int GC_BANNER_WIDTH = 96;
static const int GC_BANNER_HEIGHT = 32;
- // Banner Comment
- struct GCBannerComment
+ struct GCBannerInformation
{
- char shortTitle[32]; // Short game title shown in IPL menu
- char shortMaker[32]; // Short developer, publisher names shown in IPL menu
- char longTitle[64]; // Long game title shown in IPL game start screen
- char longMaker[64]; // Long developer, publisher names shown in IPL game start screen
- char comment[128]; // Game description shown in IPL game start screen in two lines.
+ char short_name[32]; // Short game title shown in IPL menu
+ char short_maker[32]; // Short developer, publisher names shown in IPL menu
+ char long_name[64]; // Long game title shown in IPL game start screen
+ char long_maker[64]; // Long developer, publisher names shown in IPL game
+ // start screen
+ char description[128]; // Game description shown in IPL game start screen in
+ // two lines.
};
struct GCBanner
@@ -64,22 +63,27 @@ private:
u32 id; // "BNR1" for NTSC, "BNR2" for PAL
u32 padding[7];
u16 image[GC_BANNER_WIDTH * GC_BANNER_HEIGHT]; // RGB5A3 96x32 image
- GCBannerComment comment[6]; // Comments in six languages (only one for BNR1 type)
+ GCBannerInformation information[6]; // information comes in six languages
+ // (only one for BNR1 type)
};
- static const size_t BNR1_SIZE = sizeof(GCBanner) - sizeof(GCBannerComment) * 5;
+ void LoadBannerFile() const;
+ void ExtractBannerInformation(const GCBanner& banner_file, bool is_bnr1) const;
+
+ static const size_t BNR1_SIZE = sizeof(GCBanner) - sizeof(GCBannerInformation) * 5;
static const size_t BNR2_SIZE = sizeof(GCBanner);
- enum BannerFileType
- {
- BANNER_NOT_LOADED,
- BANNER_INVALID,
- BANNER_BNR1,
- BANNER_BNR2
- };
+ mutable std::map<ELanguage, std::string> m_short_names;
+
+ mutable std::map<ELanguage, std::string> m_long_names;
+ mutable std::map<ELanguage, std::string> m_short_makers;
+ mutable std::map<ELanguage, std::string> m_long_makers;
+ mutable std::map<ELanguage, std::string> m_descriptions;
- mutable BannerFileType m_banner_file_type = BANNER_NOT_LOADED;
- mutable GCBanner m_banner_file;
+ mutable bool m_banner_loaded = false;
+ mutable std::vector<u32> m_image_buffer;
+ mutable int m_image_height = 0;
+ mutable int m_image_width = 0;
std::unique_ptr<IBlobReader> m_pReader;
};
diff --git a/Source/Core/DiscIO/VolumeWad.cpp b/Source/Core/DiscIO/VolumeWad.cpp
index c86c490ed4..fe9da2db50 100644
--- a/Source/Core/DiscIO/VolumeWad.cpp
+++ b/Source/Core/DiscIO/VolumeWad.cpp
@@ -89,7 +89,8 @@ std::string CVolumeWAD::GetUniqueID() const
std::string CVolumeWAD::GetMakerID() const
{
char temp[2] = {1};
- // Some weird channels use 0x0000 in place of the MakerID, so we need a check there
+ // Some weird channels use 0x0000 in place of the MakerID, so we need a check
+ // there
if (!Read(0x198 + m_tmd_offset, 2, (u8*)temp) || temp[0] == 0 || temp[1] == 0)
return "00";
@@ -119,7 +120,7 @@ IVolume::EPlatform CVolumeWAD::GetVolumeType() const
return WII_WAD;
}
-std::map<IVolume::ELanguage, std::string> CVolumeWAD::GetNames(bool prefer_long) const
+std::map<IVolume::ELanguage, std::string> CVolumeWAD::GetLongNames() const
{
std::vector<u8> name_data(NAMES_TOTAL_BYTES);
if (!Read(m_opening_bnr_offset + 0x9C, NAMES_TOTAL_BYTES, name_data.data()))
diff --git a/Source/Core/DiscIO/VolumeWad.h b/Source/Core/DiscIO/VolumeWad.h
index 1b522a5a83..4e5c8016ee 100644
--- a/Source/Core/DiscIO/VolumeWad.h
+++ b/Source/Core/DiscIO/VolumeWad.h
@@ -14,7 +14,8 @@
#include "DiscIO/Volume.h"
// --- this volume type is used for Wad files ---
-// Some of this code might look redundant with the CNANDContentLoader class, however,
+// Some of this code might look redundant with the CNANDContentLoader class,
+// however,
// We do not do any decryption here, we do raw read, so things are -Faster-
namespace DiscIO
@@ -30,7 +31,7 @@ public:
std::string GetMakerID() const override;
u16 GetRevision() const override;
std::string GetInternalName() const override { return ""; }
- std::map<IVolume::ELanguage, std::string> GetNames(bool prefer_long) const override;
+ std::map<IVolume::ELanguage, std::string> GetLongNames() const override;
std::vector<u32> GetBanner(int* width, int* height) const override;
u64 GetFSTSize() const override { return 0; }
std::string GetApploaderDate() const override { return ""; }
diff --git a/Source/Core/DiscIO/VolumeWiiCrypted.cpp b/Source/Core/DiscIO/VolumeWiiCrypted.cpp
index fb0b14ec43..cbc56a72f4 100644
--- a/Source/Core/DiscIO/VolumeWiiCrypted.cpp
+++ b/Source/Core/DiscIO/VolumeWiiCrypted.cpp
@@ -238,7 +238,7 @@ std::string CVolumeWiiCrypted::GetInternalName() const
return "";
}
-std::map<IVolume::ELanguage, std::string> CVolumeWiiCrypted::GetNames(bool prefer_long) const
+std::map<IVolume::ELanguage, std::string> CVolumeWiiCrypted::GetLongNames() const
{
std::unique_ptr<IFileSystem> file_system(CreateFileSystem(this));
std::vector<u8> opening_bnr(NAMES_TOTAL_BYTES);
diff --git a/Source/Core/DiscIO/VolumeWiiCrypted.h b/Source/Core/DiscIO/VolumeWiiCrypted.h
index 34bc46b029..c2f089839e 100644
--- a/Source/Core/DiscIO/VolumeWiiCrypted.h
+++ b/Source/Core/DiscIO/VolumeWiiCrypted.h
@@ -31,7 +31,7 @@ public:
std::string GetMakerID() const override;
u16 GetRevision() const override;
std::string GetInternalName() const override;
- std::map<IVolume::ELanguage, std::string> GetNames(bool prefer_long) const override;
+ std::map<IVolume::ELanguage, std::string> GetLongNames() const override;
std::vector<u32> GetBanner(int* width, int* height) const override;
u64 GetFSTSize() const override;
std::string GetApploaderDate() const override;
diff --git a/Source/Core/DolphinQt2/CMakeLists.txt b/Source/Core/DolphinQt2/CMakeLists.txt
index 97e483340b..b03d17bdf1 100644
--- a/Source/Core/DolphinQt2/CMakeLists.txt
+++ b/Source/Core/DolphinQt2/CMakeLists.txt
@@ -13,7 +13,10 @@ set(SRCS
Resources.cpp
Settings.cpp
ToolBar.cpp
+ Config/FilesystemWidget.cpp
+ Config/InfoWidget.cpp
Config/PathDialog.cpp
+ Config/PropertiesDialog.cpp
Config/SettingsWindow.cpp
GameList/GameFile.cpp
GameList/GameList.cpp
diff --git a/Source/Core/DolphinQt2/Config/FilesystemWidget.cpp b/Source/Core/DolphinQt2/Config/FilesystemWidget.cpp
new file mode 100644
index 0000000000..935d0617a2
--- /dev/null
+++ b/Source/Core/DolphinQt2/Config/FilesystemWidget.cpp
@@ -0,0 +1,9 @@
+// Copyright 2016 Dolphin Emulator Project
+// Licensed under GPLv2+
+// Refer to the license.txt file included.
+
+#include "DolphinQt2/Config/FilesystemWidget.h"
+
+FilesystemWidget::FilesystemWidget(const GameFile& game) : m_game(game)
+{
+}
diff --git a/Source/Core/DolphinQt2/Config/FilesystemWidget.h b/Source/Core/DolphinQt2/Config/FilesystemWidget.h
new file mode 100644
index 0000000000..8cb58fa236
--- /dev/null
+++ b/Source/Core/DolphinQt2/Config/FilesystemWidget.h
@@ -0,0 +1,19 @@
+// Copyright 2016 Dolphin Emulator Project
+// Licensed under GPLv2+
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include <QDialog>
+
+#include "DolphinQt2/GameList/GameFile.h"
+
+class FilesystemWidget final : public QWidget
+{
+ Q_OBJECT
+public:
+ explicit FilesystemWidget(const GameFile& game);
+
+private:
+ GameFile m_game;
+};
diff --git a/Source/Core/DolphinQt2/Config/InfoWidget.cpp b/Source/Core/DolphinQt2/Config/InfoWidget.cpp
new file mode 100644
index 0000000000..0fbba477a5
--- /dev/null
+++ b/Source/Core/DolphinQt2/Config/InfoWidget.cpp
@@ -0,0 +1,196 @@
+// Copyright 2016 Dolphin Emulator Project
+// Licensed under GPLv2+
+// Refer to the license.txt file included.
+
+#include <QComboBox>
+#include <QCryptographicHash>
+#include <QFileDialog>
+#include <QFormLayout>
+#include <QGroupBox>
+#include <QLabel>
+#include <QLineEdit>
+#include <QProgressDialog>
+#include <QPushButton>
+#include <QTextEdit>
+
+#include "DolphinQt2/Config/InfoWidget.h"
+
+InfoWidget::InfoWidget(const GameFile& game) : m_game(game)
+{
+ QVBoxLayout* layout = new QVBoxLayout();
+ layout->addWidget(CreateISODetails());
+ layout->addWidget(CreateBannerDetails());
+ setLayout(layout);
+}
+
+QGroupBox* InfoWidget::CreateISODetails()
+{
+ QGroupBox* group = new QGroupBox(tr("ISO Details"));
+ QFormLayout* layout = new QFormLayout;
+
+ QLineEdit* file_path = CreateValueDisplay(m_game.GetFilePath());
+ QLineEdit* internal_name = CreateValueDisplay(m_game.GetInternalName());
+ QLineEdit* game_id = CreateValueDisplay(m_game.GetUniqueID());
+ QLineEdit* country = CreateValueDisplay(m_game.GetCountry());
+ QLineEdit* maker = CreateValueDisplay(m_game.GetMaker());
+ QLineEdit* maker_id = CreateValueDisplay(QStringLiteral("0x") + m_game.GetMakerID());
+ QLineEdit* disc_number = CreateValueDisplay(QString::number(m_game.GetDiscNumber()));
+ QLineEdit* revision = CreateValueDisplay(QString::number(m_game.GetRevision()));
+ QLineEdit* apploader_date = CreateValueDisplay(m_game.GetApploaderDate());
+ QLineEdit* iso_size = CreateValueDisplay(FormatSize(m_game.GetFileSize()));
+ QWidget* checksum = CreateChecksumComputer();
+
+ layout->addRow(tr("File Path:"), file_path);
+ layout->addRow(tr("Internal Name:"), internal_name);
+ layout->addRow(tr("Game ID:"), game_id);
+ layout->addRow(tr("Country:"), country);
+ layout->addRow(tr("Maker:"), maker);
+ layout->addRow(tr("Maker ID:"), maker_id);
+ layout->addRow(tr("Disc Number:"), disc_number);
+ layout->addRow(tr("Revision:"), revision);
+ layout->addRow(tr("Apploader Date:"), apploader_date);
+ layout->addRow(tr("ISO Size:"), iso_size);
+ layout->addRow(tr("MD5 Checksum:"), checksum);
+
+ group->setLayout(layout);
+ return group;
+}
+
+QGroupBox* InfoWidget::CreateBannerDetails()
+{
+ QGroupBox* group = new QGroupBox(tr("%1 Banner Details").arg(m_game.GetPlatform()));
+ QFormLayout* layout = new QFormLayout;
+
+ m_long_name = CreateValueDisplay();
+ m_short_name = CreateValueDisplay();
+ m_short_maker = CreateValueDisplay();
+ m_long_maker = CreateValueDisplay();
+ m_description = new QTextEdit();
+ m_description->setReadOnly(true);
+ QWidget* banner = CreateBannerGraphic();
+ CreateLanguageSelector();
+
+ layout->addRow(tr("Show Language:"), m_language_selector);
+ if (m_game.GetPlatformID() == DiscIO::IVolume::GAMECUBE_DISC)
+ {
+ layout->addRow(tr("Short Name:"), m_short_name);
+ layout->addRow(tr("Short Maker:"), m_short_maker);
+ layout->addRow(tr("Long Name:"), m_long_name);
+ layout->addRow(tr("Long Maker:"), m_long_maker);
+ layout->addRow(tr("Description:"), m_description);
+ }
+ else if (m_game.GetPlatformID() == DiscIO::IVolume::WII_DISC)
+ {
+ layout->addRow(tr("Name:"), m_long_name);
+ }
+ layout->addRow(tr("Banner:"), banner);
+
+ group->setLayout(layout);
+ return group;
+}
+
+QWidget* InfoWidget::CreateBannerGraphic()
+{
+ QWidget* widget = new QWidget();
+ QHBoxLayout* layout = new QHBoxLayout();
+
+ QLabel* banner = new QLabel();
+ banner->setPixmap(m_game.GetBanner());
+ QPushButton* save = new QPushButton(tr("Save as..."));
+ connect(save, &QPushButton::clicked, this, &InfoWidget::SaveBanner);
+
+ layout->addWidget(banner);
+ layout->addWidget(save);
+ widget->setLayout(layout);
+ return widget;
+}
+
+void InfoWidget::SaveBanner()
+{
+ QString path = QFileDialog::getSaveFileName(this, tr("Select a File"), QDir::currentPath(),
+ tr("PNG image file (*.png);; All Files (*)"));
+ m_game.GetBanner().save(path, "PNG");
+}
+
+QLineEdit* InfoWidget::CreateValueDisplay(const QString& value)
+{
+ QLineEdit* value_display = new QLineEdit(value);
+ value_display->setReadOnly(true);
+ value_display->setCursorPosition(0);
+ return value_display;
+}
+
+void InfoWidget::CreateLanguageSelector()
+{
+ m_language_selector = new QComboBox();
+ QList<DiscIO::IVolume::ELanguage> languages = m_game.GetAvailableLanguages();
+ for (int i = 0; i < languages.count(); i++)
+ {
+ DiscIO::IVolume::ELanguage language = languages.at(i);
+ m_language_selector->addItem(m_game.GetLanguage(language), language);
+ }
+ if (m_language_selector->count() == 1)
+ m_language_selector->setDisabled(true);
+ connect(m_language_selector, SIGNAL(currentIndexChanged(int)), this, SLOT(ChangeLanguage()));
+ ChangeLanguage();
+}
+
+void InfoWidget::ChangeLanguage()
+{
+ DiscIO::IVolume::ELanguage language =
+ static_cast<DiscIO::IVolume::ELanguage>(m_language_selector->currentData().toInt());
+ m_short_name->setText(m_game.GetShortName(language));
+ m_short_maker->setText(m_game.GetShortMaker(language));
+ m_long_name->setText(m_game.GetLongName(language));
+ m_long_maker->setText(m_game.GetLongMaker(language));
+ m_description->setText(m_game.GetDescription(language));
+}
+
+QWidget* InfoWidget::CreateChecksumComputer()
+{
+ QWidget* widget = new QWidget();
+ QHBoxLayout* layout = new QHBoxLayout();
+ layout->setContentsMargins(0, 0, 0, 0);
+
+ m_checksum_result = new QLineEdit();
+ QPushButton* calculate = new QPushButton(tr("Compute"));
+ connect(calculate, &QPushButton::clicked, this, &InfoWidget::ComputeChecksum);
+ layout->addWidget(m_checksum_result);
+ layout->addWidget(calculate);
+
+ widget->setLayout(layout);
+ return widget;
+}
+
+void InfoWidget::ComputeChecksum()
+{
+ QCryptographicHash hash(QCryptographicHash::Md5);
+ hash.reset();
+ std::unique_ptr<DiscIO::IBlobReader> file(
+ DiscIO::CreateBlobReader(m_game.GetFilePath().toStdString()));
+ std::vector<u8> file_data(8 * 1080 * 1080); // read 1MB at a time
+ u64 game_size = file->GetDataSize();
+ u64 read_offset = 0;
+
+ // a maximum of 1000 is used instead of game_size because otherwise 8GB games overflow the int
+ // typed maximum parameter
+ QProgressDialog* progress =
+ new QProgressDialog(tr("Computing MD5 Checksum"), tr("Cancel"), 0, 1000, this);
+ progress->setWindowTitle(tr("Computing MD5 Checksum"));
+ progress->setMinimumDuration(500);
+ progress->setWindowModality(Qt::WindowModal);
+ while (read_offset < game_size)
+ {
+ progress->setValue(static_cast<double>(read_offset) / static_cast<double>(game_size) * 1000);
+ if (progress->wasCanceled())
+ return;
+
+ u64 read_size = std::min(file_data.size(), game_size - read_offset);
+ file->Read(read_offset, read_size, file_data.data());
+ hash.addData(reinterpret_cast<char*>(file_data.data()), read_size);
+ read_offset += read_size;
+ }
+ m_checksum_result->setText(QString::fromUtf8(hash.result().toHex()));
+ Q_ASSERT(read_offset == game_size);
+ progress->setValue(1000);
+}
diff --git a/Source/Core/DolphinQt2/Config/InfoWidget.h b/Source/Core/DolphinQt2/Config/InfoWidget.h
new file mode 100644
index 0000000000..38c73b4a1c
--- /dev/null
+++ b/Source/Core/DolphinQt2/Config/InfoWidget.h
@@ -0,0 +1,44 @@
+// Copyright 2016 Dolphin Emulator Project
+// Licensed under GPLv2+
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include <QWidget>
+
+#include "DolphinQt2/GameList/GameFile.h"
+
+class QComboBox;
+class QGroupBox;
+class QTextEdit;
+class QLineEdit;
+
+class InfoWidget final : public QWidget
+{
+ Q_OBJECT
+public:
+ explicit InfoWidget(const GameFile& game);
+
+private slots:
+ void ComputeChecksum();
+ void ChangeLanguage();
+ void SaveBanner();
+
+private:
+ QGroupBox* CreateBannerDetails();
+ QGroupBox* CreateISODetails();
+ QLineEdit* CreateValueDisplay() { return CreateValueDisplay(QStringLiteral("")); };
+ QLineEdit* CreateValueDisplay(const QString& value);
+ QWidget* CreateChecksumComputer();
+ void CreateLanguageSelector();
+ QWidget* CreateBannerGraphic();
+
+ GameFile m_game;
+ QLineEdit* m_checksum_result;
+ QComboBox* m_language_selector;
+ QLineEdit* m_long_name;
+ QLineEdit* m_short_name;
+ QLineEdit* m_short_maker;
+ QLineEdit* m_long_maker;
+ QTextEdit* m_description;
+};
diff --git a/Source/Core/DolphinQt2/Config/PropertiesDialog.cpp b/Source/Core/DolphinQt2/Config/PropertiesDialog.cpp
new file mode 100644
index 0000000000..6d00e21b9b
--- /dev/null
+++ b/Source/Core/DolphinQt2/Config/PropertiesDialog.cpp
@@ -0,0 +1,30 @@
+// Copyright 2016 Dolphin Emulator Project
+// Licensed under GPLv2+
+// Refer to the license.txt file included.
+
+#include <QDialogButtonBox>
+#include <QTabWidget>
+#include <QVBoxLayout>
+
+#include "DolphinQt2/Config/FilesystemWidget.h"
+#include "DolphinQt2/Config/InfoWidget.h"
+#include "DolphinQt2/Config/PropertiesDialog.h"
+
+PropertiesDialog::PropertiesDialog(QWidget* parent, const GameFile& game) : QDialog(parent)
+{
+ setWindowTitle(QStringLiteral("%1: %2").arg(game.GetUniqueID()).arg(game.GetLongName()));
+ QVBoxLayout* layout = new QVBoxLayout();
+
+ QTabWidget* tab_widget = new QTabWidget(this);
+ InfoWidget* info = new InfoWidget(game);
+ FilesystemWidget* filesystem = new FilesystemWidget(game);
+ tab_widget->addTab(info, tr("Info"));
+ tab_widget->addTab(filesystem, tr("Filesystem"));
+ layout->addWidget(tab_widget);
+
+ QDialogButtonBox* ok_box = new QDialogButtonBox(QDialogButtonBox::Ok);
+ connect(ok_box, &QDialogButtonBox::accepted, this, &PropertiesDialog::accept);
+ layout->addWidget(ok_box);
+
+ setLayout(layout);
+}
diff --git a/Source/Core/DolphinQt2/Config/PropertiesDialog.h b/Source/Core/DolphinQt2/Config/PropertiesDialog.h
new file mode 100644
index 0000000000..f640f4e536
--- /dev/null
+++ b/Source/Core/DolphinQt2/Config/PropertiesDialog.h
@@ -0,0 +1,16 @@
+// Copyright 2016 Dolphin Emulator Project
+// Licensed under GPLv2+
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include <QDialog>
+
+#include "DolphinQt2/GameList/GameFile.h"
+
+class PropertiesDialog final : public QDialog
+{
+ Q_OBJECT
+public:
+ explicit PropertiesDialog(QWidget* parent, const GameFile& game);
+};
diff --git a/Source/Core/DolphinQt2/DolphinQt2.vcxproj b/Source/Core/DolphinQt2/DolphinQt2.vcxproj
index 0494619944..1c69275b5b 100644
--- a/Source/Core/DolphinQt2/DolphinQt2.vcxproj
+++ b/Source/Core/DolphinQt2/DolphinQt2.vcxproj
@@ -78,7 +78,10 @@
<!--NOTE: When adding moc'd files, you must list the outputs in the following ItemGroup!-->
<ItemGroup>
<QtMoc Include="AboutDialog.h" />
+ <QtMoc Include="Config\FilesystemWidget.h" />
+ <QtMoc Include="Config\InfoWidget.h" />
<QtMoc Include="Config\PathDialog.h" />
+ <QtMoc Include="Config\PropertiesDialog.h" />
<QtMoc Include="Config\SettingsWindow.h" />
<QtMoc Include="GameList\GameFile.h" />
<QtMoc Include="GameList\GameList.h" />
@@ -96,22 +99,28 @@
<!--TODO figure out how to get QtMoc to add outputs to ClCompile's inputs...-->
<ItemGroup>
<ClCompile Include="$(QtMocOutPrefix)AboutDialog.cpp" />
+ <ClCompile Include="$(QtMocOutPrefix)FilesystemWidget.cpp" />
<ClCompile Include="$(QtMocOutPrefix)GameFile.cpp" />
<ClCompile Include="$(QtMocOutPrefix)GameList.cpp" />
<ClCompile Include="$(QtMocOutPrefix)GameListModel.cpp" />
<ClCompile Include="$(QtMocOutPrefix)GameTracker.cpp" />
<ClCompile Include="$(QtMocOutPrefix)Host.cpp" />
+ <ClCompile Include="$(QtMocOutPrefix)InfoWidget.cpp" />
<ClCompile Include="$(QtMocOutPrefix)ListProxyModel.cpp" />
<ClCompile Include="$(QtMocOutPrefix)MainWindow.cpp" />
<ClCompile Include="$(QtMocOutPrefix)MenuBar.cpp" />
<ClCompile Include="$(QtMocOutPrefix)PathDialog.cpp" />
+ <ClCompile Include="$(QtMocOutPrefix)PropertiesDialog.cpp" />
<ClCompile Include="$(QtMocOutPrefix)RenderWidget.cpp" />
<ClCompile Include="$(QtMocOutPrefix)Settings.cpp" />
<ClCompile Include="$(QtMocOutPrefix)SettingsWindow.cpp" />
<ClCompile Include="$(QtMocOutPrefix)TableDelegate.cpp" />
<ClCompile Include="$(QtMocOutPrefix)ToolBar.cpp" />
<ClCompile Include="AboutDialog.cpp" />
+ <ClCompile Include="Config\FilesystemWidget.cpp" />
+ <ClCompile Include="Config\InfoWidget.cpp" />
<ClCompile Include="Config\PathDialog.cpp" />
+ <ClCompile Include="Config\PropertiesDialog.cpp" />
<ClCompile Include="Config\SettingsWindow.cpp" />
<ClCompile Include="GameList\GameFile.cpp" />
<ClCompile Include="GameList\GameList.cpp" />
diff --git a/Source/Core/DolphinQt2/DolphinQt2.vcxproj.filters b/Source/Core/DolphinQt2/DolphinQt2.vcxproj.filters
index 5d141f9f6d..77def9d722 100644
--- a/Source/Core/DolphinQt2/DolphinQt2.vcxproj.filters
+++ b/Source/Core/DolphinQt2/DolphinQt2.vcxproj.filters
@@ -75,6 +75,18 @@
<ClCompile Include="$(QtMocOutPrefix)SettingsWindow.cpp">
<Filter>Generated Files</Filter>
</ClCompile>
+ <ClCompile Include="Config\PropertiesDialog.cpp" />
+ <ClCompile Include="$(QtMocOutPrefix)InfoWidget.cpp">
+ <Filter>Generated Files</Filter>
+ </ClCompile>
+ <ClCompile Include="$(QtMocOutPrefix)PropertiesDialog.cpp">
+ <Filter>Generated Files</Filter>
+ </ClCompile>
+ <ClCompile Include="Config\FilesystemWidget.cpp" />
+ <ClCompile Include="Config\InfoWidget.cpp" />
+ <ClCompile Include="$(QtMocOutPrefix)FilesystemWidget.cpp">
+ <Filter>Generated Files</Filter>
+ </ClCompile>
</ItemGroup>
<ItemGroup>
<QtMoc Include="MainWindow.h" />
@@ -104,6 +116,9 @@
<QtMoc Include="GameList\TableDelegate.h" />
<QtMoc Include="AboutDialog.h" />
<QtMoc Include="Config\SettingsWindow.h" />
+ <QtMoc Include="Config\PropertiesDialog.h" />
+ <QtMoc Include="Config\FilesystemWidget.h" />
+ <QtMoc Include="Config\InfoWidget.h" />
</ItemGroup>
<ItemGroup>
<QtUi Include="*.ui" />
diff --git a/Source/Core/DolphinQt2/GameList/GameFile.cpp b/Source/Core/DolphinQt2/GameList/GameFile.cpp
index 8efb267e24..3f7b9c3016 100644
--- a/Source/Core/DolphinQt2/GameList/GameFile.cpp
+++ b/Source/Core/DolphinQt2/GameList/GameFile.cpp
@@ -5,8 +5,6 @@
#include <QCryptographicHash>
#include <QDataStream>
#include <QDir>
-#include <QFile>
-#include <QFileInfo>
#include <QImage>
#include <QSharedPointer>
@@ -20,6 +18,11 @@
static const int CACHE_VERSION = 13; // Last changed in PR #3261
static const int DATASTREAM_VERSION = QDataStream::Qt_5_5;
+QList<DiscIO::IVolume::ELanguage> GameFile::GetAvailableLanguages() const
+{
+ return m_long_names.keys();
+}
+
static QMap<DiscIO::IVolume::ELanguage, QString>
ConvertLanguageMap(const std::map<DiscIO::IVolume::ELanguage, std::string>& map)
{
@@ -137,22 +140,22 @@ bool GameFile::TryLoadVolume()
return false;
m_unique_id = QString::fromStdString(volume->GetUniqueID());
- m_maker_id = QString::fromStdString(volume->GetMakerID());
+ std::string maker_id = volume->GetMakerID();
+ m_maker = QString::fromStdString(DiscIO::GetCompanyFromID(maker_id));
+ m_maker_id = QString::fromStdString(maker_id);
m_revision = volume->GetRevision();
m_internal_name = QString::fromStdString(volume->GetInternalName());
- m_short_names = ConvertLanguageMap(volume->GetNames(false));
- m_long_names = ConvertLanguageMap(volume->GetNames(true));
+ m_short_names = ConvertLanguageMap(volume->GetShortNames());
+ m_long_names = ConvertLanguageMap(volume->GetLongNames());
+ m_short_makers = ConvertLanguageMap(volume->GetShortMakers());
+ m_long_makers = ConvertLanguageMap(volume->GetLongMakers());
m_descriptions = ConvertLanguageMap(volume->GetDescriptions());
- m_company = QString::fromStdString(volume->GetCompany());
m_disc_number = volume->GetDiscNumber();
m_platform = volume->GetVolumeType();
m_country = volume->GetCountry();
m_blob_type = volume->GetBlobType();
m_raw_size = volume->GetRawSize();
-
- if (m_company.isEmpty() && m_unique_id.size() >= 6)
- m_company =
- QString::fromStdString(DiscIO::GetCompanyFromID(m_unique_id.mid(4, 2).toStdString()));
+ m_apploader_date = QString::fromStdString(volume->GetApploaderDate());
ReadBanner(*volume);
@@ -176,12 +179,13 @@ bool GameFile::TryLoadElfDol()
return true;
}
+
void GameFile::SaveCache()
{
// TODO
}
-QString GameFile::GetLanguageString(const QMap<DiscIO::IVolume::ELanguage, QString>& m) const
+QString GameFile::GetBannerString(const QMap<DiscIO::IVolume::ELanguage, QString>& m) const
{
// Try the settings language, then English, then just pick one.
if (m.isEmpty())
@@ -200,3 +204,100 @@ QString GameFile::GetLanguageString(const QMap<DiscIO::IVolume::ELanguage, QStri
return m[DiscIO::IVolume::LANGUAGE_ENGLISH];
return m.first();
}
+
+QString GameFile::GetPlatform() const
+{
+ switch (m_platform)
+ {
+ case DiscIO::IVolume::GAMECUBE_DISC:
+ return QObject::tr("GameCube");
+ case DiscIO::IVolume::WII_DISC:
+ return QObject::tr("Wii");
+ case DiscIO::IVolume::WII_WAD:
+ return QObject::tr("Wii Channel");
+ case DiscIO::IVolume::ELF_DOL:
+ return QObject::tr("ELF/DOL");
+ default:
+ return QObject::tr("Unknown");
+ }
+}
+
+QString GameFile::GetCountry() const
+{
+ switch (m_country)
+ {
+ case DiscIO::IVolume::COUNTRY_EUROPE:
+ return QObject::tr("Europe");
+ case DiscIO::IVolume::COUNTRY_JAPAN:
+ return QObject::tr("Japan");
+ case DiscIO::IVolume::COUNTRY_USA:
+ return QObject::tr("USA");
+ case DiscIO::IVolume::COUNTRY_AUSTRALIA:
+ return QObject::tr("Australia");
+ case DiscIO::IVolume::COUNTRY_FRANCE:
+ return QObject::tr("France");
+ case DiscIO::IVolume::COUNTRY_GERMANY:
+ return QObject::tr("Germany");
+ case DiscIO::IVolume::COUNTRY_ITALY:
+ return QObject::tr("Italy");
+ case DiscIO::IVolume::COUNTRY_KOREA:
+ return QObject::tr("Korea");
+ case DiscIO::IVolume::COUNTRY_NETHERLANDS:
+ return QObject::tr("Netherlands");
+ case DiscIO::IVolume::COUNTRY_RUSSIA:
+ return QObject::tr("Russia");
+ case DiscIO::IVolume::COUNTRY_SPAIN:
+ return QObject::tr("Spain");
+ case DiscIO::IVolume::COUNTRY_TAIWAN:
+ return QObject::tr("Taiwan");
+ case DiscIO::IVolume::COUNTRY_WORLD:
+ return QObject::tr("World");
+ default:
+ return QObject::tr("Unknown");
+ }
+}
+
+QString GameFile::GetLanguage(DiscIO::IVolume::ELanguage lang) const
+{
+ switch (lang)
+ {
+ case DiscIO::IVolume::LANGUAGE_JAPANESE:
+ return QObject::tr("Japanese");
+ case DiscIO::IVolume::LANGUAGE_ENGLISH:
+ return QObject::tr("English");
+ case DiscIO::IVolume::LANGUAGE_GERMAN:
+ return QObject::tr("German");
+ case DiscIO::IVolume::LANGUAGE_FRENCH:
+ return QObject::tr("French");
+ case DiscIO::IVolume::LANGUAGE_SPANISH:
+ return QObject::tr("Spanish");
+ case DiscIO::IVolume::LANGUAGE_ITALIAN:
+ return QObject::tr("Italian");
+ case DiscIO::IVolume::LANGUAGE_DUTCH:
+ return QObject::tr("Dutch");
+ case DiscIO::IVolume::LANGUAGE_SIMPLIFIED_CHINESE:
+ return QObject::tr("Simplified Chinese");
+ case DiscIO::IVolume::LANGUAGE_TRADITIONAL_CHINESE:
+ return QObject::tr("Traditional Chinese");
+ case DiscIO::IVolume::LANGUAGE_KOREAN:
+ return QObject::tr("Korean");
+ default:
+ return QObject::tr("Unknown");
+ }
+}
+
+// Convert an integer size to a friendly string representation.
+QString FormatSize(qint64 size)
+{
+ QStringList units{QStringLiteral("KB"), QStringLiteral("MB"), QStringLiteral("GB"),
+ QStringLiteral("TB")};
+ QStringListIterator i(units);
+ QString unit = QStringLiteral("B");
+ double num = (double)size;
+ while (num > 1024.0 && i.hasNext())
+ {
+ unit = i.next();
+ num /= 1024.0;
+ }
+ return QStringLiteral("%1 %2").arg(QString::number(num, 'f', 1)).arg(unit);
+}
diff --git a/Source/Core/DolphinQt2/GameList/GameFile.h b/Source/Core/DolphinQt2/GameList/GameFile.h
index c1daed88db..b76ac077df 100644
--- a/Source/Core/DolphinQt2/GameList/GameFile.h
+++ b/Source/Core/DolphinQt2/GameList/GameFile.h
@@ -19,34 +19,43 @@ public:
bool IsValid() const { return m_valid; }
// These will be properly initialized before we try to load the file.
- QString GetPath() const { return m_path; }
+ QString GetFilePath() const { return m_path; }
QString GetFileName() const { return m_file_name; }
- QString GetExtension() const { return m_extension; }
- QString GetFolder() const { return m_folder; }
+ QString GetFileExtension() const { return m_extension; }
+ QString GetFileFolder() const { return m_folder; }
qint64 GetFileSize() const { return m_size; }
// The rest will not.
QString GetUniqueID() const { return m_unique_id; }
QString GetMakerID() const { return m_maker_id; }
+ QString GetMaker() const { return m_maker; }
u16 GetRevision() const { return m_revision; }
QString GetInternalName() const { return m_internal_name; }
- QString GetCompany() const { return m_company; }
u8 GetDiscNumber() const { return m_disc_number; }
u64 GetRawSize() const { return m_raw_size; }
QPixmap GetBanner() const { return m_banner; }
QString GetIssues() const { return m_issues; }
int GetRating() const { return m_rating; }
- DiscIO::IVolume::EPlatform GetPlatform() const { return m_platform; }
- DiscIO::IVolume::ECountry GetCountry() const { return m_country; }
+ QString GetApploaderDate() const { return m_apploader_date; }
+ DiscIO::IVolume::EPlatform GetPlatformID() const { return m_platform; }
+ QString GetPlatform() const;
+ DiscIO::IVolume::ECountry GetCountryID() const { return m_country; }
+ QString GetCountry() const;
DiscIO::BlobType GetBlobType() const { return m_blob_type; }
- QString GetShortName() const { return GetLanguageString(m_short_names); }
+ // Banner details
+ QString GetLanguage(DiscIO::IVolume::ELanguage lang) const;
+ QList<DiscIO::IVolume::ELanguage> GetAvailableLanguages() const;
+ QString GetShortName() const { return GetBannerString(m_short_names); }
+ QString GetShortMaker() const { return GetBannerString(m_short_makers); }
+ QString GetLongName() const { return GetBannerString(m_long_names); }
+ QString GetLongMaker() const { return GetBannerString(m_long_makers); }
+ QString GetDescription() const { return GetBannerString(m_descriptions); }
QString GetShortName(DiscIO::IVolume::ELanguage lang) const { return m_short_names[lang]; }
- QString GetLongName() const { return GetLanguageString(m_long_names); }
+ QString GetShortMaker(DiscIO::IVolume::ELanguage lang) const { return m_short_makers[lang]; }
QString GetLongName(DiscIO::IVolume::ELanguage lang) const { return m_long_names[lang]; }
- QString GetDescription() const { return GetLanguageString(m_descriptions); }
+ QString GetLongMaker(DiscIO::IVolume::ELanguage lang) const { return m_long_makers[lang]; }
QString GetDescription(DiscIO::IVolume::ELanguage lang) const { return m_descriptions[lang]; }
private:
- DiscIO::IVolume::ELanguage GetDefaultLanguage() const;
- QString GetLanguageString(const QMap<DiscIO::IVolume::ELanguage, QString>& m) const;
+ QString GetBannerString(const QMap<DiscIO::IVolume::ELanguage, QString>& m) const;
QString GetCacheFileName() const;
void ReadBanner(const DiscIO::IVolume& volume);
@@ -67,11 +76,14 @@ private:
qint64 m_size = 0;
QString m_unique_id;
+ QString m_maker;
QString m_maker_id;
u16 m_revision = 0;
QString m_internal_name;
QMap<DiscIO::IVolume::ELanguage, QString> m_short_names;
QMap<DiscIO::IVolume::ELanguage, QString> m_long_names;
+ QMap<DiscIO::IVolume::ELanguage, QString> m_short_makers;
+ QMap<DiscIO::IVolume::ELanguage, QString> m_long_makers;
QMap<DiscIO::IVolume::ELanguage, QString> m_descriptions;
QString m_company;
u8 m_disc_number = 0;
@@ -82,4 +94,7 @@ private:
QPixmap m_banner;
QString m_issues;
int m_rating = 0;
+ QString m_apploader_date;
};
+
+QString FormatSize(qint64 size);
diff --git a/Source/Core/DolphinQt2/GameList/GameList.cpp b/Source/Core/DolphinQt2/GameList/GameList.cpp
index 8c407b846c..5559187c2e 100644
--- a/Source/Core/DolphinQt2/GameList/GameList.cpp
+++ b/Source/Core/DolphinQt2/GameList/GameList.cpp
@@ -8,6 +8,7 @@
#include <QMenu>
#include <QUrl>
+#include "DolphinQt2/Config/PropertiesDialog.h"
#include "DolphinQt2/GameList/GameList.h"
#include "DolphinQt2/GameList/ListProxyModel.h"
#include "DolphinQt2/GameList/TableDelegate.h"
@@ -103,12 +104,26 @@ void GameList::MakeListView()
void GameList::ShowContextMenu(const QPoint&)
{
QMenu* menu = new QMenu(this);
- menu->addAction(tr("Properties"));
- menu->addAction(tr("Open Wiki Page"), this, SLOT(OpenWiki()));
- menu->addAction(tr("Set as Default ISO"), this, SLOT(SetDefaultISO()));
+ DiscIO::IVolume::EPlatform platform = GameFile(GetSelectedGame()).GetPlatformID();
+ if (platform == DiscIO::IVolume::GAMECUBE_DISC || platform == DiscIO::IVolume::WII_DISC)
+ {
+ menu->addAction(tr("Properties"), this, SLOT(OpenProperties()));
+ menu->addAction(tr("Open Wiki Page"), this, SLOT(OpenWiki()));
+ menu->addAction(tr("Set as Default ISO"), this, SLOT(SetDefaultISO()));
+ }
+ else
+ {
+ return;
+ }
menu->exec(QCursor::pos());
}
+void GameList::OpenProperties()
+{
+ PropertiesDialog* properties = new PropertiesDialog(this, GameFile(GetSelectedGame()));
+ properties->show();
+}
+
void GameList::OpenWiki()
{
QString game_id = GameFile(GetSelectedGame()).GetUniqueID();
diff --git a/Source/Core/DolphinQt2/GameList/GameList.h b/Source/Core/DolphinQt2/GameList/GameList.h
index 2ba457b950..45f8b2d979 100644
--- a/Source/Core/DolphinQt2/GameList/GameList.h
+++ b/Source/Core/DolphinQt2/GameList/GameList.h
@@ -29,6 +29,7 @@ public slots:
void SetViewColumn(int col, bool view) { m_table->setColumnHidden(col, !view); }
private slots:
void ShowContextMenu(const QPoint&);
+ void OpenProperties();
void OpenWiki();
void SetDefaultISO();
diff --git a/Source/Core/DolphinQt2/GameList/GameListModel.cpp b/Source/Core/DolphinQt2/GameList/GameListModel.cpp
index dac4881432..5d28daf350 100644
--- a/Source/Core/DolphinQt2/GameList/GameListModel.cpp
+++ b/Source/Core/DolphinQt2/GameList/GameListModel.cpp
@@ -34,11 +34,11 @@ QVariant GameListModel::data(const QModelIndex& index, int role) const
case COL_DESCRIPTION:
return game->GetDescription();
case COL_MAKER:
- return game->GetCompany();
+ return game->GetMaker();
case COL_SIZE:
return game->GetFileSize();
case COL_COUNTRY:
- return game->GetCountry();
+ return game->GetCountryID();
case COL_RATING:
return game->GetRating();
}
@@ -85,7 +85,7 @@ int GameListModel::columnCount(const QModelIndex& parent) const
void GameListModel::UpdateGame(QSharedPointer<GameFile> game)
{
- QString path = game->GetPath();
+ QString path = game->GetFilePath();
int entry = FindGame(path);
if (entry < 0)
@@ -111,7 +111,7 @@ int GameListModel::FindGame(const QString& path) const
{
for (int i = 0; i < m_games.size(); i++)
{
- if (m_games[i]->GetPath() == path)
+ if (m_games[i]->GetFilePath() == path)
return i;
}
return -1;
diff --git a/Source/Core/DolphinQt2/GameList/GameListModel.h b/Source/Core/DolphinQt2/GameList/GameListModel.h
index 4637d7e0f2..7e9474672d 100644
--- a/Source/Core/DolphinQt2/GameList/GameListModel.h
+++ b/Source/Core/DolphinQt2/GameList/GameListModel.h
@@ -25,7 +25,7 @@ public:
int columnCount(const QModelIndex& parent) const override;
// Path of the Game at the specified index.
- QString GetPath(int index) const { return m_games[index]->GetPath(); }
+ QString GetPath(int index) const { return m_games[index]->GetFilePath(); }
enum
{
COL_PLATFORM = 0,
diff --git a/Source/Core/DolphinQt2/GameList/TableDelegate.cpp b/Source/Core/DolphinQt2/GameList/TableDelegate.cpp
index c6df5bfc72..f0f2fcaadf 100644
--- a/Source/Core/DolphinQt2/GameList/TableDelegate.cpp
+++ b/Source/Core/DolphinQt2/GameList/TableDelegate.cpp
@@ -4,28 +4,13 @@
#include <QPainter>
+#include "DolphinQt2/GameList/GameFile.h"
#include "DolphinQt2/GameList/GameListModel.h"
#include "DolphinQt2/GameList/TableDelegate.h"
#include "DolphinQt2/Resources.h"
static QSize NORMAL_BANNER_SIZE(96, 32);
-// Convert an integer size to a friendly string representation.
-static QString FormatSize(qint64 size)
-{
- QStringList units{QStringLiteral("KB"), QStringLiteral("MB"), QStringLiteral("GB"),
- QStringLiteral("TB")};
- QStringListIterator i(units);
- QString unit = QStringLiteral("B");
- double num = (double)size;
- while (num > 1024.0 && i.hasNext())
- {
- unit = i.next();
- num /= 1024.0;
- }
- return QStringLiteral("%1 %2").arg(QString::number(num, 'f', 1)).arg(unit);
-}
-
TableDelegate::TableDelegate(QWidget* parent) : QStyledItemDelegate(parent)
{
}
diff --git a/Source/Core/DolphinWX/ISOFile.cpp b/Source/Core/DolphinWX/ISOFile.cpp
index e61fb9875f..95b9a02e2a 100644
--- a/Source/Core/DolphinWX/ISOFile.cpp
+++ b/Source/Core/DolphinWX/ISOFile.cpp
@@ -47,7 +47,8 @@ static std::string GetLanguageString(DiscIO::IVolume::ELanguage language,
if (it != end)
return it->second;
- // English tends to be a good fallback when the requested language isn't available
+ // English tends to be a good fallback when the requested language isn't
+ // available
if (language != DiscIO::IVolume::ELanguage::LANGUAGE_ENGLISH)
{
it = strings.find(DiscIO::IVolume::ELanguage::LANGUAGE_ENGLISH);
@@ -92,9 +93,13 @@ GameListItem::GameListItem(const std::string& _rFileName,
{
m_Platform = volume->GetVolumeType();
- m_names = volume->GetNames(true);
m_descriptions = volume->GetDescriptions();
- m_company = volume->GetCompany();
+ m_names = volume->GetLongNames();
+ if (m_names.empty())
+ m_names = volume->GetShortNames();
+ m_company = GetLanguageString(DiscIO::IVolume::LANGUAGE_ENGLISH, volume->GetLongMakers());
+ if (m_company.empty())
+ m_company = GetLanguageString(DiscIO::IVolume::LANGUAGE_ENGLISH, volume->GetShortMakers());
m_Country = volume->GetCountry();
m_blob_type = volume->GetBlobType();
@@ -145,13 +150,16 @@ GameListItem::GameListItem(const std::string& _rFileName,
std::string path, name;
SplitPath(m_FileName, &path, &name, nullptr);
- // A bit like the Homebrew Channel icon, except there can be multiple files in a folder with their
+ // A bit like the Homebrew Channel icon, except there can be multiple files in
+ // a folder with their
// own icons.
- // Useful for those who don't want to have a Homebrew Channel-style folder structure.
+ // Useful for those who don't want to have a Homebrew Channel-style folder
+ // structure.
if (ReadPNGBanner(path + name + ".png"))
return;
- // Homebrew Channel icon. Typical for DOLs and ELFs, but can be also used with volumes.
+ // Homebrew Channel icon. Typical for DOLs and ELFs, but can be also used with
+ // volumes.
if (ReadPNGBanner(path + "icon.png"))
return;