فهرست منبع

Loader: Split SMDH into its own header and import helpers from QGameList

Also rewrite Qt wrappers to use those.
Emmanuel Gil Peyrot 10 سال پیش
والد
کامیت
080a2d719c
5فایلهای تغییر یافته به همراه149 افزوده شده و 89 حذف شده
  1. 11 42
      src/citra_qt/game_list_p.h
  2. 2 0
      src/core/CMakeLists.txt
  3. 0 47
      src/core/loader/loader.h
  4. 54 0
      src/core/loader/smdh.cpp
  5. 82 0
      src/core/loader/smdh.h

+ 11 - 42
src/citra_qt/game_list_p.h

@@ -15,52 +15,21 @@
 #include "common/string_util.h"
 #include "common/color.h"
 
-#include "core/loader/loader.h"
+#include "core/loader/smdh.h"
 
 #include "video_core/utils.h"
 
-/**
- * Tests if data is a valid SMDH by its length and magic number.
- * @param smdh_data data buffer to test
- * @return bool test result
- */
-static bool IsValidSMDH(const std::vector<u8>& smdh_data) {
-    if (smdh_data.size() < sizeof(Loader::SMDH))
-        return false;
-
-    u32 magic;
-    memcpy(&magic, smdh_data.data(), 4);
-
-    return Loader::MakeMagic('S', 'M', 'D', 'H') == magic;
-}
-
 /**
  * Gets game icon from SMDH
  * @param sdmh SMDH data
  * @param large If true, returns large icon (48x48), otherwise returns small icon (24x24)
  * @return QPixmap game icon
  */
