mirror of https://github.com/mgba-emu/mgba.git
Qt: First pass at 3DS forwarder generator
This commit is contained in:
parent
2b7f5ba4d0
commit
658f4e1a34
|
@ -5,6 +5,7 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
#include "ForwarderController.h"
|
||||
|
||||
#include <QDir>
|
||||
#include <QFileInfo>
|
||||
#include <QNetworkAccessManager>
|
||||
#include <QNetworkReply>
|
||||
|
@ -16,6 +17,14 @@
|
|||
|
||||
using namespace QGBA;
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
const QChar LIST_SPLIT{';'};
|
||||
const char* SUFFIX = ".exe";
|
||||
#else
|
||||
const QChar LIST_SPLIT{':'};
|
||||
const char* SUFFIX = "";
|
||||
#endif
|
||||
|
||||
ForwarderController::ForwarderController(QObject* parent)
|
||||
: QObject(parent)
|
||||
, m_netman(new QNetworkAccessManager(this))
|
||||
|
@ -29,15 +38,36 @@ ForwarderController::ForwarderController(QObject* parent)
|
|||
});
|
||||
}
|
||||
|
||||
void ForwarderController::setGenerator(std::unique_ptr<ForwarderGenerator>&& generator) {
|
||||
m_generator = std::move(generator);
|
||||
connect(m_generator.get(), &ForwarderGenerator::buildFailed, this, &ForwarderController::buildFailed);
|
||||
connect(m_generator.get(), &ForwarderGenerator::buildFailed, this, &ForwarderController::cleanup);
|
||||
connect(m_generator.get(), &ForwarderGenerator::buildComplete, this, &ForwarderController::buildComplete);
|
||||
connect(m_generator.get(), &ForwarderGenerator::buildComplete, this, &ForwarderController::cleanup);
|
||||
}
|
||||
|
||||
void ForwarderController::startBuild(const QString& outFilename) {
|
||||
if (m_inProgress) {
|
||||
return;
|
||||
}
|
||||
m_inProgress = true;
|
||||
m_outFilename = outFilename;
|
||||
|
||||
QStringList neededTools = m_generator->externalTools();
|
||||
for (const auto& tool : neededTools) {
|
||||
if (!toolInstalled(tool)) {
|
||||
downloadForwarderKit();
|
||||
return;
|
||||
}
|
||||
}
|
||||
downloadManifest();
|
||||
}
|
||||
|
||||
void ForwarderController::downloadForwarderKit() {
|
||||
// TODO
|
||||
emit buildFailed();
|
||||
}
|
||||
|
||||
void ForwarderController::downloadManifest() {
|
||||
QNetworkReply* reply = m_netman->get(QNetworkRequest(QUrl("https://mgba.io/latest.ini")));
|
||||
connect(reply, &QNetworkReply::finished, this, [this, reply]() {
|
||||
|
@ -109,10 +139,21 @@ void ForwarderController::gotBuild(QNetworkReply* reply) {
|
|||
QByteArray data = reply->readAll();
|
||||
m_sourceFile.write(data);
|
||||
m_sourceFile.close();
|
||||
if (!m_generator->rebuild(m_sourceFile.fileName(), m_outFilename)) {
|
||||
emit buildFailed();
|
||||
} else {
|
||||
emit buildComplete();
|
||||
}
|
||||
m_generator->rebuild(m_sourceFile.fileName(), m_outFilename);
|
||||
}
|
||||
|
||||
void ForwarderController::cleanup() {
|
||||
m_sourceFile.remove();
|
||||
}
|
||||
|
||||
bool ForwarderController::toolInstalled(const QString& tool) {
|
||||
QByteArray arr = qgetenv("PATH");
|
||||
QStringList path = QString::fromUtf8(arr).split(LIST_SPLIT);
|
||||
for (QDir dir : path) {
|
||||
QFileInfo exe(dir, tool + SUFFIX);
|
||||
if (exe.isExecutable()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@ Q_OBJECT
|
|||
public:
|
||||
ForwarderController(QObject* parent = nullptr);
|
||||
|
||||
void setGenerator(std::unique_ptr<ForwarderGenerator>&& generator) { m_generator = std::move(generator); }
|
||||
void setGenerator(std::unique_ptr<ForwarderGenerator>&& generator);
|
||||
ForwarderGenerator* generator() { return m_generator.get(); }
|
||||
|
||||
QString channel() const { return m_channel; }
|
||||
|
@ -40,8 +40,11 @@ private slots:
|
|||
void gotBuild(QNetworkReply*);
|
||||
|
||||
private:
|
||||
void downloadForwarderKit();
|
||||
void downloadManifest();
|
||||
void downloadBuild(const QUrl&);
|
||||
bool toolInstalled(const QString& tool);
|
||||
void cleanup();
|
||||
|
||||
QString m_channel{"dev"};
|
||||
QString m_outFilename;
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include <QImage>
|
||||
#include <QObject>
|
||||
#include <QString>
|
||||
#include <QStringList>
|
||||
#include <QVector>
|
||||
|
||||
#include <memory>
|
||||
|
@ -41,9 +42,15 @@ public:
|
|||
QString systemName() const { return systemName(system()); }
|
||||
virtual QString extension() const = 0;
|
||||
|
||||
virtual QStringList externalTools() const { return {}; }
|
||||
|
||||
static QString systemName(System);
|
||||
|
||||
virtual bool rebuild(const QString& source, const QString& target) = 0;
|
||||
virtual void rebuild(const QString& source, const QString& target) = 0;
|
||||
|
||||
signals:
|
||||
void buildComplete();
|
||||
void buildFailed();
|
||||
|
||||
protected:
|
||||
ForwarderGenerator(int imageTypes, QObject* parent = nullptr);
|
||||
|
|
|
@ -5,11 +5,27 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
#include "ForwarderGenerator3DS.h"
|
||||
|
||||
#include "ConfigController.h"
|
||||
#include "utils.h"
|
||||
#include "VFileDevice.h"
|
||||
|
||||
#include <QDir>
|
||||
#include <QFile>
|
||||
#include <QFileInfo>
|
||||
#include <QProcess>
|
||||
|
||||
#include <mgba/core/version.h>
|
||||
#include <mgba-util/vfs.h>
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
using namespace QGBA;
|
||||
|
||||
ForwarderGenerator3DS::ForwarderGenerator3DS()
|
||||
: ForwarderGenerator(2)
|
||||
{
|
||||
connect(this, &ForwarderGenerator::buildFailed, this, &ForwarderGenerator3DS::cleanup);
|
||||
connect(this, &ForwarderGenerator::buildComplete, this, &ForwarderGenerator3DS::cleanup);
|
||||
}
|
||||
|
||||
QList<QPair<QString, QSize>> ForwarderGenerator3DS::imageTypes() const {
|
||||
|
@ -19,6 +35,333 @@ QList<QPair<QString, QSize>> ForwarderGenerator3DS::imageTypes() const {
|
|||
};
|
||||
}
|
||||
|
||||
bool ForwarderGenerator3DS::rebuild(const QString& source, const QString& target) {
|
||||
return false;
|
||||
void ForwarderGenerator3DS::rebuild(const QString& source, const QString& target) {
|
||||
m_cia = dumpCia(source);
|
||||
if (m_cia.isNull()) {
|
||||
emit buildFailed();
|
||||
return;
|
||||
}
|
||||
|
||||
m_target = target;
|
||||
extractCia();
|
||||
}
|
||||
|
||||
QString ForwarderGenerator3DS::dumpCia(const QString& archive) {
|
||||
VDir* inArchive = VFileDevice::openArchive(archive);
|
||||
if (!inArchive) {
|
||||
return {};
|
||||
}
|
||||
bool gotFile = extractMatchingFile(inArchive, [](VDirEntry* dirent) -> QString {
|
||||
if (dirent->type(dirent) != VFS_FILE) {
|
||||
return {};
|
||||
}
|
||||
QString filename(dirent->name(dirent));
|
||||
if (!filename.endsWith(".cia")) {
|
||||
return {};
|
||||
}
|
||||
return "tmp.cia";
|
||||
});
|
||||
inArchive->close(inArchive);
|
||||
|
||||
if (gotFile) {
|
||||
return QLatin1String("tmp.cia");
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
void ForwarderGenerator3DS::extractCia() {
|
||||
m_currentProc = std::make_unique<QProcess>();
|
||||
m_currentProc->setProgram("ctrtool");
|
||||
|
||||
QStringList args;
|
||||
args << QLatin1String("--contents=%0/cxi").arg(ConfigController::cacheDir());
|
||||
args << m_cia;
|
||||
m_currentProc->setArguments(args);
|
||||
|
||||
connect(m_currentProc.get(), qOverload<int, QProcess::ExitStatus>(&QProcess::finished), this, &ForwarderGenerator3DS::extractCxi);
|
||||
m_currentProc->start(QIODevice::ReadOnly);
|
||||
}
|
||||
|
||||
void ForwarderGenerator3DS::extractCxi() {
|
||||
QStringList output = QString::fromUtf8(m_currentProc->readAll()).split("\n");
|
||||
QString index;
|
||||
for (const QString& line : output) {
|
||||
if (!line.contains("|- ContentId:")) {
|
||||
continue;
|
||||
}
|
||||
index = line.trimmed().right(8);
|
||||
}
|
||||
m_cxi = ConfigController::cacheDir() + "/cxi.0000." + index;
|
||||
|
||||
m_currentProc = std::make_unique<QProcess>();
|
||||
m_currentProc->setProgram("3dstool");
|
||||
|
||||
QStringList args;
|
||||
init3dstoolArgs(args, m_cxi);
|
||||
args << "--exh" << ConfigController::cacheDir() + "/exheader.bin";
|
||||
args << "--header" << ConfigController::cacheDir() + "/header.bin";
|
||||
args << "--exefs" << ConfigController::cacheDir() + "/exefs.bin";
|
||||
m_currentProc->setArguments(args);
|
||||
|
||||
connect(m_currentProc.get(), qOverload<int, QProcess::ExitStatus>(&QProcess::finished), this, &ForwarderGenerator3DS::extractExefs);
|
||||
m_currentProc->start(QIODevice::ReadOnly);
|
||||
}
|
||||
|
||||
void ForwarderGenerator3DS::extractExefs() {
|
||||
m_currentProc = std::make_unique<QProcess>();
|
||||
m_currentProc->setProgram("3dstool");
|
||||
|
||||
QStringList args;
|
||||
init3dstoolArgs(args, ConfigController::cacheDir() + "/exefs.bin");
|
||||
args << "--header" << ConfigController::cacheDir() + "/exeheader.bin";
|
||||
args << "--exefs-dir" << ConfigController::cacheDir() + "/exefs";
|
||||
m_currentProc->setArguments(args);
|
||||
|
||||
connect(m_currentProc.get(), qOverload<int, QProcess::ExitStatus>(&QProcess::finished), this, &ForwarderGenerator3DS::processCxi);
|
||||
m_currentProc->start(QIODevice::ReadOnly);
|
||||
}
|
||||
|
||||
void ForwarderGenerator3DS::processCxi() {
|
||||
QByteArray hash = hashRom();
|
||||
QByteArray tid = hash.left(4);
|
||||
quint32 tidNum;
|
||||
LOAD_32LE(tidNum, 0, tid.data());
|
||||
tidNum &= 0x7FFFFFF;
|
||||
tidNum += 0x0300000;
|
||||
STORE_32LE(tidNum, 0, tid.data());
|
||||
|
||||
QFile header(ConfigController::cacheDir() + "/header.bin");
|
||||
if (!header.open(QIODevice::ReadWrite | QIODevice::ExistingOnly)) {
|
||||
emit buildFailed();
|
||||
return;
|
||||
}
|
||||
header.seek(0x108);
|
||||
header.write(tid);
|
||||
header.seek(0x118);
|
||||
header.write(tid);
|
||||
|
||||
QByteArray productCode("MGBA-");
|
||||
productCode += base36(hash, 11).toLatin1();
|
||||
header.seek(0x150);
|
||||
header.write(productCode);
|
||||
|
||||
header.seek(0x18D);
|
||||
QByteArray type = header.read(3);
|
||||
type[0] = type[0] | 1; // Has romfs
|
||||
type[2] = type[2] & ~2; // Can mount romfs
|
||||
header.seek(0x18D);
|
||||
header.write(type);
|
||||
header.close();
|
||||
|
||||
QFile exheader(ConfigController::cacheDir() + "/exheader.bin");
|
||||
if (!exheader.open(QIODevice::ReadWrite | QIODevice::ExistingOnly)) {
|
||||
emit buildFailed();
|
||||
return;
|
||||
}
|
||||
exheader.seek(0x1C8);
|
||||
exheader.write(tid);
|
||||
exheader.seek(0x200);
|
||||
exheader.write(tid);
|
||||
exheader.seek(0x600);
|
||||
exheader.write(tid);
|
||||
exheader.close();
|
||||
|
||||
prepareRomfs();
|
||||
}
|
||||
|
||||
void ForwarderGenerator3DS::prepareRomfs() {
|
||||
QDir romfsDir(ConfigController::cacheDir());
|
||||
|
||||
romfsDir.mkdir("romfs");
|
||||
romfsDir.cd("romfs");
|
||||
|
||||
QFileInfo info(rom());
|
||||
QByteArray buffer(info.fileName().toUtf8());
|
||||
QFile filename(romfsDir.filePath("filename"));
|
||||
if (!filename.open(QIODevice::Truncate | QIODevice::WriteOnly)) {
|
||||
emit buildFailed();
|
||||
return;
|
||||
}
|
||||
if (filename.write(buffer) != filename.size()) {
|
||||
emit buildFailed();
|
||||
return;
|
||||
}
|
||||
filename.close();
|
||||
|
||||
if (!QFile::copy(info.filePath(), romfsDir.filePath(info.fileName()))) {
|
||||
emit buildFailed();
|
||||
return;
|
||||
}
|
||||
|
||||
buildRomfs();
|
||||
}
|
||||
|
||||
void ForwarderGenerator3DS::buildRomfs() {
|
||||
m_currentProc = std::make_unique<QProcess>();
|
||||
m_currentProc->setProgram("3dstool");
|
||||
|
||||
QStringList args;
|
||||
init3dstoolArgs(args, ConfigController::cacheDir() + "/romfs.bin", "romfs");
|
||||
args << "--romfs-dir";
|
||||
args << ConfigController::cacheDir() + "/romfs";
|
||||
m_currentProc->setArguments(args);
|
||||
|
||||
connect(m_currentProc.get(), qOverload<int, QProcess::ExitStatus>(&QProcess::finished), this, &ForwarderGenerator3DS::buildSmdh);
|
||||
m_currentProc->start(QIODevice::NotOpen);
|
||||
}
|
||||
|
||||
void ForwarderGenerator3DS::buildSmdh() {
|
||||
m_currentProc = std::make_unique<QProcess>();
|
||||
m_currentProc->setProgram("bannertool");
|
||||
|
||||
if (image(0).isNull()) {
|
||||
QFile::copy(":/res/mgba-48.png", ConfigController::cacheDir() + "/smdh.png");
|
||||
} else {
|
||||
image(0).save(ConfigController::cacheDir() + "/smdh.png", "PNG");
|
||||
}
|
||||
|
||||
QStringList args;
|
||||
args << "makesmdh";
|
||||
|
||||
args << "-s" << title();
|
||||
args << "-l" << title();
|
||||
args << "-p" << projectName + QString(" Forwarder");
|
||||
args << "-i" << ConfigController::cacheDir() + "/smdh.png";
|
||||
args << "-o" << ConfigController::cacheDir() + "/exefs/icon.icn";
|
||||
m_currentProc->setArguments(args);
|
||||
|
||||
if (image(1).isNull()) {
|
||||
connect(m_currentProc.get(), qOverload<int, QProcess::ExitStatus>(&QProcess::finished), this, &ForwarderGenerator3DS::buildExefs);
|
||||
} else {
|
||||
connect(m_currentProc.get(), qOverload<int, QProcess::ExitStatus>(&QProcess::finished), this, &ForwarderGenerator3DS::buildBanner);
|
||||
}
|
||||
m_currentProc->start(QIODevice::ReadOnly);
|
||||
}
|
||||
|
||||
void ForwarderGenerator3DS::buildBanner() {
|
||||
QFile banner(ConfigController::cacheDir() + "/exefs/banner.bnr");
|
||||
if (!banner.open(QIODevice::ReadOnly)) {
|
||||
emit buildFailed();
|
||||
return;
|
||||
}
|
||||
|
||||
banner.seek(0x84);
|
||||
QByteArray bcwavOffsetBuffer(banner.read(4));
|
||||
qint64 bcwavOffset;
|
||||
LOAD_64LE(bcwavOffset, 0, bcwavOffsetBuffer.data());
|
||||
banner.seek(bcwavOffset);
|
||||
QByteArray bcwav(banner.readAll());
|
||||
QFile bcwavFile(ConfigController::cacheDir() + "/banner.bcwav");
|
||||
if (!bcwavFile.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
|
||||
emit buildFailed();
|
||||
return;
|
||||
}
|
||||
bcwavFile.write(bcwav);
|
||||
banner.close();
|
||||
|
||||
m_currentProc = std::make_unique<QProcess>();
|
||||
m_currentProc->setProgram("bannertool");
|
||||
|
||||
image(1).save(ConfigController::cacheDir() + "/banner.png", "PNG");
|
||||
|
||||
QStringList args;
|
||||
args << "makebanner";
|
||||
|
||||
args << "-i" << ConfigController::cacheDir() + "/banner.png";
|
||||
args << "-ca" << ConfigController::cacheDir() + "/banner.bcwav";
|
||||
args << "-o" << ConfigController::cacheDir() + "/exefs/banner.bnr";
|
||||
m_currentProc->setArguments(args);
|
||||
|
||||
connect(m_currentProc.get(), qOverload<int, QProcess::ExitStatus>(&QProcess::finished), this, &ForwarderGenerator3DS::buildExefs);
|
||||
m_currentProc->start(QIODevice::ReadOnly);
|
||||
}
|
||||
|
||||
void ForwarderGenerator3DS::buildExefs() {
|
||||
QByteArray out = m_currentProc->readAll();
|
||||
qDebug() << out;
|
||||
m_currentProc = std::make_unique<QProcess>();
|
||||
m_currentProc->setProgram("3dstool");
|
||||
|
||||
QStringList args;
|
||||
init3dstoolArgs(args, ConfigController::cacheDir() + "/exefs.bin", "exefs");
|
||||
args << "--header" << ConfigController::cacheDir() + "/exeheader.bin";
|
||||
args << "--exefs-dir" << ConfigController::cacheDir() + "/exefs";
|
||||
m_currentProc->setArguments(args);
|
||||
|
||||
connect(m_currentProc.get(), qOverload<int, QProcess::ExitStatus>(&QProcess::finished), this, &ForwarderGenerator3DS::buildCxi);
|
||||
m_currentProc->start(QIODevice::NotOpen);
|
||||
}
|
||||
|
||||
void ForwarderGenerator3DS::buildCxi() {
|
||||
m_currentProc = std::make_unique<QProcess>();
|
||||
m_currentProc->setProgram("3dstool");
|
||||
|
||||
QFile cxi(m_cxi);
|
||||
cxi.remove();
|
||||
|
||||
QStringList args;
|
||||
init3dstoolArgs(args, m_cxi, "cxi");
|
||||
args << "--exh" << ConfigController::cacheDir() + "/exheader.bin";
|
||||
args << "--header" << ConfigController::cacheDir() + "/header.bin";
|
||||
args << "--exefs" << ConfigController::cacheDir() + "/exefs.bin";
|
||||
args << "--romfs" << ConfigController::cacheDir() + "/romfs.bin";
|
||||
m_currentProc->setArguments(args);
|
||||
|
||||
connect(m_currentProc.get(), qOverload<int, QProcess::ExitStatus>(&QProcess::finished), this, &ForwarderGenerator3DS::buildCia);
|
||||
m_currentProc->start(QIODevice::NotOpen);
|
||||
}
|
||||
|
||||
void ForwarderGenerator3DS::buildCia() {
|
||||
m_currentProc = std::make_unique<QProcess>();
|
||||
m_currentProc->setProgram("makerom");
|
||||
|
||||
QStringList args;
|
||||
args << "-f" << "cia";
|
||||
args << "-o" << m_target;
|
||||
args << "-content" << m_cxi + ":0:0";
|
||||
m_currentProc->setArguments(args);
|
||||
|
||||
connect(m_currentProc.get(), qOverload<int, QProcess::ExitStatus>(&QProcess::finished), this, &ForwarderGenerator3DS::buildComplete);
|
||||
m_currentProc->start(QIODevice::NotOpen);
|
||||
}
|
||||
|
||||
void ForwarderGenerator3DS::cleanup() {
|
||||
for (const QString& path : {m_cia, m_cxi}) {
|
||||
QFile file(path);
|
||||
if (file.exists()) {
|
||||
file.remove();
|
||||
}
|
||||
}
|
||||
|
||||
QDir cacheDir(ConfigController::cacheDir());
|
||||
QStringList files{
|
||||
"romfs.bin",
|
||||
"exefs.bin",
|
||||
"exheader.bin",
|
||||
"exeheader.bin",
|
||||
"header.bin",
|
||||
"smdh.png",
|
||||
"banner.png",
|
||||
"banner.bcwav",
|
||||
};
|
||||
for (QString path : files) {
|
||||
QFile file(cacheDir.filePath(path));
|
||||
if (file.exists()) {
|
||||
file.remove();
|
||||
}
|
||||
}
|
||||
|
||||
for (QString path : {"romfs", "exefs"}) {
|
||||
QDir dir(cacheDir.filePath(path));
|
||||
dir.removeRecursively();
|
||||
}
|
||||
}
|
||||
|
||||
void ForwarderGenerator3DS::init3dstoolArgs(QStringList& args, const QString& file, const QString& createType) {
|
||||
if (createType.isEmpty()) {
|
||||
args << "-xf" << file;
|
||||
} else {
|
||||
args << "-cf" << file;
|
||||
args << "-t" << createType;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,6 +7,10 @@
|
|||
|
||||
#include "ForwarderGenerator.h"
|
||||
|
||||
#include <QProcess>
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace QGBA {
|
||||
|
||||
class ForwarderGenerator3DS final : public ForwarderGenerator {
|
||||
|
@ -19,7 +23,33 @@ public:
|
|||
System system() const override { return System::N3DS; }
|
||||
QString extension() const override { return QLatin1String("cia"); }
|
||||
|
||||
bool rebuild(const QString& source, const QString& target) override;
|
||||
virtual QStringList externalTools() const { return {"bannertool", "3dstool", "ctrtool", "makerom"}; }
|
||||
|
||||
void rebuild(const QString& source, const QString& target) override;
|
||||
|
||||
private slots:
|
||||
void extractCia();
|
||||
void extractCxi();
|
||||
void extractExefs();
|
||||
void processCxi();
|
||||
void prepareRomfs();
|
||||
void buildRomfs();
|
||||
void buildSmdh();
|
||||
void buildBanner();
|
||||
void buildExefs();
|
||||
void buildCxi();
|
||||
void buildCia();
|
||||
|
||||
void cleanup();
|
||||
|
||||
private:
|
||||
QString dumpCia(const QString& archive);
|
||||
void init3dstoolArgs(QStringList& args, const QString& file, const QString& createType = {});
|
||||
|
||||
std::unique_ptr<QProcess> m_currentProc;
|
||||
QString m_cia;
|
||||
QString m_cxi;
|
||||
QString m_target;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -29,10 +29,11 @@ QList<QPair<QString, QSize>> ForwarderGeneratorVita::imageTypes() const {
|
|||
};
|
||||
}
|
||||
|
||||
bool ForwarderGeneratorVita::rebuild(const QString& source, const QString& target) {
|
||||
void ForwarderGeneratorVita::rebuild(const QString& source, const QString& target) {
|
||||
QString vpk = dumpVpk(source);
|
||||
if (vpk.isNull()) {
|
||||
return false;
|
||||
emit buildFailed();
|
||||
return;
|
||||
}
|
||||
|
||||
QFile vpkFile(vpk);
|
||||
|
@ -43,7 +44,8 @@ bool ForwarderGeneratorVita::rebuild(const QString& source, const QString& targe
|
|||
}
|
||||
vpkFile.remove();
|
||||
if (!outdir) {
|
||||
return false;
|
||||
emit buildFailed();
|
||||
return;
|
||||
}
|
||||
|
||||
VFile* sfo = outdir->openFile(outdir, "sce_sys/param.sfo", O_WRONLY);
|
||||
|
@ -74,7 +76,7 @@ bool ForwarderGeneratorVita::rebuild(const QString& source, const QString& targe
|
|||
|
||||
outdir->close(outdir);
|
||||
|
||||
return true;
|
||||
emit buildComplete();
|
||||
}
|
||||
|
||||
QString ForwarderGeneratorVita::dumpVpk(const QString& archive) {
|
||||
|
|
|
@ -22,7 +22,7 @@ public:
|
|||
System system() const override { return System::VITA; }
|
||||
QString extension() const override { return QLatin1String("vpk"); }
|
||||
|
||||
bool rebuild(const QString& source, const QString& target) override;
|
||||
void rebuild(const QString& source, const QString& target) override;
|
||||
|
||||
private:
|
||||
QString dumpVpk(const QString& archive);
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
<qresource>
|
||||
<file>../../../res/mgba-1024.png</file>
|
||||
<file>../../../res/mgba-256.png</file>
|
||||
<file>../../../res/mgba-48.png</file>
|
||||
<file>../../../res/keymap.qpic</file>
|
||||
<file>../../../res/patrons.txt</file>
|
||||
<file>../../../res/no-cam.png</file>
|
||||
|
|
Loading…
Reference in New Issue