support external patches
Before Width: | Height: | Size: 9.3 KiB After Width: | Height: | Size: 9.3 KiB |
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 10 KiB |
Before Width: | Height: | Size: 5.8 KiB After Width: | Height: | Size: 5.8 KiB |
Before Width: | Height: | Size: 3.9 KiB After Width: | Height: | Size: 3.9 KiB |
Before Width: | Height: | Size: 3.9 KiB After Width: | Height: | Size: 3.9 KiB |
Before Width: | Height: | Size: 3.0 KiB After Width: | Height: | Size: 3.0 KiB |
Before Width: | Height: | Size: 6.8 KiB After Width: | Height: | Size: 6.8 KiB |
Before Width: | Height: | Size: 5.3 KiB After Width: | Height: | Size: 5.3 KiB |
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 2.4 KiB |
Before Width: | Height: | Size: 3.0 KiB After Width: | Height: | Size: 3.0 KiB |
Before Width: | Height: | Size: 3.7 KiB After Width: | Height: | Size: 3.7 KiB |
Before Width: | Height: | Size: 9.8 KiB After Width: | Height: | Size: 9.8 KiB |
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 2.6 KiB |
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 10 KiB |
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 2.2 KiB |
Before Width: | Height: | Size: 5.4 KiB After Width: | Height: | Size: 5.4 KiB |
Before Width: | Height: | Size: 5.0 KiB After Width: | Height: | Size: 5.0 KiB |
Before Width: | Height: | Size: 4.5 KiB After Width: | Height: | Size: 4.5 KiB |
Before Width: | Height: | Size: 6.2 KiB After Width: | Height: | Size: 6.2 KiB |
Before Width: | Height: | Size: 5.6 KiB After Width: | Height: | Size: 5.6 KiB |
Before Width: | Height: | Size: 4.1 KiB After Width: | Height: | Size: 4.1 KiB |
Before Width: | Height: | Size: 7.0 KiB After Width: | Height: | Size: 7.0 KiB |
Before Width: | Height: | Size: 4.7 KiB After Width: | Height: | Size: 4.7 KiB |
Before Width: | Height: | Size: 8.8 KiB After Width: | Height: | Size: 8.8 KiB |
Before Width: | Height: | Size: 4.5 KiB After Width: | Height: | Size: 4.5 KiB |
Before Width: | Height: | Size: 5.2 KiB After Width: | Height: | Size: 5.2 KiB |
Before Width: | Height: | Size: 4.5 KiB After Width: | Height: | Size: 4.5 KiB |
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 24 KiB |
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 2.2 KiB |
Before Width: | Height: | Size: 7.0 KiB After Width: | Height: | Size: 7.0 KiB |
Before Width: | Height: | Size: 5.7 KiB After Width: | Height: | Size: 5.7 KiB |
Before Width: | Height: | Size: 7.8 KiB After Width: | Height: | Size: 7.8 KiB |
Before Width: | Height: | Size: 69 KiB After Width: | Height: | Size: 69 KiB |
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 10 KiB |
Before Width: | Height: | Size: 5.1 KiB After Width: | Height: | Size: 5.1 KiB |
Before Width: | Height: | Size: 6.7 KiB After Width: | Height: | Size: 6.7 KiB |
Before Width: | Height: | Size: 4.9 KiB After Width: | Height: | Size: 4.9 KiB |
Before Width: | Height: | Size: 3.3 KiB After Width: | Height: | Size: 3.3 KiB |
Before Width: | Height: | Size: 4.4 KiB After Width: | Height: | Size: 4.4 KiB |
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 2.0 KiB |
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 24 KiB |
Before Width: | Height: | Size: 9.5 KiB After Width: | Height: | Size: 9.5 KiB |
|
@ -1,6 +1,6 @@
|
|||
|
||||
HEADERS += src/exdeath.hh src/data.hh src/randodata.hh src/randomizer.hh src/fiesta.hh
|
||||
SOURCES += src/exdeath.cc src/main.cc src/randomizer.cc src/fiesta.cc
|
||||
HEADERS += src/exdeath.hh src/data.hh src/randodata.hh src/randomizer.hh src/fiesta.hh src/patch.hh
|
||||
SOURCES += src/exdeath.cc src/main.cc src/randomizer.cc src/fiesta.cc src/patch.cc
|
||||
RESOURCES += patches.qrc
|
||||
|
||||
CONFIG += release
|
||||
|
|
117
src/exdeath.cc
|
@ -30,6 +30,7 @@
|
|||
#include <iostream>
|
||||
|
||||
#include "exdeath.hh"
|
||||
#include "patch.hh"
|
||||
|
||||
#include <cstring>
|
||||
#include <cstdlib>
|
||||
|
@ -37,7 +38,7 @@
|
|||
#include <ctime>
|
||||
#include <climits>
|
||||
|
||||
Exdeath::Exdeath(QSettings *cfg, QWidget *parent) : QWidget(parent) {
|
||||
Exdeath::Exdeath(QSettings *cfg, QList<QPair<QString,QString> > modes, QList<QPair<QString,QString> > NEDs, QWidget *parent) : QWidget(parent) {
|
||||
error = new QErrorMessage();
|
||||
filename = nullptr;
|
||||
_cfg = cfg;
|
||||
|
@ -52,15 +53,15 @@ Exdeath::Exdeath(QSettings *cfg, QWidget *parent) : QWidget(parent) {
|
|||
layColumns->addLayout(layLeft);
|
||||
layColumns->addLayout(layRight);
|
||||
|
||||
initMain();
|
||||
initRandom();
|
||||
initMain(modes);
|
||||
initRandom(NEDs);
|
||||
initInnates();
|
||||
initMulti();
|
||||
initPreview();
|
||||
initConfig();
|
||||
|
||||
connect(btnROM, &QPushButton::clicked, this, &Exdeath::btnROM_clicked);
|
||||
connect(selMode, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &Exdeath::selMode_index);
|
||||
connect(selMode, QOverload<int>::of(&QComboBox::activated), this, &Exdeath::selMode_index);
|
||||
connect(selNED, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &Exdeath::selNED_index);
|
||||
connect(btnApply, &QPushButton::clicked, this, &Exdeath::btnApply_clicked);
|
||||
connect(btnSave, &QPushButton::clicked, this, &Exdeath::btnSave_clicked);
|
||||
|
@ -68,7 +69,7 @@ Exdeath::Exdeath(QSettings *cfg, QWidget *parent) : QWidget(parent) {
|
|||
|
||||
Exdeath::~Exdeath() {}
|
||||
|
||||
void Exdeath::initMain(void) {
|
||||
void Exdeath::initMain(QList<QPair<QString,QString> > modes) {
|
||||
layMain = new QGridLayout(this);
|
||||
grpMain = new QGroupBox("Main");
|
||||
grpMain->setLayout(layMain);
|
||||
|
@ -80,10 +81,12 @@ void Exdeath::initMain(void) {
|
|||
txtMode = new QLabel("Mode:");
|
||||
selMode = new QComboBox();
|
||||
selMode->addItem("Base");
|
||||
selMode->addItem("Ian's Balance", "Ian's Balance Patch.ips");
|
||||
selMode->addItem("Waddler Rebalance", "waddle.ips");
|
||||
selMode->addItem("Balance", "balance.ips");
|
||||
selMode->addItem("Custom Classes", "custom_classes.ips");
|
||||
|
||||
for (int i = 0; i < modes.size(); i++) {
|
||||
QPair<QString,QString> file = modes.at(i);
|
||||
|
||||
selMode->addItem(file.first, file.second);
|
||||
}
|
||||
|
||||
txtUnlock = new QLabel("Unlock Jobs:");
|
||||
chkUnlock = new QCheckBox("Yes");
|
||||
|
@ -112,7 +115,7 @@ void Exdeath::initMain(void) {
|
|||
layMain->addWidget(btnSave, 5, 1);
|
||||
}
|
||||
|
||||
void Exdeath::initRandom(void) {
|
||||
void Exdeath::initRandom(QList<QPair<QString,QString> > NEDs) {
|
||||
layRandom = new QFormLayout(this);
|
||||
grpRandom = new QGroupBox("Randomization");
|
||||
grpRandom->setLayout(layRandom);
|
||||
|
@ -128,47 +131,11 @@ void Exdeath::initRandom(void) {
|
|||
selNED->addItem("Random", "random");
|
||||
selNED->addItem("Vanilla", "vanilla");
|
||||
selNED->setCurrentIndex(1);
|
||||
selNED->addItem("Absolute Virtue", "abs_vir");
|
||||
selNED->addItem("Barf", "barf");
|
||||
selNED->addItem("Biolizard", "biolizard");
|
||||
selNED->addItem("Cactuar", "cactuar");
|
||||
selNED->addItem("Chain Chomp", "chomp");
|
||||
//selNED->addItem("Classic", "classic");
|
||||
selNED->addItem("Chaos", "chaos");
|
||||
selNED->addItem("Cloud of Darkness", "cad");
|
||||
selNED->addItem("Doomtrain", "train");
|
||||
selNED->addItem("Emperor", "emperor");
|
||||
selNED->addItem("Fat Chocobo", "NeoExChonk");
|
||||
selNED->addItem("Fiends", "fiend_ned");
|
||||
selNED->addItem("Flammie (1)", "flammie1");
|
||||
selNED->addItem("Flammie (2)", "flammie2");
|
||||
selNED->addItem("Fly", "fly");
|
||||
selNED->addItem("Godzilla", "godzilla");
|
||||
selNED->addItem("Guy Fieri", "flavortown");
|
||||
selNED->addItem("Jace", "Jace");
|
||||
selNED->addItem("Lavos Spawn", "lavos-spawn");
|
||||
selNED->addItem("Kefka", "kefka");
|
||||
selNED->addItem("Majima", "Majima");
|
||||
selNED->addItem("Majima (flipped)", "MajimaFlipped");
|
||||
selNED->addItem("MechaGodzilla", "mechagodzilla");
|
||||
selNED->addItem("Metroid", "metroid");
|
||||
selNED->addItem("Neo X Death", "neo-x-death");
|
||||
selNED->addItem("Neo ExDesert", "NeoExDesert");
|
||||
selNED->addItem("Neo ExDuck", "neoexduck");
|
||||
selNED->addItem("Neon ExDeath", "fancy");
|
||||
selNED->addItem("Nero Exdeath", "nero_exdeath");
|
||||
selNED->addItem("Omega Larboard Cannon", "omega_cannon");
|
||||
selNED->addItem("Puzzle & Dragon", "pad");
|
||||
selNED->addItem("Romancing SaGa 3 Boss", "rs3boss");
|
||||
selNED->addItem("Shaq", "shaq");
|
||||
selNED->addItem("Stupid Sexy Flanders", "flanders");
|
||||
selNED->addItem("TargetNED", "targetned");
|
||||
selNED->addItem("Territorial Oak", "tree");
|
||||
selNED->addItem("Thomas the Tank Engine", "thomas");
|
||||
selNED->addItem("Warriors of Light", "BizarroParty");
|
||||
selNED->addItem("Warriors of Light (Fiesta)", "FiestaParty");
|
||||
selNED->addItem("Yiazmat", "yiazmat");
|
||||
selNED->addItem("Zeromus", "Zeromus");
|
||||
for (int i = 0; i < NEDs.size(); i++) {
|
||||
QPair<QString,QString> file = NEDs.at(i);
|
||||
|
||||
selNED->addItem(file.first, file.second);
|
||||
}
|
||||
layRandom->addRow("Neo ExDeath:", selNED);
|
||||
|
||||
chkRandom = new QCheckBox("Yes");
|
||||
|
@ -312,40 +279,26 @@ void Exdeath::initConfig(void) {
|
|||
}
|
||||
|
||||
void Exdeath::selNED_index(int idx) {
|
||||
imgPreview = new QPixmap(":/gallery/ned/" + selNED->itemData(idx).toString() + ".png");
|
||||
QString filename = selNED->itemData(idx).toString();
|
||||
if (!filename.startsWith(":")) {
|
||||
filename.append(".png");
|
||||
}
|
||||
imgPreview = new QPixmap(filename);
|
||||
txtPreview->setPixmap(*imgPreview);
|
||||
}
|
||||
|
||||
void Exdeath::selMode_index(int idx) {
|
||||
bool random_ok = false;
|
||||
bool unlock_ok = false;
|
||||
bool innate_ok = false;
|
||||
bool sound_ok = false;
|
||||
bool ned_ok = false;
|
||||
if (idx == 0) return;
|
||||
int ret = QMessageBox::warning(
|
||||
this,
|
||||
tr("Exdeath"),
|
||||
tr("Using a mode other than Base may cause innate abilities, ability randomization, or Neo Exdeath graphic changes to break the game.\nAre you sure you want to do this?"),
|
||||
QMessageBox::Yes | QMessageBox::No
|
||||
);
|
||||
|
||||
if (idx < 3) {
|
||||
unlock_ok = true;
|
||||
innate_ok = true;
|
||||
sound_ok = true;
|
||||
ned_ok = true;
|
||||
if (ret == QMessageBox::No) {
|
||||
selMode->setCurrentIndex(0);
|
||||
}
|
||||
if (idx <= 1) {
|
||||
random_ok = true;
|
||||
}
|
||||
|
||||
chkRandom->setEnabled(random_ok);
|
||||
|
||||
chkUnlock->setEnabled(unlock_ok);
|
||||
chkSound->setEnabled(sound_ok);
|
||||
|
||||
selNED->setEnabled(ned_ok);
|
||||
|
||||
chkPassages->setEnabled(innate_ok);
|
||||
chkPitfalls->setEnabled(innate_ok);
|
||||
chkLiteStep->setEnabled(innate_ok);
|
||||
chkDash->setEnabled(innate_ok);
|
||||
chkLearning->setEnabled(innate_ok);
|
||||
innates_enabled = innate_ok;
|
||||
}
|
||||
|
||||
void Exdeath::btnSave_clicked(bool trigger) {
|
||||
|
@ -411,7 +364,11 @@ void Exdeath::btnApply_clicked(bool trigger) {
|
|||
QString output = QFileDialog::getSaveFileName(
|
||||
this,
|
||||
"Select target ROM image",
|
||||
#ifdef __WIN32__
|
||||
QApplication::applicationDirPath(),
|
||||
#else
|
||||
QStandardPaths::standardLocations(QStandardPaths::DocumentsLocation)[0],
|
||||
#endif
|
||||
"GBA ROM images (*.gba)"
|
||||
);
|
||||
QFile::copy(filename, output);
|
||||
|
@ -423,7 +380,7 @@ void Exdeath::btnApply_clicked(bool trigger) {
|
|||
patches << ":/patches/fixnames.ips";
|
||||
|
||||
if (mode > 0) {
|
||||
patches << ":/patches/" + selMode->itemData(mode).toString();
|
||||
patches << selMode->itemData(mode).toString();
|
||||
}
|
||||
if (chkUnlock->isChecked() && chkUnlock->isEnabled()) {
|
||||
patches << ":/patches/unlock.ips";
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include <QGroupBox>
|
||||
#include <QIODevice>
|
||||
#include <QLabel>
|
||||
#include <QList>
|
||||
#include <QPixmap>
|
||||
#include <QPushButton>
|
||||
#include <QRadioButton>
|
||||
|
@ -32,7 +33,7 @@
|
|||
|
||||
class Exdeath : public QWidget {
|
||||
public:
|
||||
Exdeath(QSettings *cfg, QWidget *parent = nullptr);
|
||||
Exdeath(QSettings *cfg, QList<QPair<QString,QString> > modes, QList<QPair<QString,QString> > NEDs, QWidget *parent = nullptr);
|
||||
~Exdeath();
|
||||
|
||||
private:
|
||||
|
@ -105,9 +106,9 @@ private:
|
|||
QPixmap *imgPreview;
|
||||
|
||||
// Initialization
|
||||
void initMain(void);
|
||||
void initMain(QList<QPair<QString,QString> > modes);
|
||||
void initInnates(void);
|
||||
void initRandom(void);
|
||||
void initRandom(QList<QPair<QString,QString> > NEDs);
|
||||
void initMulti(void);
|
||||
void initPreview(void);
|
||||
void initConfig(void);
|
||||
|
|
16
src/main.cc
|
@ -26,8 +26,10 @@
|
|||
*/
|
||||
|
||||
#include "exdeath.hh"
|
||||
#include "patch.hh"
|
||||
|
||||
#include <QApplication>
|
||||
#include <iostream>
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
QApplication *app = new QApplication(argc, argv);
|
||||
|
@ -35,10 +37,20 @@ int main(int argc, char **argv) {
|
|||
QApplication::setOrganizationDomain("aerdan.org");
|
||||
QApplication::setApplicationName("Exdeath");
|
||||
QApplication::setApplicationDisplayName("Exdeath");
|
||||
QApplication::setApplicationVersion("0.9.2");
|
||||
QApplication::setApplicationVersion("0.10.0");
|
||||
|
||||
#ifdef __WIN32__
|
||||
QString path = QApplication::applicationDirPath();
|
||||
#else
|
||||
QString path = QStandardPaths::standardLocations(QStandardPaths::AppDataLocation)[0];
|
||||
#endif
|
||||
QDir dir = QDir(path);
|
||||
std::cout << "Searching in" << path.toStdString() << std::endl;
|
||||
QList<QPair<QString,QString> > modes = getPatchList(dir, PatchType::Mode);
|
||||
QList<QPair<QString,QString> > NEDs = getPatchList(dir, PatchType::NED);
|
||||
|
||||
QSettings *cfg = new QSettings();
|
||||
Exdeath *win = new Exdeath(cfg);
|
||||
Exdeath *win = new Exdeath(cfg, modes, NEDs);
|
||||
|
||||
win->show();
|
||||
|
||||
|
|
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
* Copyright (c) 2023, Síle Ekaterin Liszka.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the software nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "patch.hh"
|
||||
|
||||
QList<QPair<QString,QString> > getPatchList(QDir dir, PatchType type) {
|
||||
QList<QPair<QString,QString> > list;
|
||||
|
||||
if (!dir.exists()) {
|
||||
return list;
|
||||
}
|
||||
if (type == PatchType::Mode) {
|
||||
dir.cd("modes");
|
||||
if (!dir.exists()) {
|
||||
return list;
|
||||
}
|
||||
} else if (type == PatchType::NED) {
|
||||
dir.cd("ned");
|
||||
if (!dir.exists()) {
|
||||
return list;
|
||||
}
|
||||
}
|
||||
dir.setFilter(QDir::Files | QDir::Readable);
|
||||
dir.setSorting(QDir::Name);
|
||||
|
||||
QFileInfoList files = dir.entryInfoList();
|
||||
|
||||
for (int i = 0; i < files.size(); i++) {
|
||||
QFileInfo file = files.at(i);
|
||||
|
||||
if (file.suffix() == "ips") {
|
||||
QString filename = file.canonicalPath() + "/" + file.completeBaseName() + ".ips";
|
||||
QPair<QString,QString> pair = {file.completeBaseName(), filename};
|
||||
|
||||
list.append(pair);
|
||||
}
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <QDir>
|
||||
#include <QFileInfo>
|
||||
#include <QList>
|
||||
#include <QString>
|
||||
|
||||
enum PatchType {
|
||||
Mode,
|
||||
NED,
|
||||
};
|
||||
|
||||
|
||||
QList<QPair<QString,QString> > getPatchList(QDir dir, PatchType type);
|