1
0
Fork 0
mirror of https://github.com/eliboa/TegraRcmGUI.git synced 2024-11-08 11:51:45 +00:00
TegraRcmGUI/qhekate.cpp
2020-12-11 12:46:53 +01:00

304 lines
9.2 KiB
C++

#include "tegrarcmgui.h"
#include "qhekate.h"
#include "ui_qhekate.h"
#include "qobjects/custombutton.h"
#include "qprogress_widget.h"
qHekate::qHekate(TegraRcmGUI *parent) : QWidget(parent), ui(new Ui::qHekate), parent(parent)
{
ui->setupUi(this);
m_kourou = parent->m_kourou;
m_device = &parent->m_device;
// Connect signals & slots
connect(this, SIGNAL(error(int)), parent, SLOT(error(int)));
initHekatePayload();
// Styles
ui->umsFrame->setStyleSheet(GetStyleSheetFromResFile(":/res/QFrame_box02.qss"));
ui->configFrame->setStyleSheet(GetStyleSheetFromResFile(":/res/QFrame_box02.qss"));
ui->umsLayout->setAlignment(Qt::AlignLeft);
ui->headerLayout->setAlignment(Qt::AlignLeft);
ui->configLayout->setAlignment(Qt::AlignRight);
ui->hconfigTableWidget->setColumnCount(2);
ui->hconfigTableWidget->setColumnWidth(0, 110);
ui->hconfigTableWidget->setColumnWidth(1, 120);
ui->hconfigTableWidget->horizontalScrollBar()->setStyleSheet("QScrollBar {height:0px;}");
ui->hconfigTableWidget->setStyleSheet(GetStyleSheetFromResFile(":/res/QTableWidget.qss"));
ui->hconfigTableWidget->setAlternatingRowColors(true);
// Meta types
qRegisterMetaType<nyx_ums_type>("nyx_ums_type");
// Draw boxes
drawHeader();
drawUmsBox();
/*
* TODO
* - Que faire si aucun payload ?
*
*/
}
qHekate::~qHekate()
{
delete ui;
}
bool qHekate::initHekatePayload()
{
auto hekate_pkg = parent->m_pkgs.get("Hekate");
if (!hekate_pkg || !hekate_pkg->exists() || !hekate_pkg->payload().length())
return false;
QFile payload(hekate_pkg->payload());
payload.open(QIODevice::ReadOnly);
if (!payload.isOpen())
return false;
m_hekate_payload = payload.readAll();
payload.close();
// Check nyx bin & get version
QFile nyx_bin(hekate_pkg->location() + "/bootloader/sys/nyx.bin");
nyx_bin.open(QIODevice::ReadOnly);
if (nyx_bin.isOpen())
{
nyx_bin.seek(0x99);
QString magic(nyx_bin.read(3));
if (magic == "CTC")
{
m_nyx_version.major = QString(nyx_bin.read(1)).toInt();
m_nyx_version.minor = QString(nyx_bin.read(1)).toInt();
m_nyx_version.micro = QString(nyx_bin.read(1)).toInt();
}
nyx_bin.close();
}
return true;
}
void qHekate::on_tabActivated()
{
//new WarningBox("TEST", ui->fullLayout);
}
void qHekate::on_deviceStateChange()
{
drawHeader();
drawUmsBox();
drawConfigBox();
}
void qHekate::on_deviceInfo_received()
{
drawHeader();
drawUmsBox();
}
void qHekate::drawHeader()
{
// Clear all items in layout
ClearLayout(ui->headerLayout);
auto hekate_pkg = parent->m_pkgs.get("Hekate");
// Hekate's badge
if (m_hekate_payload.size() && hekate_pkg && hekate_pkg->version().length())
{
Badge *hekate_badge = new Badge("Hekate", hekate_pkg->version(), this);
hekate_badge->setStatusTip(tr("Hekate's payload location: ") + hekate_pkg->payload());
ui->headerLayout->addWidget(hekate_badge);
}
auto di = m_device->deviceInfo();
if (!m_device->isDeviceInfoAvailable() || !di.sdmmc_initialized || !m_hekate_payload.size())
return;
// Nyx & AMS badges
AppVersion nyx_ver;
nyx_ver.major = QString(di.nyx_version[0]).toInt();
nyx_ver.minor = QString(di.nyx_version[1]).toInt();
nyx_ver.micro = QString(di.nyx_version[2]).toInt();
Badge *nyx_badge = new Badge("Nyx", !di.cbl_nyx ? "Not found" : GetAppVersionAsQString(nyx_ver), this);
ui->headerLayout->addWidget(nyx_badge);
AppVersion ams_ver;
ams_ver.major = di.ams_version[0];
ams_ver.minor = di.ams_version[1];
ams_ver.micro = di.ams_version[2];
Badge *ams_badge = new Badge("AMS", !di.cfw_ams ? "Not found" : GetAppVersionAsQString(ams_ver), this);
ui->headerLayout->addWidget(ams_badge);
// Header button lambda
auto createHeaderButton = [&](const QString& label, void(qHekate::* slotName)())
{
auto *button = new CustomButton(parent, label);
button->addEnableCondition(C_ARIANE_READY);
button->setFixedHeight(22);
button->setStyleSheet("padding: 5px;");
connect(button, &QPushButton::clicked, this, slotName);
button->setStatusTip(tr("%1 on device (i.e needed files will be copied to SD card)").arg(label));
ui->headerLayout->addWidget(button);
};
// Create buttons
createHeaderButton(tr("Install Hekate/Nyx"), &qHekate::on_hekate_install);
createHeaderButton(tr("Install AMS"), &qHekate::on_ams_install);
}
void qHekate::drawConfigBox()
{
ClearLayout(ui->configLayout);
if (!m_kourou->hekate_ini)
return;
auto cfg_list = ui->configComboBox;
auto configs = m_kourou->hekate_ini->configs()->data();
cfg_list->clear();
for (auto config : configs)
{
QVariant id = config->getValue("id");
if (id.toString().size())
cfg_list->addItem(config->name(), id);
}
if (cfg_list->count())
{
auto *button = new CustomButton(parent, "Launch config");
button->setFixedSize(100, 22);
connect(button, &QPushButton::clicked, [=]() {
emit on_launchHekateConfig();
});
button->setStatusTip(tr("Launch selected config"));
button->addEnableCondition(C_READY_FOR_PAYLOAD);
ui->configLayout->addWidget(button, 0, 0);
}
}
void qHekate::drawUmsBox()
{
// Clear all items in layout
ClearLayout(ui->umsLayout);
if (!m_device->arianeIsReady())
{
QString label(tr("Ariane needs to be loaded.\n"));
label.append(m_kourou->autoLaunchAriane ? tr("Boot device to RCM") : tr("Enable Ariane autoboot first"));
new WarningBox(label, ui->umsLayout);
return;
}
auto di = m_device->deviceInfo();
// We need available device infos + nyx installed on device + ariane loaded and ready
if (!m_device->isDeviceInfoAvailable() || !di.cbl_nyx)
return;
// UMS button lambda
auto createUmsButton = [&](const QString& storage, nyx_ums_type ums_type, int row, int col)
{
auto *button = new CustomButton(parent, storage, LIGHT);
button->setFixedSize(100, 22);
connect(button, &QPushButton::clicked, [=]() {
emit on_launchHekateUms(ums_type);
});
button->setStatusTip(tr("Mount %1 as an external hard drive").arg(storage));
ui->umsLayout->addWidget(button, row, col);
};
// Create UMS buttons
if (di.sdmmc_initialized) createUmsButton(tr("SD Card"), NYX_UMS_SD_CARD, 0, 0);
createUmsButton(tr("eMMC RAWNAND"), NYX_UMS_EMMC_GPP, 0, 1);
createUmsButton(tr("eMMC BOOT0"), NYX_UMS_EMMC_BOOT0, 0, 2);
createUmsButton(tr("eMMC BOOT1"), NYX_UMS_EMMC_BOOT1, 0, 3);
if (!di.emunand_enabled)
return;
createUmsButton(tr("EMU RAWNAND"), NYX_UMS_EMUMMC_GPP, 1, 0);
createUmsButton(tr("EMU BOOT0"), NYX_UMS_EMUMMC_BOOT0, 1, 1);
createUmsButton(tr("EMU BOOT1"), NYX_UMS_EMUMMC_BOOT0, 1, 2);
}
void qHekate::on_launchHekateUms(nyx_ums_type type)
{
if (!m_hekate_payload.size())
return;
// Clear boot config
for (int i=0x94; i < 0x105; i++)
m_hekate_payload[i] = 0;
// Set boot config
m_hekate_payload[0x97] = EXTRA_CFG_NYX_UMS;
m_hekate_payload[0x98] = type;
QtConcurrent::run(m_kourou, &QKourou::hack, (u8*)m_hekate_payload.data(), (u32)m_hekate_payload.size());
}
void qHekate::on_launchHekateConfig()
{
if (!m_hekate_payload.size())
return;
QString id = ui->configComboBox->currentData().toString();
if (!id.size())
{
parent->pushMessage(tr("No config selected"));
return;
}
// Clear boot config
for (int i=0x94; i < 0x105; i++)
m_hekate_payload[i] = 0;
// Set boot config
m_hekate_payload[0x94] = BOOT_CFG_AUTOBOOT_EN | BOOT_CFG_FROM_ID;
m_hekate_payload.replace(0x98, id.size() < 8 ? id.size() : 8, id.toLocal8Bit().constData());
QtConcurrent::run(m_kourou, &QKourou::hack, (u8*)m_hekate_payload.data(), (u32)m_hekate_payload.size());
}
void qHekate::on_hekate_install()
{
QString path = QFileInfo(m_payloads.at(0).file_path).absolutePath();
QtConcurrent::run(m_kourou, &QKourou::installSDFiles, path, false);
}
void qHekate::on_ams_install()
{
QtConcurrent::run(m_kourou, &QKourou::installSDFiles, QString("atmosphere"), true);
}
void qHekate::on_configComboBox_currentIndexChanged(int index)
{
QString id = ui->configComboBox->currentData().toString();
auto tw = ui->hconfigTableWidget;
tw->setRowCount(0);
if (!m_kourou->hekate_ini)
return;
auto config = m_kourou->hekate_ini->configs()->getConfigById(id);
if (!config)
return;
for (auto entry : config->entries())
{
tw->insertRow(tw->rowCount());
auto label_i = new QTableWidgetItem(entry.name);
label_i->setTextAlignment(Qt::AlignLeft |Qt::AlignVCenter);
label_i->setFlags(label_i->flags() ^ Qt::ItemIsEditable);
auto value_i = new QTableWidgetItem(entry.value.toString());
value_i->setTextAlignment(Qt::AlignLeft |Qt::AlignVCenter);
tw->setItem(tw->rowCount()-1, 0, label_i);
tw->setItem(tw->rowCount()-1, 1, value_i);
}
tw->resizeColumnsToContents();
}