all repos — mgba @ cc214e0f44b51498bf2fc6db21909b1bbf12d733

mGBA Game Boy Advance Emulator

GBA: Cheat saving
Jeffrey Pfau jeffrey@endrift.com
Sun, 15 Feb 2015 04:52:21 -0800
commit

cc214e0f44b51498bf2fc6db21909b1bbf12d733

parent

bc8175515bca1df94785300cd2de41a6f2495a29

M src/gba/cheats.csrc/gba/cheats.c

@@ -695,6 +695,7 @@ struct GBACheatSet* set = 0;

struct GBACheatSet* newSet; int gsaVersion = 0; bool nextDisabled = false; + bool reset = false; while (true) { size_t i = 0; ssize_t bytesRead = vf->readline(vf, cheat, sizeof(cheat));

@@ -718,6 +719,8 @@ newSet->enabled = !nextDisabled;

nextDisabled = false; if (set) { GBACheatAddSet(device, set); + } + if (set && !reset) { newSet->gsaVersion = set->gsaVersion; memcpy(newSet->gsaSeeds, set->gsaSeeds, sizeof(newSet->gsaSeeds)); if (set->hook) {

@@ -727,6 +730,7 @@ }

} else { _setGameSharkVersion(newSet, gsaVersion); } + reset = false; set = newSet; break; case '!':

@@ -742,6 +746,10 @@ if (strcasecmp(&cheat[i], "disabled") == 0) {

nextDisabled = true; break; } + if (strcasecmp(&cheat[i], "reset") == 0) { + reset = true; + break; + } break; default: if (!set) {

@@ -757,6 +765,54 @@ }

} if (set) { GBACheatAddSet(device, set); + } + return true; +} + +bool GBACheatSaveFile(struct GBACheatDevice* device, struct VFile* vf) { + static const char lineStart[3] = "# "; + static const char lineEnd = '\n'; + + struct GBACheatHook* lastHook = 0; + + size_t i; + for (i = 0; i < GBACheatSetsSize(&device->cheats); ++i) { + struct GBACheatSet* set = *GBACheatSetsGetPointer(&device->cheats, i); + if (lastHook && set->hook != lastHook) { + static const char* resetDirective = "!reset\n"; + vf->write(vf, resetDirective, strlen(resetDirective)); + } + switch (set->gsaVersion) { + case 1: { + static const char* versionDirective = "!GSAv1\n"; + vf->write(vf, versionDirective, strlen(versionDirective)); + break; + } + case 3: { + static const char* versionDirective = "!PARv3\n"; + vf->write(vf, versionDirective, strlen(versionDirective)); + break; + } + default: + break; + } + lastHook = set->hook; + if (!set->enabled) { + static const char* disabledDirective = "!disabled\n"; + vf->write(vf, disabledDirective, strlen(disabledDirective)); + } + + vf->write(vf, lineStart, 2); + if (set->name) { + vf->write(vf, set->name, strlen(set->name)); + } + vf->write(vf, &lineEnd, 1); + size_t c; + for (c = 0; c < StringListSize(&set->lines); ++c) { + const char* line = *StringListGetPointer(&set->lines, c); + vf->write(vf, line, strlen(line)); + vf->write(vf, &lineEnd, 1); + } } return true; }
M src/gba/cheats.hsrc/gba/cheats.h

@@ -199,6 +199,8 @@ bool GBACheatAddAutodetect(struct GBACheatSet*, uint32_t op1, uint32_t op2);

bool GBACheatAddAutodetectLine(struct GBACheatSet*, const char* line); bool GBACheatParseFile(struct GBACheatDevice*, struct VFile*); +bool GBACheatSaveFile(struct GBACheatDevice*, struct VFile*); + bool GBACheatAddLine(struct GBACheatSet*, const char* line); void GBACheatRefresh(struct GBACheatDevice*, struct GBACheatSet*);
M src/platform/qt/CheatsModel.cppsrc/platform/qt/CheatsModel.cpp

@@ -176,6 +176,15 @@ endResetModel();

vf->close(vf); } +void CheatsModel::saveFile(const QString& path) { + VFile* vf = VFileOpen(path.toLocal8Bit().constData(), O_TRUNC | O_CREAT | O_WRONLY); + if (!vf) { + return; + } + GBACheatSaveFile(m_device, vf); + vf->close(vf); +} + void CheatsModel::addSet(GBACheatSet* set) { beginInsertRows(QModelIndex(), GBACheatSetsSize(&m_device->cheats), GBACheatSetsSize(&m_device->cheats)); GBACheatAddSet(m_device, set);
M src/platform/qt/CheatsModel.hsrc/platform/qt/CheatsModel.h

@@ -36,6 +36,8 @@ void beginAppendRow(const QModelIndex& index);

void endAppendRow(); void loadFile(const QString& path); + void saveFile(const QString& path); + void addSet(GBACheatSet* set); public slots:
M src/platform/qt/CheatsView.cppsrc/platform/qt/CheatsView.cpp

@@ -25,6 +25,7 @@

m_ui.cheatList->setModel(&m_model); connect(m_ui.load, SIGNAL(clicked()), this, SLOT(load())); + connect(m_ui.save, SIGNAL(clicked()), this, SLOT(save())); connect(m_ui.addSet, SIGNAL(clicked()), this, SLOT(addSet())); connect(m_ui.remove, SIGNAL(clicked()), this, SLOT(removeSet())); connect(controller, SIGNAL(gameStopped(GBAThread*)), &m_model, SLOT(invalidated()));

@@ -46,6 +47,13 @@ void CheatsView::load() {

QString filename = QFileDialog::getOpenFileName(this, tr("Select cheats file")); if (!filename.isEmpty()) { m_model.loadFile(filename); + } +} + +void CheatsView::save() { + QString filename = QFileDialog::getSaveFileName(this, tr("Select cheats file")); + if (!filename.isEmpty()) { + m_model.saveFile(filename); } }
M src/platform/qt/CheatsView.hsrc/platform/qt/CheatsView.h

@@ -28,6 +28,7 @@ CheatsView(GameController* controller, QWidget* parent = nullptr);

private slots: void load(); + void save(); void addSet(); void removeSet();
M src/platform/qt/CheatsView.uisrc/platform/qt/CheatsView.ui

@@ -68,9 +68,6 @@ </widget>

</item> <item row="1" column="2"> <widget class="QPushButton" name="save"> - <property name="enabled"> - <bool>false</bool> - </property> <property name="text"> <string>Save</string> </property>