diff options
author | WaluigiWare64 <68647953+WaluigiWare64@users.noreply.github.com> | 2021-07-02 17:42:54 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-07-02 16:42:54 +0000 |
commit | e5240a688c54d07dd6d6b4994a920137d15bbad3 (patch) | |
tree | 267691a34b04fb8b121c4df6cbccb9f8d45fa05c | |
parent | 5a071c4c29c7d8943c5588e3198564d033a73acb (diff) |
Add ROM Header struct and ROM info dialog (#1095)
-rw-r--r-- | src/NDSCart.cpp | 24 | ||||
-rw-r--r-- | src/NDSCart.h | 4 | ||||
-rw-r--r-- | src/NDS_Header.h | 119 | ||||
-rw-r--r-- | src/frontend/FrontendUtil.h | 5 | ||||
-rw-r--r-- | src/frontend/Util_ROM.cpp | 68 | ||||
-rw-r--r-- | src/frontend/qt_sdl/CMakeLists.txt | 1 | ||||
-rw-r--r-- | src/frontend/qt_sdl/ROMInfoDialog.cpp | 145 | ||||
-rw-r--r-- | src/frontend/qt_sdl/ROMInfoDialog.h | 75 | ||||
-rw-r--r-- | src/frontend/qt_sdl/ROMInfoDialog.ui | 831 | ||||
-rw-r--r-- | src/frontend/qt_sdl/main.cpp | 17 | ||||
-rw-r--r-- | src/frontend/qt_sdl/main.h | 2 |
11 files changed, 1284 insertions, 7 deletions
diff --git a/src/NDSCart.cpp b/src/NDSCart.cpp index 96cbaa3..65bed2b 100644 --- a/src/NDSCart.cpp +++ b/src/NDSCart.cpp @@ -58,6 +58,9 @@ u32 CartID; bool CartIsHomebrew; bool CartIsDSi; +NDSHeader Header; +NDSBanner Banner; + CartCommon* Cart; u32 Key1_KeyBuf[0x412]; @@ -1498,8 +1501,11 @@ void DecryptSecureArea(u8* out) // * .srl ROMs (VC dumps) have encrypted secure areas but have precomputed // decryption data at 0x1000 (and at the beginning of the DSi region if any) - u32 gamecode = *(u32*)&CartROM[0x0C]; - u32 arm9base = *(u32*)&CartROM[0x20]; + u32 gamecode = (u32)Header.GameCode[3] << 24 | + (u32)Header.GameCode[2] << 16 | + (u32)Header.GameCode[1] << 8 | + (u32)Header.GameCode[0]; + u32 arm9base = Header.ARM9ROMOffset; memcpy(out, &CartROM[arm9base], 0x800); @@ -1526,11 +1532,17 @@ void DecryptSecureArea(u8* out) bool LoadROMCommon(u32 filelength, const char *sram, bool direct) { - u32 gamecode; - memcpy(&gamecode, CartROM + 0x0C, 4); - printf("Game code: %c%c%c%c\n", gamecode&0xFF, (gamecode>>8)&0xFF, (gamecode>>16)&0xFF, gamecode>>24); + memcpy(&Header, CartROM, sizeof(Header)); + memcpy(&Banner, CartROM + Header.BannerOffset, sizeof(Banner)); + + printf("Game code: %.4s\n", Header.GameCode); + + u32 gamecode = (u32)Header.GameCode[3] << 24 | + (u32)Header.GameCode[2] << 16 | + (u32)Header.GameCode[1] << 8 | + (u32)Header.GameCode[0]; - u8 unitcode = CartROM[0x12]; + u8 unitcode = Header.UnitCode; CartIsDSi = (unitcode & 0x02) != 0; ROMListEntry romparams; diff --git a/src/NDSCart.h b/src/NDSCart.h index 0345297..cb7f1e2 100644 --- a/src/NDSCart.h +++ b/src/NDSCart.h @@ -20,6 +20,7 @@ #define NDSCART_H #include "types.h" +#include "NDS_Header.h" namespace NDSCart { @@ -191,6 +192,9 @@ extern u32 CartROMSize; extern u32 CartID; +extern NDSHeader Header; +extern NDSBanner Banner; + bool Init(); void DeInit(); void Reset(); diff --git a/src/NDS_Header.h b/src/NDS_Header.h new file mode 100644 index 0000000..d2e70fa --- /dev/null +++ b/src/NDS_Header.h @@ -0,0 +1,119 @@ +/*
+ Copyright 2016-2021 Arisotura, WaluigiWare64
+
+ This file is part of melonDS.
+
+ melonDS is free software: you can redistribute it and/or modify it under
+ the terms of the GNU General Public License as published by the Free
+ Software Foundation, either version 3 of the License, or (at your option)
+ any later version.
+
+ melonDS is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with melonDS. If not, see http://www.gnu.org/licenses/.
+*/
+
+#ifndef NDS_HEADER_H
+#define NDS_HEADER_H
+
+#include "types.h"
+
+// Consult GBATEK for info on what these are
+struct NDSHeader
+{
+ char GameTitle[12];
+ char GameCode[4];
+ char MakerCode[2];
+ u8 UnitCode;
+ u8 EncryptionSeedSelect;
+ u8 CardSize;
+ u8 Reserved1[8];
+ u8 NDSRegion;
+ u8 ROMVersion;
+ u8 Autostart;
+
+ u32 ARM9ROMOffset;
+ u32 ARM9EntryAddress;
+ u32 ARM9RAMAddress;
+ u32 ARM9Size;
+
+ u32 ARM7ROMOffset;
+ u32 ARM7EntryAddress;
+ u32 ARM7RAMAddress;
+ u32 ARM7Size;
+
+ u32 FNTOffset;
+ u32 FNTSize;
+ u32 FATOffset;
+ u32 FATSize;
+
+ u32 ARM9OverlayOffset;
+ u32 ARM9OverlaySize;
+ u32 ARM7OverlayOffset;
+ u32 ARM7OverlaySize;
+
+ u32 NormalCommandSettings;
+ u32 Key1CommandSettings;
+
+ u32 BannerOffset;
+
+ u16 SecureAreaCRC16;
+ u16 SecureAreaDelay;
+
+ // GBATEK lists the following two with a question mark
+ u32 ARM9AutoLoadListAddress;
+ u32 ARM7AutoLoadListAddress;
+
+ u64 SecureAreaDisable;
+
+ u32 ROMSize;
+ u32 HeaderSize;
+
+ u32 Unknown1;
+ u8 Reserved2[52];
+
+ u8 NintendoLogo[156];
+ u16 NintendoLogoCRC16;
+ u16 HeaderCRC16;
+
+ u32 DebugROMOffset;
+ u32 DebugSize;
+ u32 DebugRAMAddress;
+
+ u32 Reserved4;
+ u8 Reserved5[144];
+};
+
+static_assert(sizeof(NDSHeader) == 512, "NDSHeader is not 512 bytes!");
+
+struct NDSBanner
+{
+ u16 Version;
+ u16 CRC16[4];
+ u8 Reserved1[22];
+ u8 Icon[512];
+ u16 Palette[16];
+
+ char16_t JapaneseTitle[128];
+ char16_t EnglishTitle[128];
+ char16_t FrenchTitle[128];
+ char16_t GermanTitle[128];
+ char16_t ItalianTitle[128];
+ char16_t SpanishTitle[128];
+ char16_t ChineseTitle[128];
+ char16_t KoreanTitle[128];
+
+ u8 Reserved2[2048];
+
+ u8 DSiIcon[8][512];
+ u16 DSiPalette[8][16];
+ u16 DSiSequence[64];
+};
+
+static_assert(sizeof(NDSBanner) == 9152, "NDSBanner is not 9152 bytes!");
+
+
+#endif //NDS_HEADER_H
diff --git a/src/frontend/FrontendUtil.h b/src/frontend/FrontendUtil.h index f051c6c..b361c2a 100644 --- a/src/frontend/FrontendUtil.h +++ b/src/frontend/FrontendUtil.h @@ -21,6 +21,8 @@ #include "types.h" +#include <vector> + namespace Frontend { @@ -84,6 +86,9 @@ int LoadROM(const u8 *romdata, u32 romlength, const char *archivefilename, const // simulating ejection of the cartridge void UnloadROM(int slot); +void ROMIcon(u8 (&data)[512], u16 (&palette)[16], u32* iconRef); +void AnimatedROMIcon(u8 (&data)[8][512], u16 (&palette)[8][16], u16 (&sequence)[64], u32 (&animatedTexRef)[32 * 32 * 64], std::vector<int> &animatedSequenceRef); + // reset execution of the current ROM int Reset(); diff --git a/src/frontend/Util_ROM.cpp b/src/frontend/Util_ROM.cpp index 8d691b3..19023fb 100644 --- a/src/frontend/Util_ROM.cpp +++ b/src/frontend/Util_ROM.cpp @@ -19,6 +19,8 @@ #include <stdio.h> #include <string.h> +#include <utility> + #ifdef ARCHIVE_SUPPORT_ENABLED #include "ArchiveUtil.h" #endif @@ -461,6 +463,72 @@ int LoadROM(const char* file, int slot) } } +void ROMIcon(u8 (&data)[512], u16 (&palette)[16], u32* iconRef) +{ + int index = 0; + for (int i = 0; i < 4; i++) + { + for (int j = 0; j < 4; j++) + { + for (int k = 0; k < 8; k++) + { + for (int l = 0; l < 8; l++) + { + u8 pal_index = index % 2 ? data[index/2] >> 4 : data[index/2] & 0x0F; + u8 r = ((palette[pal_index] >> 0) & 0x1F) * 255 / 31; + u8 g = ((palette[pal_index] >> 5) & 0x1F) * 255 / 31; + u8 b = ((palette[pal_index] >> 10) & 0x1F) * 255 / 31; + u8 a = pal_index ? 255: 0; + u32* row = &iconRef[256 * i + 32 * k + 8 * j]; + row[l] = (a << 24) | (r << 16) | (g << 8) | b; + index++; + } + } + } + } +} + +#define SEQ_FLIPV(i) ((i & 0b1000000000000000) >> 15) +#define SEQ_FLIPH(i) ((i & 0b0100000000000000) >> 14) +#define SEQ_PAL(i) ((i & 0b0011100000000000) >> 11) +#define SEQ_BMP(i) ((i & 0b0000011100000000) >> 8) +#define SEQ_DUR(i) ((i & 0b0000000011111111) >> 0) + +void AnimatedROMIcon(u8 (&data)[8][512], u16 (&palette)[8][16], u16 (&sequence)[64], u32 (&animatedTexRef)[32 * 32 * 64], std::vector<int> &animatedSequenceRef) +{ + for (int i = 0; i < 64; i++) + { + if (!sequence[i]) + break; + u32* frame = &animatedTexRef[32 * 32 * i]; + ROMIcon(data[SEQ_BMP(sequence[i])], palette[SEQ_PAL(sequence[i])], frame); + + if (SEQ_FLIPH(sequence[i])) + { + for (int x = 0; x < 32; x++) + { + for (int y = 0; y < 32/2; y++) + { + std::swap(frame[x * 32 + y], frame[x * 32 + (32 - 1 - y)]); + } + } + } + if (SEQ_FLIPV(sequence[i])) + { + for (int x = 0; x < 32/2; x++) + { + for (int y = 0; y < 32; y++) + { + std::swap(frame[x * 32 + y], frame[(32 - 1 - x) * 32 + y]); + } + } + } + + for (int j = 0; j < SEQ_DUR(sequence[i]); j++) + animatedSequenceRef.push_back(i); + } +} + void UnloadROM(int slot) { if (slot == ROMSlot_NDS) diff --git a/src/frontend/qt_sdl/CMakeLists.txt b/src/frontend/qt_sdl/CMakeLists.txt index 05dce4a..1ec01b1 100644 --- a/src/frontend/qt_sdl/CMakeLists.txt +++ b/src/frontend/qt_sdl/CMakeLists.txt @@ -10,6 +10,7 @@ SET(SOURCES_QT_SDL AudioSettingsDialog.cpp WifiSettingsDialog.cpp InterfaceSettingsDialog.cpp + ROMInfoDialog.cpp Input.cpp LAN_PCap.cpp LAN_Socket.cpp diff --git a/src/frontend/qt_sdl/ROMInfoDialog.cpp b/src/frontend/qt_sdl/ROMInfoDialog.cpp new file mode 100644 index 0000000..673aaee --- /dev/null +++ b/src/frontend/qt_sdl/ROMInfoDialog.cpp @@ -0,0 +1,145 @@ +/*
+ Copyright 2016-2021 Arisotura, WaluigiWare64
+
+ This file is part of melonDS.
+
+ melonDS is free software: you can redistribute it and/or modify it under
+ the terms of the GNU General Public License as published by the Free
+ Software Foundation, either version 3 of the License, or (at your option)
+ any later version.
+
+ melonDS is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with melonDS. If not, see http://www.gnu.org/licenses/.
+*/
+
+#include "ROMInfoDialog.h"
+#include "ui_ROMInfoDialog.h"
+
+#include <QFileDialog>
+
+#include "NDS.h"
+#include "NDSCart.h"
+#include "Platform.h"
+#include "Config.h"
+#include "PlatformConfig.h"
+
+QString IntToHex(u64 num)
+{
+ return ("0x" + QString::number(num, 16).toUpper());
+}
+
+QString QStringBytes(u64 num)
+{
+ return (QString::number(num) + " Bytes");
+}
+
+ROMInfoDialog* ROMInfoDialog::currentDlg = nullptr;
+
+ROMInfoDialog::ROMInfoDialog(QWidget* parent) : QDialog(parent), ui(new Ui::ROMInfoDialog)
+{
+ ui->setupUi(this);
+ setAttribute(Qt::WA_DeleteOnClose);
+
+
+ u32 iconData[32 * 32];
+ Frontend::ROMIcon(NDSCart::Banner.Icon, NDSCart::Banner.Palette, iconData);
+ iconImage = QImage(reinterpret_cast<unsigned char*>(iconData), 32, 32, QImage::Format_ARGB32).copy();
+ ui->iconImage->setPixmap(QPixmap::fromImage(iconImage));
+
+ if (NDSCart::Banner.Version == 0x103)
+ {
+ u32 animatedIconData[32 * 32 * 64] = {0};
+ Frontend::AnimatedROMIcon(NDSCart::Banner.DSiIcon, NDSCart::Banner.DSiPalette, NDSCart::Banner.DSiSequence, animatedIconData, animatedSequence);
+
+ for (int i = 0; i < 64; i++)
+ {
+ if (animatedIconData[32 * 32 * i] == 0)
+ break;
+ animatedIconImages.push_back(QPixmap::fromImage(QImage(reinterpret_cast<unsigned char*>(&animatedIconData[32 * 32 * i]), 32, 32, QImage::Format_ARGB32).copy()));
+ }
+
+ iconTimeline = new QTimeLine(animatedSequence.size() / 60 * 1000, this);
+ iconTimeline->setFrameRange(0, animatedSequence.size() - 1);
+ iconTimeline->setLoopCount(0);
+ iconTimeline->setEasingCurve(QEasingCurve::Linear);
+ connect(iconTimeline, &QTimeLine::frameChanged, this, &ROMInfoDialog::iconSetFrame);
+ iconTimeline->start();
+ }
+ else
+ {
+ ui->dsiIconImage->setPixmap(QPixmap::fromImage(iconImage));
+ }
+
+ ui->iconTitle->setText(QString::fromUtf16(NDSCart::Banner.EnglishTitle));
+
+ ui->japaneseTitle->setText(QString::fromUtf16(NDSCart::Banner.JapaneseTitle));
+ ui->englishTitle->setText(QString::fromUtf16(NDSCart::Banner.EnglishTitle));
+ ui->frenchTitle->setText(QString::fromUtf16(NDSCart::Banner.FrenchTitle));
+ ui->germanTitle->setText(QString::fromUtf16(NDSCart::Banner.GermanTitle));
+ ui->italianTitle->setText(QString::fromUtf16(NDSCart::Banner.ItalianTitle));
+ ui->spanishTitle->setText(QString::fromUtf16(NDSCart::Banner.SpanishTitle));
+
+ if (NDSCart::Banner.Version > 1)
+ ui->chineseTitle->setText(QString::fromUtf16(NDSCart::Banner.ChineseTitle));
+ else
+ ui->chineseTitle->setText("None");
+
+ if (NDSCart::Banner.Version > 2)
+ ui->koreanTitle->setText(QString::fromUtf16(NDSCart::Banner.KoreanTitle));
+ else
+ ui->koreanTitle->setText("None");
+
+ ui->gameTitle->setText(QString::fromLatin1(NDSCart::Header.GameTitle, 12));
+ ui->gameCode->setText(QString::fromLatin1(NDSCart::Header.GameCode, 4));
+ ui->makerCode->setText(QString::fromLatin1(NDSCart::Header.MakerCode, 2));
+ ui->cardSize->setText(QString::number(128 << NDSCart::Header.CardSize) + " KB");
+
+ ui->arm9RomOffset->setText(IntToHex(NDSCart::Header.ARM9ROMOffset));
+ ui->arm9EntryAddress->setText(IntToHex(NDSCart::Header.ARM9EntryAddress));
+ ui->arm9RamAddress->setText(IntToHex(NDSCart::Header.ARM9RAMAddress));
+ ui->arm9Size->setText(QStringBytes(NDSCart::Header.ARM9Size));
+
+ ui->arm7RomOffset->setText(IntToHex(NDSCart::Header.ARM7ROMOffset));
+ ui->arm7EntryAddress->setText(IntToHex(NDSCart::Header.ARM7EntryAddress));
+ ui->arm7RamAddress->setText(IntToHex(NDSCart::Header.ARM7RAMAddress));
+ ui->arm7Size->setText(QStringBytes(NDSCart::Header.ARM7Size));
+
+ ui->fntOffset->setText(IntToHex(NDSCart::Header.FNTOffset));
+ ui->fntSize->setText(QStringBytes(NDSCart::Header.FNTSize));
+ ui->fatOffset->setText(IntToHex(NDSCart::Header.FATOffset));
+ ui->fatSize->setText(QStringBytes(NDSCart::Header.FATSize));
+
+}
+
+ROMInfoDialog::~ROMInfoDialog()
+{
+ delete ui;
+}
+
+void ROMInfoDialog::done(int r)
+{
+ QDialog::done(r);
+
+ closeDlg();
+}
+
+void ROMInfoDialog::on_saveIconButton_clicked()
+{
+ QString filename = QFileDialog::getSaveFileName(this,
+ "Save Icon",
+ Config::LastROMFolder,
+ "PNG Images (*.png)");
+ if (filename.isEmpty())
+ return;
+
+ iconImage.save(filename, "PNG");
+}
+
+void ROMInfoDialog::iconSetFrame(int frame)
+{
+ ui->dsiIconImage->setPixmap(animatedIconImages[animatedSequence[frame]]);
+}
diff --git a/src/frontend/qt_sdl/ROMInfoDialog.h b/src/frontend/qt_sdl/ROMInfoDialog.h new file mode 100644 index 0000000..5193554 --- /dev/null +++ b/src/frontend/qt_sdl/ROMInfoDialog.h @@ -0,0 +1,75 @@ +/*
+ Copyright 2016-2021 Arisotura, WaluigiWare64
+
+ This file is part of melonDS.
+
+ melonDS is free software: you can redistribute it and/or modify it under
+ the terms of the GNU General Public License as published by the Free
+ Software Foundation, either version 3 of the License, or (at your option)
+ any later version.
+
+ melonDS is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with melonDS. If not, see http://www.gnu.org/licenses/.
+*/
+
+#ifndef ROMINFODIALOG_H
+#define ROMINFODIALOG_H
+
+#include <QDialog>
+#include <QTimeLine>
+#include <QPixmap>
+#include <QImage>
+
+#include "types.h"
+#include "FrontendUtil.h"
+
+namespace Ui { class ROMInfoDialog; }
+class ROMInfoDialog;
+
+class ROMInfoDialog : public QDialog
+{
+ Q_OBJECT
+
+public:
+ explicit ROMInfoDialog(QWidget* parent);
+ ~ROMInfoDialog();
+
+ static ROMInfoDialog* currentDlg;
+ static ROMInfoDialog* openDlg(QWidget* parent)
+ {
+ if (currentDlg)
+ {
+ currentDlg->activateWindow();
+ return currentDlg;
+ }
+
+ currentDlg = new ROMInfoDialog(parent);
+ currentDlg->open();
+ return currentDlg;
+ }
+ static void closeDlg()
+ {
+ currentDlg = nullptr;
+ }
+
+private slots:
+ void done(int r);
+
+ void on_saveIconButton_clicked();
+
+ void iconSetFrame(int frame);
+
+private:
+ Ui::ROMInfoDialog* ui;
+
+ QImage iconImage;
+ QTimeLine* iconTimeline;
+ std::vector<QPixmap> animatedIconImages;
+ std::vector<int> animatedSequence;
+};
+
+#endif // ROMINFODIALOG_H
diff --git a/src/frontend/qt_sdl/ROMInfoDialog.ui b/src/frontend/qt_sdl/ROMInfoDialog.ui new file mode 100644 index 0000000..4c5d7d3 --- /dev/null +++ b/src/frontend/qt_sdl/ROMInfoDialog.ui @@ -0,0 +1,831 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>ROMInfoDialog</class> + <widget class="QDialog" name="ROMInfoDialog"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>427</width> + <height>434</height> + </rect> + </property> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="windowTitle"> + <string>ROM Info - melonDS</string> + </property> + <layout class="QGridLayout" name="gridLayout"> + <item row="2" column="0"> + <widget class="QGroupBox" name="titles"> + <property name="sizePolicy"> + <sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="title"> + <string>Titles</string> + </property> + <layout class="QFormLayout" name="formLayout"> + <item row="0" column="0"> + <widget class="QLabel" name="label_2"> + <property name="font"> + <font> + <underline>false</underline> + </font> + </property> + <property name="text"> + <string>Japanese Title:</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QLabel" name="japaneseTitle"> + <property name="text"> + <string>[japanese title]</string> + </property> + </widget> + </item> + <item row="1" column="0"> + <widget class="QLabel" name="label_3"> + <property name="font"> + <font> + <underline>false</underline> + </font> + </property> + <property name="text"> + <string>English Title:</string> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="QLabel" name="englishTitle"> + <property name="text"> + <string>[english title]</string> + </property> + </widget> + </item> + <item row="2" column="0"> + <widget class="QLabel" name="label_4"> + <property name="font"> + <font> + <underline>false</underline> + </font> + </property> + <property name="text"> + <string>French Title:</string> + </property> + </widget> + </item> + <item row="2" column="1"> + <widget class="QLabel" name="frenchTitle"> + <property name="text"> + <string>[french title]</string> + </property> + </widget> + </item> + <item row="3" column="0"> + <widget class="QLabel" name="label_5"> + <property name="font"> + <font> + <underline>false</underline> + </font> + </property> + <property name="text"> + <string>German Title:</string> + </property> + </widget> + </item> + <item row="3" column="1"> + <widget class="QLabel" name="germanTitle"> + <property name="text"> + <string>[german title]</string> + </property> + </widget> + </item> + <item row="4" column="0"> + <widget class="QLabel" name="label_6"> + <property name="font"> + <font> + <underline>false</underline> + </font> + </property> + <property name="text"> + <string>Italian Title:</string> + </property> + </widget> + </item> + <item row="4" column="1"> + <widget class="QLabel" name="italianTitle"> + <property name="text"> + <string>[italian title]</string> + </property> + </widget> + </item> + <item row="5" column="0"> + <widget class="QLabel" name="label_7"> + <property name="font"> + <font> + <underline>false</underline> + </font> + </property> + <property name="text"> + <string>Spanish Title:</string> + </property> + </widget> + </item> + <item row="5" column="1"> + <widget class="QLabel" name="spanishTitle"> + <property name="text"> + <string>[spanish title]</string> + </property> + </widget> + </item> + <item row="6" column="0"> + <widget class="QLabel" name="label_25"> + <property name="font"> + <font> + <underline>false</underline> + </font> + </property> + <property name="text"> + <string>Chinese Title:</string> + </property> + </widget> + </item> + <item row="6" column="1"> + <widget class="QLabel" name="chineseTitle"> + <property name="text"> + <string>[chinese title]</string> + </property> + </widget> + </item> + <item row="7" column="0"> + <widget class="QLabel" name="label_23"> + <property name="font"> + <font> + <underline>false</underline> + </font> + </property> + <property name="text"> + <string>Korean Title:</string> + </property> + </widget> + </item> + <item row="7" column="1"> + <widget class="QLabel" name="koreanTitle"> + <property name="text"> + <string>[korean title]</string> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item row="2" column="1"> + <widget class="QGroupBox" name="arm9AndArm7Binaries"> + <property name="title"> + <string>ARM7 and ARM9 binaries</string> + </property> + <layout class="QFormLayout" name="formLayout_2"> + <item row="0" column="0"> + <widget class="QLabel" name="label_11"> + <property name="font"> + <font> + <underline>false</underline> + </font> + </property> + <property name="text"> + <string>ARM9 ROM Offset: </string> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QLabel" name="arm9RomOffset"> + <property name="text"> + <string>[arm9 rom offset]</string> + </property> + </widget> + </item> + <item row="1" column="0"> + <widget class="QLabel" name="label_12"> + <property name="font"> + <font> + <underline>false</underline> + </font> + </property> + <property name="text"> + <string>ARM9 Entry Address:</string> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="QLabel" name="arm9EntryAddress"> + <property name="text"> + <string>[arm9 entry address]</string> + </property> + </widget> + </item> + <item row="2" column="0"> + <widget class="QLabel" name="label_14"> + <property name="font"> + <font> + <underline>false</underline> + </font> + </property> + <property name="text"> + <string>ARM9 RAM Address:</string> + </property> + </widget> + </item> + <item row="2" column="1"> + <widget class="QLabel" name="arm9RamAddress"> + <property name="text"> + <string>[arm9 ram address]</string> + </property> + </widget> + </item> + <item row="3" column="0"> + <widget class="QLabel" name="label_16"> + <property name="font"> + <font> + <underline>false</underline> + </font> + </property> + <property name="text"> + <string>ARM9 Size:</string> + </property> + </widget> + </item> + <item row="3" column="1"> + <widget class="QLabel" name="arm9Size"> + <property name="text"> + <string>[arm9 size]</string> + </property> + </widget> + </item> + <item row="4" column="0"> + <widget class="QLabel" name="label_15"> + <property name="font"> + <font> + <underline>false</underline> + </font> + </property> + <property name="text"> + <string>ARM7 ROM Offset: </string> + </property> + </widget> + </item> + <item row="4" column="1"> + <widget class="QLabel" name="arm7RomOffset"> + <property name="text"> + <string>[arm7 rom offset]</string> + </property> + </widget> + </item> + <item row="5" column="0"> + <widget class="QLabel" name="label_13"> + <property name="font"> + <font> + <underline>false</underline> + </font> + </property> + <property name="text"> + <string>ARM7 Entry Address:</string> + </property> + </widget> + </item> + <item row="5" column="1"> + <widget class="QLabel" name="arm7EntryAddress"> + <property name="text"> + <string>[arm7 entry address]</string> + </property> + </widget> + </item> + <item row="6" column="0"> + <widget class="QLabel" name="label_18"> + <property name="font"> + <font> + <underline>false</underline> + </font> + </property> + <property name="text"> + <string>ARM7 RAM Address:</string> + </property> + </widget> + </item> + <item row="6" column="1"> + <widget class="QLabel" name="arm7RamAddress"> + <property name="text"> + <string>[arm7 ram address]</string> + </property> + </widget> + </item> + <item row="7" column="0"> + <widget class="QLabel" name="label_17"> + <property name="font"> + <font> + <underline>false</underline> + </font> + </property> + <property name="text"> + <string>ARM7 Size:</string> + </property> + </widget> + </item> + <item row="7" column="1"> + <widget class="QLabel" name="arm7Size"> + <property name="text"> + <string>[arm7 size]</string> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item row="3" column="1"> + <widget class="QGroupBox" name="filesystem"> + <property name="sizePolicy"> + <sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="title"> + <string>Filesystem</string> + </property> + <layout class="QFormLayout" name="formLayout_4"> + <item row="0" column="0"> + <widget class="QLabel" name="label_19"> + <property name="font"> + <font> + <underline>false</underline> + </font> + </property> + <property name="text"> + <string>FNT Offset:</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QLabel" name="fntOffset"> + <property name="text"> + <string>[fnt offset]</string> + </property> + </widget> + </item> + <item row="1" column="0"> + <widget class="QLabel" name="label_20"> + <property name="font"> + <font> + <underline>false</underline> + </font> + </property> + <property name="text"> + <string>FNT Size:</string> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="QLabel" name="fntSize"> + <property name="text"> + <string>[fnt size]</string> + </property> + </widget> + </item> + <item row="2" column="0"> + <widget class="QLabel" name="label_21"> + <property name="font"> + <font> + <underline>false</underline> + </font> + </property> + <property name="text"> + <string>FAT Offset:</string> + </property> + </widget> + </item> + <item row="2" column="1"> + <widget class="QLabel" name="fatOffset"> + <property name="text"> + <string>[fat offset]</string> + </property> + </widget> + </item> + <item row="3" column="0"> + <widget class="QLabel" name="label_22"> + <property name="font"> + <font> + <underline>false</underline> + </font> + </property> + <property name="text"> + <string>FAT Size:</string> + </property> + </widget> + </item> + <item row="3" column="1"> + <widget class="QLabel" name="fatSize"> + <property name="text"> + <string>[fat size]</string> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item row="3" column="0"> + <widget class="QGroupBox" name="generalInfo"> + <property name="sizePolicy"> + <sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="title"> + <string>General Info</string> + </property> + <layout class="QFormLayout" name="formLayout_3"> + <item row="0" column="0"> + <widget class="QLabel" name="label"> + <property name="font"> + <font> + <underline>false</underline> + </font> + </property> + <property name="text"> + <string>Game Title:</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QLabel" name="gameTitle"> + <property name="text"> + <string>[game title]</string> + </property> + </widget> + </item> + <item row="1" column="0"> + <widget class="QLabel" name="label_8"> + <property name="font"> + <font> + <underline>false</underline> + </font> + </property> + <property name="text"> + <string>Game Code:</string> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="QLabel" name="gameCode"> + <property name="text"> + <string>[game code]</string> + </property> + </widget> + </item> + <item row="2" column="0"> + <widget class="QLabel" name="label_9"> + <property name="font"> + <font> + <underline>false</underline> + </font> + </property> + <property name="text"> + <string>Maker Code:</string> + </property> + </widget> + </item> + <item row="2" column="1"> + <widget class="QLabel" name="makerCode"> + <property name="text"> + <string>[maker code]</string> + </property> + </widget> + </item> + <item row="3" column="0"> + <widget class="QLabel" name="label_10"> + <property name="font"> + <font> + <underline>false</underline> + </font> + </property> + <property name="text"> + <string>Card Size:</string> + </property> + </widget> + </item> + <item row="3" column="1"> + <widget class="QLabel" name="cardSize"> + <property name="text"> + <string>[card size]</string> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item row="4" column="0" colspan="2"> + <widget class="QDialogButtonBox" name="buttonBox"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="standardButtons"> + <set>QDialogButtonBox::Ok</set> + </property> + </widget> + </item> + <item row="0" column="0" colspan="2"> + <widget class="QGroupBox" name="groupBox_2"> + <layout class="QGridLayout" name="gridLayout_9"> + <item row="0" column="1"> + <widget class="QGroupBox" name="iconBox"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="styleSheet"> + <string notr="true">#iconBox { + border: 1px solid black; + background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, + stop: 0 white, + stop: 1 lightgrey); +} + +#titleBox { + border: 0.5px solid grey; + background-color: #fbfbfb; +} + +#iconTitle { + color: black; +} +</string> + </property> + <property name="title"> + <string/> + </property> + <property name="alignment"> + <set>Qt::AlignCenter</set> + </property> + <property name="flat"> + <bool>false</bool> + </property> + <property name="checkable"> + <bool>false</bool> + </property> + <layout class="QGridLayout" name="gridLayout_2"> + <property name="topMargin"> + <number>2</number> + </property> + <property name="bottomMargin"> + <number>2</number> + </property> + <item row="0" column="1"> + <widget class="QLabel" name="iconImage"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>32</width> + <height>32</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>32</width> + <height>32</height> + </size> + </property> + <property name="text"> + <string>[icon]</string> + </property> + </widget> + </item> + <item row="0" column="2"> + <widget class="QGroupBox" name="titleBox"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Expanding"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="title"> + <string/> + </property> + <layout class="QGridLayout" name="gridLayout_4"> + <property name="leftMargin"> + <number>1</number> + </property> + <property name="topMargin"> + <number>1</number> + </property> + <property name="rightMargin"> + <number>1</number> + </property> + <property name="bottomMargin"> + <number>1</number> + </property> + <item row="0" column="0"> + <widget class="QLabel" name="iconTitle"> + <property name="sizePolicy"> + <sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="font"> + <font> + <family>Courier New</family> + <pointsize>8</pointsize> + <weight>50</weight> + <italic>false</italic> + <bold>false</bold> + </font> + </property> + <property name="text"> + <string>[title]</string> + </property> + <property name="alignment"> + <set>Qt::AlignCenter</set> + </property> + </widget> + </item> + </layout> + </widget> + </item> + </layout> + </widget> + </item> + <item row="0" column="3"> + <widget class="QGroupBox" name="dsiIconBox"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Minimum" vsizetype="Minimum"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="styleSheet"> + <string notr="true">#dsiIconBox { + border-radius: 4px; + background-color: #515151; +} + +#dsiIconImage { + background-color: white; +}</string> + </property> + <property name="title"> + <string/> + </property> + <property name="alignment"> + <set>Qt::AlignCenter</set> + </property> + <property name="flat"> + <bool>false</bool> + </property> + <property name="checkable"> + <bool>false</bool> + </property> + <layout class="QGridLayout" name="gridLayout_10"> + <property name="leftMargin"> + <number>8</number> + </property> + <property name="topMargin"> + <number>6</number> + </property> + <property name="rightMargin"> + <number>8</number> + </property> + <property name="bottomMargin"> + <number>6</number> + </property> + <item row="0" column="0"> + <widget class="QLabel" name="dsiIconImage"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Minimum" vsizetype="Minimum"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>32</width> + <height>32</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>32</width> + <height>32</height> + </size> + </property> + <property name="text"> + <string>[dsi icon]</string> + </property> + <property name="alignment"> + <set>Qt::AlignCenter</set> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item row="0" column="0"> + <spacer name="horizontalSpacer"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>55</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item row="0" column="4"> + <spacer name="horizontalSpacer_3"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item row="0" column="2"> + <spacer name="horizontalSpacer_2"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item row="1" column="1"> + <widget class="QPushButton" name="saveIconButton"> + <property name="text"> + <string>Save Icon</string> + </property> + </widget> + </item> + </layout> + </widget> + </item> + </layout> + </widget> + <resources/> + <connections> + <connection> + <sender>buttonBox</sender> + <signal>accepted()</signal> + <receiver>ROMInfoDialog</receiver> + <slot>accept()</slot> + <hints> + <hint type="sourcelabel"> + <x>248</x> + <y>254</y> + </hint> + <hint type="destinationlabel"> + <x>157</x> + <y>274</y> + </hint> + </hints> + </connection> + <connection> + <sender>buttonBox</sender> + <signal>rejected()</signal> + <receiver>ROMInfoDialog</receiver> + <slot>reject()</slot> + <hints> + <hint type="sourcelabel"> + <x>316</x> + <y>260</y> + </hint> + <hint type="destinationlabel"> + <x>286</x> + <y>274</y> + </hint> + </hints> + </connection> + </connections> +</ui> diff --git a/src/frontend/qt_sdl/main.cpp b/src/frontend/qt_sdl/main.cpp index 8407acb..acb8d29 100644 --- a/src/frontend/qt_sdl/main.cpp +++ b/src/frontend/qt_sdl/main.cpp @@ -57,6 +57,7 @@ #include "AudioSettingsDialog.h" #include "WifiSettingsDialog.h" #include "InterfaceSettingsDialog.h" +#include "ROMInfoDialog.h" #include "types.h" #include "version.h" @@ -65,6 +66,7 @@ #include "OSD.h" #include "NDS.h" +#include "NDSCart.h" #include "GBACart.h" #include "GPU.h" #include "SPU.h" @@ -1331,6 +1333,10 @@ MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent) actSetupCheats = menu->addAction("Setup cheat codes"); actSetupCheats->setMenuRole(QAction::NoRole); connect(actSetupCheats, &QAction::triggered, this, &MainWindow::onSetupCheats); + + menu->addSeparator(); + actROMInfo = menu->addAction("ROM Info"); + connect(actROMInfo, &QAction::triggered, this, &MainWindow::onROMInfo); } { QMenu* menu = menubar->addMenu("Config"); @@ -1533,9 +1539,10 @@ MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent) actSetupCheats->setEnabled(false); - actEnableCheats->setChecked(Config::EnableCheats != 0); + actROMInfo->setEnabled(false); + actSavestateSRAMReloc->setChecked(Config::SavestateRelocSRAM != 0); actScreenRotation[Config::ScreenRotation]->setChecked(true); @@ -2335,6 +2342,10 @@ void MainWindow::onCheatsDialogFinished(int res) emuThread->emuUnpause(); } +void MainWindow::onROMInfo() +{ + ROMInfoDialog* dlg = ROMInfoDialog::openDlg(this); +} void MainWindow::onOpenEmuSettings() { @@ -2589,6 +2600,8 @@ void MainWindow::onEmuStart() actImportSavefile->setEnabled(true); actSetupCheats->setEnabled(true); + + actROMInfo->setEnabled(true); } void MainWindow::onEmuStop() @@ -2609,6 +2622,8 @@ void MainWindow::onEmuStop() actFrameStep->setEnabled(false); actSetupCheats->setEnabled(false); + + actROMInfo->setEnabled(false); } void MainWindow::onUpdateVideoSettings(bool glchange) diff --git a/src/frontend/qt_sdl/main.h b/src/frontend/qt_sdl/main.h index 024af8a..9d9e40e 100644 --- a/src/frontend/qt_sdl/main.h +++ b/src/frontend/qt_sdl/main.h @@ -235,6 +235,7 @@ private slots: void onEnableCheats(bool checked); void onSetupCheats(); void onCheatsDialogFinished(int res); + void onROMInfo(); void onOpenEmuSettings(); void onEmuSettingsDialogFinished(int res); @@ -310,6 +311,7 @@ public: QAction* actFrameStep; QAction* actEnableCheats; QAction* actSetupCheats; + QAction* actROMInfo; QAction* actEmuSettings; QAction* actInputConfig; |