summaryrefslogtreecommitdiff
path: root/Source
diff options
context:
space:
mode:
authorJosJuice <josjuice@gmail.com>2020-06-21 20:41:50 +0200
committerJosJuice <josjuice@gmail.com>2020-06-21 20:47:23 +0200
commitd494e0230c2ebfd580bb66b2a741d19ef830d658 (patch)
treeedd701dfdd98be00f0971dc747eea0dcbe5f7c71 /Source
parent99822518994d62def4e336f6746d6a2e2d108fb2 (diff)
Show file format details in game properties
Diffstat (limited to 'Source')
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/NativeLibrary.java2
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/dialogs/GameDetailsDialog.java48
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/model/GameFile.java10
-rw-r--r--Source/Android/app/src/main/res/layout/dialog_game_details.xml82
-rw-r--r--Source/Android/app/src/main/res/values/strings.xml5
-rw-r--r--Source/Android/jni/GameList/GameFile.cpp41
-rw-r--r--Source/Android/jni/MainAndroid.cpp8
-rw-r--r--Source/Core/DiscIO/Blob.cpp30
-rw-r--r--Source/Core/DiscIO/Blob.h3
-rw-r--r--Source/Core/DiscIO/CISOBlob.h1
-rw-r--r--Source/Core/DiscIO/CompressedBlob.h1
-rw-r--r--Source/Core/DiscIO/DirectoryBlob.h1
-rw-r--r--Source/Core/DiscIO/DriveBlob.h1
-rw-r--r--Source/Core/DiscIO/FileBlob.h1
-rw-r--r--Source/Core/DiscIO/ScrubbedBlob.h4
-rw-r--r--Source/Core/DiscIO/TGCBlob.h1
-rw-r--r--Source/Core/DiscIO/VolumeFileBlobReader.cpp5
-rw-r--r--Source/Core/DiscIO/VolumeFileBlobReader.h1
-rw-r--r--Source/Core/DiscIO/WIABlob.cpp20
-rw-r--r--Source/Core/DiscIO/WIABlob.h1
-rw-r--r--Source/Core/DiscIO/WbfsBlob.h1
-rw-r--r--Source/Core/DolphinQt/Config/InfoWidget.cpp53
-rw-r--r--Source/Core/DolphinQt/Config/InfoWidget.h3
-rw-r--r--Source/Core/UICommon/GameFile.cpp27
-rw-r--r--Source/Core/UICommon/GameFile.h5
-rw-r--r--Source/Core/UICommon/GameFileCache.cpp2
26 files changed, 341 insertions, 16 deletions
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/NativeLibrary.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/NativeLibrary.java
index f37169ddee..3751385be8 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/NativeLibrary.java
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/NativeLibrary.java
@@ -449,6 +449,8 @@ public final class NativeLibrary
public static native boolean InstallWAD(String file);
+ public static native String FormatSize(long bytes, int decimals);
+
private static boolean alertResult = false;
public static boolean displayAlertMsg(final String caption, final String text,
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/dialogs/GameDetailsDialog.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/dialogs/GameDetailsDialog.java
index 88120e3c42..a0597390e5 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/dialogs/GameDetailsDialog.java
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/dialogs/GameDetailsDialog.java
@@ -10,6 +10,7 @@ import android.widget.TextView;
import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.DialogFragment;
+import org.dolphinemu.dolphinemu.NativeLibrary;
import org.dolphinemu.dolphinemu.R;
import org.dolphinemu.dolphinemu.model.GameFile;
import org.dolphinemu.dolphinemu.services.GameFileCacheService;
@@ -50,8 +51,17 @@ public final class GameDetailsDialog extends DialogFragment
TextView textGameId = contents.findViewById(R.id.text_game_id);
TextView textRevision = contents.findViewById(R.id.text_revision);
+ TextView textFileFormat = contents.findViewById(R.id.text_file_format);
+ TextView textCompression = contents.findViewById(R.id.text_compression);
+ TextView textBlockSize = contents.findViewById(R.id.text_block_size);
+
+ TextView labelFileFormat = contents.findViewById(R.id.label_file_format);
+ TextView labelCompression = contents.findViewById(R.id.label_compression);
+ TextView labelBlockSize = contents.findViewById(R.id.label_block_size);
+
String country = getResources().getStringArray(R.array.countryNames)[gameFile.getCountry()];
String description = gameFile.getDescription();
+ String fileSize = NativeLibrary.FormatSize(gameFile.getFileSize(), 2);
textTitle.setText(gameFile.getTitle());
textDescription.setText(gameFile.getDescription());
@@ -59,11 +69,49 @@ public final class GameDetailsDialog extends DialogFragment
{
textDescription.setVisibility(View.GONE);
}
+
textCountry.setText(country);
textCompany.setText(gameFile.getCompany());
textGameId.setText(gameFile.getGameId());
textRevision.setText(Integer.toString(gameFile.getRevision()));
+ if (!gameFile.shouldShowFileFormatDetails())
+ {
+ labelFileFormat.setText(R.string.game_details_file_size);
+ textFileFormat.setText(fileSize);
+
+ labelCompression.setVisibility(View.GONE);
+ textCompression.setVisibility(View.GONE);
+ labelBlockSize.setVisibility(View.GONE);
+ textBlockSize.setVisibility(View.GONE);
+ }
+ else
+ {
+ long blockSize = gameFile.getBlockSize();
+ String compression = gameFile.getCompressionMethod();
+
+ textFileFormat.setText(String.format("%1$s (%2$s)", gameFile.getBlobTypeString(), fileSize));
+
+ if (compression.isEmpty())
+ {
+ textCompression.setText(R.string.game_details_no_compression);
+ }
+ else
+ {
+ textCompression.setText(gameFile.getCompressionMethod());
+ }
+
+ if (blockSize > 0)
+ {
+ textBlockSize.setText(NativeLibrary.FormatSize(blockSize, 0));
+ }
+ else
+ {
+ labelBlockSize.setVisibility(View.GONE);
+ textBlockSize.setVisibility(View.GONE);
+ }
+ }
+
PicassoUtils.loadGameBanner(banner, gameFile);
builder.setView(contents);
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/model/GameFile.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/model/GameFile.java
index dea006f24e..666103cf05 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/model/GameFile.java
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/model/GameFile.java
@@ -38,6 +38,16 @@ public class GameFile
public native int getRevision();
+ public native String getBlobTypeString();
+
+ public native long getBlockSize();
+
+ public native String getCompressionMethod();
+
+ public native boolean shouldShowFileFormatDetails();
+
+ public native long getFileSize();
+
public native int[] getBanner();
public native int getBannerWidth();
diff --git a/Source/Android/app/src/main/res/layout/dialog_game_details.xml b/Source/Android/app/src/main/res/layout/dialog_game_details.xml
index fc6b360320..58816600bf 100644
--- a/Source/Android/app/src/main/res/layout/dialog_game_details.xml
+++ b/Source/Android/app/src/main/res/layout/dialog_game_details.xml
@@ -42,7 +42,7 @@
app:layout_constraintTop_toBottomOf="@id/text_description" />
<View
- android:id="@+id/divider"
+ android:id="@+id/divider_1"
android:layout_width="0dp"
android:layout_height="1dp"
android:background="#1F000000"
@@ -59,7 +59,7 @@
android:gravity="start"
android:text="@string/game_details_country"
app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintTop_toBottomOf="@id/divider" />
+ app:layout_constraintTop_toBottomOf="@id/divider_1" />
<TextView
android:id="@+id/label_company"
@@ -89,15 +89,14 @@
android:gravity="start"
android:text="@string/game_details_revision"
app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintTop_toBottomOf="@id/label_game_id"
- app:layout_constraintBottom_toBottomOf="parent" />
+ app:layout_constraintTop_toBottomOf="@id/label_game_id" />
<androidx.constraintlayout.widget.Barrier
android:id="@+id/label_barrier"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:barrierDirection="end"
- app:constraint_referenced_ids="label_country,label_company,label_game_id,label_revision" />
+ app:constraint_referenced_ids="label_country,label_company,label_game_id,label_revision,label_file_format,label_compression,label_block_size" />
<TextView
android:id="@+id/text_country"
@@ -143,4 +142,77 @@
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBaseline_toBaselineOf="@id/label_revision" />
+ <View
+ android:id="@+id/divider_2"
+ android:layout_width="0dp"
+ android:layout_height="1dp"
+ android:background="#1F000000"
+ android:layout_marginTop="32dp"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintTop_toBottomOf="@id/label_revision" />
+
+ <TextView
+ android:id="@+id/label_file_format"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="24dp"
+ android:gravity="start"
+ android:text="@string/game_details_file_format"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintTop_toBottomOf="@id/divider_2" />
+
+ <TextView
+ android:id="@+id/label_compression"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="24dp"
+ android:gravity="start"
+ android:text="@string/game_details_compression"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintTop_toBottomOf="@id/label_file_format" />
+
+ <TextView
+ android:id="@+id/label_block_size"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="24dp"
+ android:gravity="start"
+ android:text="@string/game_details_block_size"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintTop_toBottomOf="@id/label_compression" />
+
+ <TextView
+ android:id="@+id/text_file_format"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_marginStart="16dp"
+ android:gravity="end"
+ tools:text="ISO (4.38 GiB)"
+ app:layout_constraintStart_toEndOf="@id/label_barrier"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintBaseline_toBaselineOf="@id/label_file_format" />
+
+ <TextView
+ android:id="@+id/text_compression"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_marginStart="16dp"
+ android:gravity="end"
+ tools:text="No Compression"
+ app:layout_constraintStart_toEndOf="@id/label_barrier"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintBaseline_toBaselineOf="@id/label_compression" />
+
+ <TextView
+ android:id="@+id/text_block_size"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_marginStart="16dp"
+ android:gravity="end"
+ tools:text="0 B"
+ app:layout_constraintStart_toEndOf="@id/label_barrier"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintBaseline_toBaselineOf="@id/label_block_size" />
+
</androidx.constraintlayout.widget.ConstraintLayout>
diff --git a/Source/Android/app/src/main/res/values/strings.xml b/Source/Android/app/src/main/res/values/strings.xml
index 94590230f6..dfc69dfaf1 100644
--- a/Source/Android/app/src/main/res/values/strings.xml
+++ b/Source/Android/app/src/main/res/values/strings.xml
@@ -317,6 +317,11 @@
<string name="game_details_company">Company</string>
<string name="game_details_game_id">Game ID</string>
<string name="game_details_revision">Revision</string>
+ <string name="game_details_file_size">File Size</string>
+ <string name="game_details_file_format">File Format</string>
+ <string name="game_details_compression">Compression</string>
+ <string name="game_details_block_size">Block Size</string>
+ <string name="game_details_no_compression">No Compression</string>
<!-- Emulation Menu -->
<string name="emulation_screenshot">Take Screenshot</string>
diff --git a/Source/Android/jni/GameList/GameFile.cpp b/Source/Android/jni/GameList/GameFile.cpp
index efad21681f..f1af2584c3 100644
--- a/Source/Android/jni/GameList/GameFile.cpp
+++ b/Source/Android/jni/GameList/GameFile.cpp
@@ -10,6 +10,7 @@
#include <jni.h>
+#include "DiscIO/Blob.h"
#include "DiscIO/Enums.h"
#include "UICommon/GameFile.h"
#include "jni/AndroidCommon/AndroidCommon.h"
@@ -62,6 +63,16 @@ JNIEXPORT jint JNICALL Java_org_dolphinemu_dolphinemu_model_GameFile_getDiscNumb
jobject obj);
JNIEXPORT jint JNICALL Java_org_dolphinemu_dolphinemu_model_GameFile_getRevision(JNIEnv* env,
jobject obj);
+JNIEXPORT jstring JNICALL
+Java_org_dolphinemu_dolphinemu_model_GameFile_getBlobTypeString(JNIEnv* env, jobject obj);
+JNIEXPORT jlong JNICALL Java_org_dolphinemu_dolphinemu_model_GameFile_getBlockSize(JNIEnv* env,
+ jobject obj);
+JNIEXPORT jstring JNICALL
+Java_org_dolphinemu_dolphinemu_model_GameFile_getCompressionMethod(JNIEnv* env, jobject obj);
+JNIEXPORT jboolean JNICALL
+Java_org_dolphinemu_dolphinemu_model_GameFile_shouldShowFileFormatDetails(JNIEnv* env, jobject obj);
+JNIEXPORT jlong JNICALL Java_org_dolphinemu_dolphinemu_model_GameFile_getFileSize(JNIEnv* env,
+ jobject obj);
JNIEXPORT jintArray JNICALL Java_org_dolphinemu_dolphinemu_model_GameFile_getBanner(JNIEnv* env,
jobject obj);
JNIEXPORT jint JNICALL Java_org_dolphinemu_dolphinemu_model_GameFile_getBannerWidth(JNIEnv* env,
@@ -143,6 +154,36 @@ JNIEXPORT jint JNICALL Java_org_dolphinemu_dolphinemu_model_GameFile_getRevision
return GetRef(env, obj)->GetRevision();
}
+JNIEXPORT jstring JNICALL
+Java_org_dolphinemu_dolphinemu_model_GameFile_getBlobTypeString(JNIEnv* env, jobject obj)
+{
+ return ToJString(env, DiscIO::GetName(GetRef(env, obj)->GetBlobType(), true));
+}
+
+JNIEXPORT jlong JNICALL Java_org_dolphinemu_dolphinemu_model_GameFile_getBlockSize(JNIEnv* env,
+ jobject obj)
+{
+ return GetRef(env, obj)->GetBlockSize();
+}
+
+JNIEXPORT jstring JNICALL
+Java_org_dolphinemu_dolphinemu_model_GameFile_getCompressionMethod(JNIEnv* env, jobject obj)
+{
+ return ToJString(env, GetRef(env, obj)->GetCompressionMethod());
+}
+
+JNIEXPORT jboolean JNICALL
+Java_org_dolphinemu_dolphinemu_model_GameFile_shouldShowFileFormatDetails(JNIEnv* env, jobject obj)
+{
+ return GetRef(env, obj)->ShouldShowFileFormatDetails();
+}
+
+JNIEXPORT jlong JNICALL Java_org_dolphinemu_dolphinemu_model_GameFile_getFileSize(JNIEnv* env,
+ jobject obj)
+{
+ return GetRef(env, obj)->GetFileSize();
+}
+
JNIEXPORT jintArray JNICALL Java_org_dolphinemu_dolphinemu_model_GameFile_getBanner(JNIEnv* env,
jobject obj)
{
diff --git a/Source/Android/jni/MainAndroid.cpp b/Source/Android/jni/MainAndroid.cpp
index adcba61345..469d719869 100644
--- a/Source/Android/jni/MainAndroid.cpp
+++ b/Source/Android/jni/MainAndroid.cpp
@@ -742,6 +742,14 @@ JNIEXPORT jboolean JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_InstallW
return static_cast<jboolean>(WiiUtils::InstallWAD(path));
}
+JNIEXPORT jstring JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_FormatSize(JNIEnv* env,
+ jobject obj,
+ jlong bytes,
+ jint decimals)
+{
+ return ToJString(env, UICommon::FormatSize(bytes, decimals));
+}
+
#ifdef __cplusplus
}
#endif
diff --git a/Source/Core/DiscIO/Blob.cpp b/Source/Core/DiscIO/Blob.cpp
index 50146c9c91..e24c52f181 100644
--- a/Source/Core/DiscIO/Blob.cpp
+++ b/Source/Core/DiscIO/Blob.cpp
@@ -12,6 +12,7 @@
#include "Common/CDUtils.h"
#include "Common/CommonTypes.h"
#include "Common/File.h"
+#include "Common/MsgHandler.h"
#include "DiscIO/Blob.h"
#include "DiscIO/CISOBlob.h"
@@ -25,6 +26,35 @@
namespace DiscIO
{
+std::string GetName(BlobType blob_type, bool translate)
+{
+ const auto translate_str = [translate](const std::string& str) {
+ return translate ? Common::GetStringT(str.c_str()) : str;
+ };
+
+ switch (blob_type)
+ {
+ case BlobType::PLAIN:
+ return "ISO";
+ case BlobType::DIRECTORY:
+ return translate_str("Directory");
+ case BlobType::GCZ:
+ return "GCZ";
+ case BlobType::CISO:
+ return "CISO";
+ case BlobType::WBFS:
+ return "WBFS";
+ case BlobType::TGC:
+ return "TGC";
+ case BlobType::WIA:
+ return "WIA";
+ case BlobType::RVZ:
+ return "RVZ";
+ default:
+ return "";
+ }
+}
+
void SectorReader::SetSectorSize(int blocksize)
{
m_block_size = std::max(blocksize, 0);
diff --git a/Source/Core/DiscIO/Blob.h b/Source/Core/DiscIO/Blob.h
index e2a1c3c9e9..aa5274618a 100644
--- a/Source/Core/DiscIO/Blob.h
+++ b/Source/Core/DiscIO/Blob.h
@@ -41,6 +41,8 @@ enum class BlobType
RVZ,
};
+std::string GetName(BlobType blob_type, bool translate);
+
class BlobReader
{
public:
@@ -55,6 +57,7 @@ public:
// Returns 0 if the format does not use blocks
virtual u64 GetBlockSize() const = 0;
virtual bool HasFastRandomAccessInBlock() const = 0;
+ virtual std::string GetCompressionMethod() const = 0;
// NOT thread-safe - can't call this from multiple threads.
virtual bool Read(u64 offset, u64 size, u8* out_ptr) = 0;
diff --git a/Source/Core/DiscIO/CISOBlob.h b/Source/Core/DiscIO/CISOBlob.h
index 40d44aaa9d..97ef23ab5e 100644
--- a/Source/Core/DiscIO/CISOBlob.h
+++ b/Source/Core/DiscIO/CISOBlob.h
@@ -46,6 +46,7 @@ public:
u64 GetBlockSize() const override { return m_block_size; }
bool HasFastRandomAccessInBlock() const override { return true; }
+ std::string GetCompressionMethod() const override { return {}; }
bool Read(u64 offset, u64 nbytes, u8* out_ptr) override;
diff --git a/Source/Core/DiscIO/CompressedBlob.h b/Source/Core/DiscIO/CompressedBlob.h
index 602d21d91a..d1b2459145 100644
--- a/Source/Core/DiscIO/CompressedBlob.h
+++ b/Source/Core/DiscIO/CompressedBlob.h
@@ -58,6 +58,7 @@ public:
u64 GetBlockSize() const override { return m_header.block_size; }
bool HasFastRandomAccessInBlock() const override { return false; }
+ std::string GetCompressionMethod() const override { return "Deflate"; }
u64 GetBlockCompressedSize(u64 block_num) const;
bool GetBlock(u64 block_num, u8* out_ptr) override;
diff --git a/Source/Core/DiscIO/DirectoryBlob.h b/Source/Core/DiscIO/DirectoryBlob.h
index d526c26ea2..9e6a834151 100644
--- a/Source/Core/DiscIO/DirectoryBlob.h
+++ b/Source/Core/DiscIO/DirectoryBlob.h
@@ -168,6 +168,7 @@ public:
u64 GetBlockSize() const override { return 0; }
bool HasFastRandomAccessInBlock() const override { return true; }
+ std::string GetCompressionMethod() const override { return {}; }
private:
struct PartitionWithType
diff --git a/Source/Core/DiscIO/DriveBlob.h b/Source/Core/DiscIO/DriveBlob.h
index 65356feb41..ec100185e8 100644
--- a/Source/Core/DiscIO/DriveBlob.h
+++ b/Source/Core/DiscIO/DriveBlob.h
@@ -32,6 +32,7 @@ public:
u64 GetBlockSize() const override { return ECC_BLOCK_SIZE; }
bool HasFastRandomAccessInBlock() const override { return false; }
+ std::string GetCompressionMethod() const override { return {}; }
private:
DriveReader(const std::string& drive);
diff --git a/Source/Core/DiscIO/FileBlob.h b/Source/Core/DiscIO/FileBlob.h
index bb97cea7e4..d418976fa3 100644
--- a/Source/Core/DiscIO/FileBlob.h
+++ b/Source/Core/DiscIO/FileBlob.h
@@ -27,6 +27,7 @@ public:
u64 GetBlockSize() const override { return 0; }
bool HasFastRandomAccessInBlock() const override { return true; }
+ std::string GetCompressionMethod() const override { return {}; }
bool Read(u64 offset, u64 nbytes, u8* out_ptr) override;
diff --git a/Source/Core/DiscIO/ScrubbedBlob.h b/Source/Core/DiscIO/ScrubbedBlob.h
index badeb457f8..5bd8652ad5 100644
--- a/Source/Core/DiscIO/ScrubbedBlob.h
+++ b/Source/Core/DiscIO/ScrubbedBlob.h
@@ -30,6 +30,10 @@ public:
{
return m_blob_reader->HasFastRandomAccessInBlock();
}
+ std::string GetCompressionMethod() const override
+ {
+ return m_blob_reader->GetCompressionMethod();
+ }
bool Read(u64 offset, u64 size, u8* out_ptr) override;
diff --git a/Source/Core/DiscIO/TGCBlob.h b/Source/Core/DiscIO/TGCBlob.h
index b76a282d6e..101e969c89 100644
--- a/Source/Core/DiscIO/TGCBlob.h
+++ b/Source/Core/DiscIO/TGCBlob.h
@@ -50,6 +50,7 @@ public:
u64 GetBlockSize() const override { return 0; }
bool HasFastRandomAccessInBlock() const override { return true; }
+ std::string GetCompressionMethod() const override { return {}; }
bool Read(u64 offset, u64 nbytes, u8* out_ptr) override;
diff --git a/Source/Core/DiscIO/VolumeFileBlobReader.cpp b/Source/Core/DiscIO/VolumeFileBlobReader.cpp
index eb80003adc..3f50f1332d 100644
--- a/Source/Core/DiscIO/VolumeFileBlobReader.cpp
+++ b/Source/Core/DiscIO/VolumeFileBlobReader.cpp
@@ -54,6 +54,11 @@ bool VolumeFileBlobReader::HasFastRandomAccessInBlock() const
return m_volume.GetBlobReader().HasFastRandomAccessInBlock();
}
+std::string VolumeFileBlobReader::GetCompressionMethod() const
+{
+ return m_volume.GetBlobReader().GetCompressionMethod();
+}
+
bool VolumeFileBlobReader::Read(u64 offset, u64 length, u8* out_ptr)
{
if (offset + length > m_file_info->GetSize())
diff --git a/Source/Core/DiscIO/VolumeFileBlobReader.h b/Source/Core/DiscIO/VolumeFileBlobReader.h
index 8e227ece63..5cdb7baf7c 100644
--- a/Source/Core/DiscIO/VolumeFileBlobReader.h
+++ b/Source/Core/DiscIO/VolumeFileBlobReader.h
@@ -30,6 +30,7 @@ public:
u64 GetBlockSize() const override;
bool HasFastRandomAccessInBlock() const override;
+ std::string GetCompressionMethod() const override;
bool Read(u64 offset, u64 length, u8* out_ptr) override;
diff --git a/Source/Core/DiscIO/WIABlob.cpp b/Source/Core/DiscIO/WIABlob.cpp
index 6f64b3ba01..4886ceaf7c 100644
--- a/Source/Core/DiscIO/WIABlob.cpp
+++ b/Source/Core/DiscIO/WIABlob.cpp
@@ -291,6 +291,26 @@ BlobType WIARVZFileReader<RVZ>::GetBlobType() const
}
template <bool RVZ>
+std::string WIARVZFileReader<RVZ>::GetCompressionMethod() const
+{
+ switch (m_compression_type)
+ {
+ case WIARVZCompressionType::Purge:
+ return "Purge";
+ case WIARVZCompressionType::Bzip2:
+ return "bzip2";
+ case WIARVZCompressionType::LZMA:
+ return "LZMA";
+ case WIARVZCompressionType::LZMA2:
+ return "LZMA2";
+ case WIARVZCompressionType::Zstd:
+ return "Zstandard";
+ default:
+ return {};
+ }
+}
+
+template <bool RVZ>
bool WIARVZFileReader<RVZ>::Read(u64 offset, u64 size, u8* out_ptr)
{
if (offset + size > Common::swap64(m_header_1.iso_file_size))
diff --git a/Source/Core/DiscIO/WIABlob.h b/Source/Core/DiscIO/WIABlob.h
index 789a3e7dd5..8f941ce98b 100644
--- a/Source/Core/DiscIO/WIABlob.h
+++ b/Source/Core/DiscIO/WIABlob.h
@@ -56,6 +56,7 @@ public:
u64 GetBlockSize() const override { return Common::swap32(m_header_2.chunk_size); }
bool HasFastRandomAccessInBlock() const override { return false; }
+ std::string GetCompressionMethod() const override;
bool Read(u64 offset, u64 size, u8* out_ptr) override;
bool SupportsReadWiiDecrypted() const override;
diff --git a/Source/Core/DiscIO/WbfsBlob.h b/Source/Core/DiscIO/WbfsBlob.h
index 0f985fe3d4..d3bca22ecc 100644
--- a/Source/Core/DiscIO/WbfsBlob.h
+++ b/Source/Core/DiscIO/WbfsBlob.h
@@ -34,6 +34,7 @@ public:
u64 GetBlockSize() const override { return m_wbfs_sector_size; }
bool HasFastRandomAccessInBlock() const override { return true; }
+ std::string GetCompressionMethod() const override { return {}; }
bool Read(u64 offset, u64 nbytes, u8* out_ptr) override;
diff --git a/Source/Core/DolphinQt/Config/InfoWidget.cpp b/Source/Core/DolphinQt/Config/InfoWidget.cpp
index 9d7c643a14..3bcd186fb1 100644
--- a/Source/Core/DolphinQt/Config/InfoWidget.cpp
+++ b/Source/Core/DolphinQt/Config/InfoWidget.cpp
@@ -27,7 +27,8 @@ InfoWidget::InfoWidget(const UICommon::GameFile& game) : m_game(game)
{
QVBoxLayout* layout = new QVBoxLayout();
- layout->addWidget(CreateISODetails());
+ layout->addWidget(CreateFileDetails());
+ layout->addWidget(CreateGameDetails());
if (!game.GetLanguages().empty())
layout->addWidget(CreateBannerDetails());
@@ -35,20 +36,55 @@ InfoWidget::InfoWidget(const UICommon::GameFile& game) : m_game(game)
setLayout(layout);
}
-QGroupBox* InfoWidget::CreateISODetails()
+QGroupBox* InfoWidget::CreateFileDetails()
+{
+ QGroupBox* group = new QGroupBox(tr("File Details"));
+ QFormLayout* layout = new QFormLayout;
+
+ layout->setFieldGrowthPolicy(QFormLayout::AllNonFixedFieldsGrow);
+
+ QString path = QDir::toNativeSeparators(QString::fromStdString(m_game.GetFilePath()));
+ layout->addRow(tr("Path:"), CreateValueDisplay(path));
+
+ const std::string file_size = UICommon::FormatSize(m_game.GetFileSize());
+
+ if (!m_game.ShouldShowFileFormatDetails())
+ {
+ layout->addRow(tr("File Size:"), CreateValueDisplay(file_size));
+ }
+ else
+ {
+ const QString file_format =
+ QStringLiteral("%1 (%2)")
+ .arg(QString::fromStdString(DiscIO::GetName(m_game.GetBlobType(), true)))
+ .arg(QString::fromStdString(file_size));
+ layout->addRow(tr("File Format:"), CreateValueDisplay(file_format));
+
+ QString compression = QString::fromStdString(m_game.GetCompressionMethod());
+ if (compression.isEmpty())
+ compression = tr("No Compression");
+ layout->addRow(tr("Compression:"), CreateValueDisplay(compression));
+
+ if (m_game.GetBlockSize() > 0)
+ {
+ const std::string block_size = UICommon::FormatSize(m_game.GetBlockSize(), 0);
+ layout->addRow(tr("Block Size:"), CreateValueDisplay(block_size));
+ }
+ }
+
+ group->setLayout(layout);
+ return group;
+}
+
+QGroupBox* InfoWidget::CreateGameDetails()
{
const QString UNKNOWN_NAME = tr("Unknown");
- QGroupBox* group = new QGroupBox(tr("ISO Details"));
+ QGroupBox* group = new QGroupBox(tr("Game Details"));
QFormLayout* layout = new QFormLayout;
layout->setFieldGrowthPolicy(QFormLayout::AllNonFixedFieldsGrow);
- QLineEdit* file_path = CreateValueDisplay(
- QStringLiteral("%1 (%2)")
- .arg(QDir::toNativeSeparators(QString::fromStdString(m_game.GetFilePath())))
- .arg(QString::fromStdString(UICommon::FormatSize(m_game.GetFileSize()))));
-
const QString game_name = QString::fromStdString(m_game.GetInternalName());
bool is_disc_based = m_game.GetPlatform() == DiscIO::Platform::GameCubeDisc ||
@@ -79,7 +115,6 @@ QGroupBox* InfoWidget::CreateISODetails()
m_game.GetMakerID() + ")");
layout->addRow(tr("Name:"), internal_name);
- layout->addRow(tr("File:"), file_path);
layout->addRow(tr("Game ID:"), game_id);
layout->addRow(tr("Country:"), country);
layout->addRow(tr("Maker:"), maker);
diff --git a/Source/Core/DolphinQt/Config/InfoWidget.h b/Source/Core/DolphinQt/Config/InfoWidget.h
index c409b0eb85..e32474f996 100644
--- a/Source/Core/DolphinQt/Config/InfoWidget.h
+++ b/Source/Core/DolphinQt/Config/InfoWidget.h
@@ -26,8 +26,9 @@ private:
void ChangeLanguage();
void SaveBanner();
+ QGroupBox* CreateFileDetails();
+ QGroupBox* CreateGameDetails();
QGroupBox* CreateBannerDetails();
- QGroupBox* CreateISODetails();
QLineEdit* CreateValueDisplay(const QString& value);
QLineEdit* CreateValueDisplay(const std::string& value = "");
void CreateLanguageSelector();
diff --git a/Source/Core/UICommon/GameFile.cpp b/Source/Core/UICommon/GameFile.cpp
index ca5c53ae31..31a3fa4d26 100644
--- a/Source/Core/UICommon/GameFile.cpp
+++ b/Source/Core/UICommon/GameFile.cpp
@@ -115,6 +115,8 @@ GameFile::GameFile(std::string path) : m_file_path(std::move(path))
m_region = volume->GetRegion();
m_country = volume->GetCountry();
m_blob_type = volume->GetBlobType();
+ m_block_size = volume->GetBlobReader().GetBlockSize();
+ m_compression_method = volume->GetBlobReader().GetCompressionMethod();
m_file_size = volume->GetRawSize();
m_volume_size = volume->GetSize();
m_volume_size_is_accurate = volume->IsSizeAccurate();
@@ -320,6 +322,8 @@ void GameFile::DoState(PointerWrap& p)
p.Do(m_country);
p.Do(m_platform);
p.Do(m_blob_type);
+ p.Do(m_block_size);
+ p.Do(m_compression_method);
p.Do(m_revision);
p.Do(m_disc_number);
p.Do(m_apploader_date);
@@ -566,6 +570,29 @@ std::string GameFile::GetWiiFSPath() const
return Common::GetTitleDataPath(m_title_id, Common::FROM_CONFIGURED_ROOT);
}
+bool GameFile::ShouldShowFileFormatDetails() const
+{
+ switch (m_blob_type)
+ {
+ case DiscIO::BlobType::PLAIN:
+ break;
+ case DiscIO::BlobType::DRIVE:
+ return false;
+ default:
+ return true;
+ }
+
+ switch (m_platform)
+ {
+ case DiscIO::Platform::WiiWAD:
+ return false;
+ case DiscIO::Platform::ELFOrDOL:
+ return false;
+ default:
+ return true;
+ }
+}
+
const GameBanner& GameFile::GetBannerImage() const
{
return m_custom_banner.empty() ? m_volume_banner : m_custom_banner;
diff --git a/Source/Core/UICommon/GameFile.h b/Source/Core/UICommon/GameFile.h
index e3c29860f4..3450111238 100644
--- a/Source/Core/UICommon/GameFile.h
+++ b/Source/Core/UICommon/GameFile.h
@@ -86,6 +86,9 @@ public:
DiscIO::Country GetCountry() const { return m_country; }
DiscIO::Platform GetPlatform() const { return m_platform; }
DiscIO::BlobType GetBlobType() const { return m_blob_type; }
+ u64 GetBlockSize() const { return m_block_size; }
+ const std::string& GetCompressionMethod() const { return m_compression_method; }
+ bool ShouldShowFileFormatDetails() const;
const std::string& GetApploaderDate() const { return m_apploader_date; }
u64 GetFileSize() const { return m_file_size; }
u64 GetVolumeSize() const { return m_volume_size; }
@@ -144,6 +147,8 @@ private:
DiscIO::Country m_country{DiscIO::Country::Unknown};
DiscIO::Platform m_platform{};
DiscIO::BlobType m_blob_type{};
+ u64 m_block_size{};
+ std::string m_compression_method{};
u16 m_revision{};
u8 m_disc_number{};
std::string m_apploader_date;
diff --git a/Source/Core/UICommon/GameFileCache.cpp b/Source/Core/UICommon/GameFileCache.cpp
index 1af33ae44b..c551016d7f 100644
--- a/Source/Core/UICommon/GameFileCache.cpp
+++ b/Source/Core/UICommon/GameFileCache.cpp
@@ -27,7 +27,7 @@
namespace UICommon
{
-static constexpr u32 CACHE_REVISION = 17; // Last changed in PR 8738
+static constexpr u32 CACHE_REVISION = 18; // Last changed in PR 8891
std::vector<std::string> FindAllGamePaths(const std::vector<std::string>& directories_to_scan,
bool recursive_scan)