-static QPixmap GetIconFromSMDH(const Loader::SMDH& smdh, bool large) {
-    u32 size;
-    const u8* icon_data;
-
-    if (large) {
-        size = 48;
-        icon_data = smdh.large_icon.data();
-    } else {
-        size = 24;
-        icon_data = smdh.small_icon.data();
-    }
-
-    QImage icon(size, size, QImage::Format::Format_RGB888);
-    for (u32 x = 0; x < size; ++x) {
-        for (u32 y = 0; y < size; ++y) {
-            u32 coarse_y = y & ~7;
-            auto v = Color::DecodeRGB565(
-                icon_data + VideoCore::GetMortonOffset(x, y, 2) + coarse_y * size * 2);
-            icon.setPixel(x, y, qRgb(v.r(), v.g(), v.b()));
-        }
-    }
+static QPixmap GetQPixmapFromSMDH(const Loader::SMDH& smdh, bool large) {
+    std::vector<u16> icon_data = smdh.GetIcon(large);
+    const uchar* data = reinterpret_cast<const uchar*>(icon_data.data());
+    int size = large ? 48 : 24;
+    QImage icon(data, size, size, QImage::Format::Format_RGB16);
     return QPixmap::fromImage(icon);
 }
 
@@ -82,8 +51,8 @@ static QPixmap GetDefaultIcon(bool large) {
  * @param language title language
  * @return QString short title
  */
-static QString GetShortTitleFromSMDH(const Loader::SMDH& smdh, Loader::SMDH::TitleLanguage language) {
-    return QString::fromUtf16(smdh.titles[static_cast<int>(language)].short_title.data());
+static QString GetQStringShortTitleFromSMDH(const Loader::SMDH& smdh, Loader::SMDH::TitleLanguage language) {
+    return QString::fromUtf16(smdh.GetShortTitle(language).data());
 }
 
 class GameListItem : public QStandardItem {
@@ -112,7 +81,7 @@ public:
     {
         setData(game_path, FullPathRole);
 
-        if (!IsValidSMDH(smdh_data)) {
+        if (!Loader::IsValidSMDH(smdh_data)) {
             // SMDH is not valid, set a default icon
             setData(GetDefaultIcon(true), Qt::DecorationRole);
             return;
@@ -122,10 +91,10 @@ public:
         memcpy(&smdh, smdh_data.data(), sizeof(Loader::SMDH));
 
         // Get icon from SMDH
-        setData(GetIconFromSMDH(smdh, true), Qt::DecorationRole);
+        setData(GetQPixmapFromSMDH(smdh, true), Qt::DecorationRole);
 
         // Get title form SMDH
-        setData(GetShortTitleFromSMDH(smdh, Loader::SMDH::TitleLanguage::English), TitleRole);
+        setData(GetQStringShortTitleFromSMDH(smdh, Loader::SMDH::TitleLanguage::English), TitleRole);
     }
 
     QVariant data(int role) const override {

+ 2 - 0
src/core/CMakeLists.txt

@@ -121,6 +121,7 @@ set(SRCS
             loader/elf.cpp
             loader/loader.cpp
             loader/ncch.cpp
+            loader/smdh.cpp
             tracer/recorder.cpp
             memory.cpp
             settings.cpp
@@ -256,6 +257,7 @@ set(HEADERS
             loader/elf.h
             loader/loader.h
             loader/ncch.h
+            loader/smdh.h
             tracer/recorder.h
             tracer/citrace.h
             memory.h

+ 0 - 47
src/core/loader/loader.h

@@ -10,10 +10,8 @@
 #include <string>
 #include <vector>
 
-#include "common/common_funcs.h"
 #include "common/common_types.h"
 #include "common/file_util.h"
-#include "common/swap.h"
 
 namespace Kernel {
 struct AddressMapping;
@@ -80,51 +78,6 @@ constexpr u32 MakeMagic(char a, char b, char c, char d) {
     return a | b << 8 | c << 16 | d << 24;
 }
 
-/// SMDH data structure that contains titles, icons etc. See https://www.3dbrew.org/wiki/SMDH
-struct SMDH {
-    u32_le magic;
-    u16_le version;
-    INSERT_PADDING_BYTES(2);
-
-    struct Title {
-        std::array<u16, 0x40> short_title;
-        std::array<u16, 0x80> long_title;
-        std::array<u16, 0x40> publisher;
-    };
-    std::array<Title, 16> titles;
-
-    std::array<u8, 16> ratings;
-    u32_le region_lockout;
-    u32_le match_maker_id;
-    u64_le match_maker_bit_id;
-    u32_le flags;
-    u16_le eula_version;
-    INSERT_PADDING_BYTES(2);
-    float_le banner_animation_frame;
-    u32_le cec_id;
-    INSERT_PADDING_BYTES(8);
-
-    std::array<u8, 0x480> small_icon;
-    std::array<u8, 0x1200> large_icon;
-
-    /// indicates the language used for each title entry
-    enum class TitleLanguage {
-        Japanese = 0,
-        English = 1,
-        French = 2,
-        German = 3,
-        Italian = 4,
-        Spanish = 5,
-        SimplifiedChinese = 6,
-        Korean= 7,
-        Dutch = 8,
-        Portuguese = 9,
-        Russian = 10,
-        TraditionalChinese = 11
-    };
-};
-static_assert(sizeof(SMDH) == 0x36C0, "SMDH structure size is wrong");
-
 /// Interface for loading an application
 class AppLoader : NonCopyable {
 public:

+ 54 - 0
src/core/loader/smdh.cpp

@@ -0,0 +1,54 @@
+// Copyright 2016 Citra Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include <cstring>
+#include <vector>
+
+#include "common/common_types.h"
+
+#include "core/loader/loader.h"
+#include "core/loader/smdh.h"
+
+#include "video_core/utils.h"
+
+namespace Loader {
+
+bool IsValidSMDH(const std::vector<u8>& smdh_data) {
+    if (smdh_data.size() < sizeof(Loader::SMDH))
+        return false;
+
+    u32 magic;
+    memcpy(&magic, smdh_data.data(), sizeof(u32));
+
+    return Loader::MakeMagic('S', 'M', 'D', 'H') == magic;
+}
+
+std::vector<u16> SMDH::GetIcon(bool large) const {
+    u32 size;
+    const u8* icon_data;
+
+    if (large) {
+        size = 48;
+        icon_data = large_icon.data();
+    } else {
+        size = 24;
+        icon_data = small_icon.data();
+    }
+
+    std::vector<u16> icon(size * size);
+    for (u32 x = 0; x < size; ++x) {
+        for (u32 y = 0; y < size; ++y) {
+            u32 coarse_y = y & ~7;
+            const u8* pixel = icon_data + VideoCore::GetMortonOffset(x, y, 2) + coarse_y * size * 2;
+            icon[x + size * y] = (pixel[1] << 8) + pixel[0];
+        }
+    }
+    return icon;
+}
+
+std::array<u16, 0x40> SMDH::GetShortTitle(Loader::SMDH::TitleLanguage language) const {
+    return titles[static_cast<int>(language)].short_title;
+}
+
+} // namespace

+ 82 - 0
src/core/loader/smdh.h

@@ -0,0 +1,82 @@
+// Copyright 2016 Citra Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include <array>
+#include <vector>
+
+#include "common/common_funcs.h"
+#include "common/common_types.h"
+#include "common/swap.h"
+
+namespace Loader {
+
+/**
+ * Tests if data is a valid SMDH by its length and magic number.
+ * @param smdh_data data buffer to test
+ * @return bool test result
+ */
+bool IsValidSMDH(const std::vector<u8>& smdh_data);
+
+/// SMDH data structure that contains titles, icons etc. See https://www.3dbrew.org/wiki/SMDH
+struct SMDH {
+    u32_le magic;
+    u16_le version;
+    INSERT_PADDING_BYTES(2);
+
+    struct Title {
+        std::array<u16, 0x40> short_title;
+        std::array<u16, 0x80> long_title;
+        std::array<u16, 0x40> publisher;
+    };
+    std::array<Title, 16> titles;
+
+    std::array<u8, 16> ratings;
+    u32_le region_lockout;
+    u32_le match_maker_id;
+    u64_le match_maker_bit_id;
+    u32_le flags;
+    u16_le eula_version;
+    INSERT_PADDING_BYTES(2);
+    float_le banner_animation_frame;
+    u32_le cec_id;
+    INSERT_PADDING_BYTES(8);
+
+    std::array<u8, 0x480> small_icon;
+    std::array<u8, 0x1200> large_icon;
+
+    /// indicates the language used for each title entry
+    enum class TitleLanguage {
+        Japanese = 0,
+        English = 1,
+        French = 2,
+        German = 3,
+        Italian = 4,
+        Spanish = 5,
+        SimplifiedChinese = 6,
+        Korean= 7,
+        Dutch = 8,
+        Portuguese = 9,
+        Russian = 10,
+        TraditionalChinese = 11
+    };
+
+    /**
+     * Gets game icon from SMDH
+     * @param large If true, returns large icon (48x48), otherwise returns small icon (24x24)
+     * @return vector of RGB565 data
+     */
+    std::vector<u16> GetIcon(bool large) const;
+
+    /**
+     * Gets the short game title from SMDH
+     * @param language title language
+     * @return UTF-16 array of the short title
+     */
+    std::array<u16, 0x40> GetShortTitle(Loader::SMDH::TitleLanguage language) const;
+};
+static_assert(sizeof(SMDH) == 0x36C0, "SMDH structure size is wrong");
+
+} // namespace