From cc214e0f44b51498bf2fc6db21909b1bbf12d733 Mon Sep 17 00:00:00 2001 From: Jeffrey Pfau Date: Sun, 15 Feb 2015 04:52:21 -0800 Subject: [PATCH] GBA: Cheat saving --- src/gba/cheats.c | 56 +++++++++++++++++++++++++++++++++ src/gba/cheats.h | 2 ++ src/platform/qt/CheatsModel.cpp | 9 ++++++ src/platform/qt/CheatsModel.h | 2 ++ src/platform/qt/CheatsView.cpp | 8 +++++ src/platform/qt/CheatsView.h | 1 + src/platform/qt/CheatsView.ui | 3 -- 7 files changed, 78 insertions(+), 3 deletions(-) diff --git a/src/gba/cheats.c b/src/gba/cheats.c index f400c3444..2a34f06d2 100644 --- a/src/gba/cheats.c +++ b/src/gba/cheats.c @@ -695,6 +695,7 @@ bool GBACheatParseFile(struct GBACheatDevice* device, struct VFile* vf) { 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 @@ bool GBACheatParseFile(struct GBACheatDevice* device, struct VFile* vf) { 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 @@ bool GBACheatParseFile(struct GBACheatDevice* device, struct VFile* vf) { } else { _setGameSharkVersion(newSet, gsaVersion); } + reset = false; set = newSet; break; case '!': @@ -742,6 +746,10 @@ bool GBACheatParseFile(struct GBACheatDevice* device, struct VFile* vf) { nextDisabled = true; break; } + if (strcasecmp(&cheat[i], "reset") == 0) { + reset = true; + break; + } break; default: if (!set) { @@ -761,6 +769,54 @@ bool GBACheatParseFile(struct GBACheatDevice* device, struct VFile* vf) { 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; +} + bool GBACheatAddLine(struct GBACheatSet* cheats, const char* line) { uint32_t op1; uint16_t op2; diff --git a/src/gba/cheats.h b/src/gba/cheats.h index a2cdfae28..257791a1a 100644 --- a/src/gba/cheats.h +++ b/src/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*); diff --git a/src/platform/qt/CheatsModel.cpp b/src/platform/qt/CheatsModel.cpp index 572b6fdcd..4996582f2 100644 --- a/src/platform/qt/CheatsModel.cpp +++ b/src/platform/qt/CheatsModel.cpp @@ -176,6 +176,15 @@ void CheatsModel::loadFile(const QString& path) { 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); diff --git a/src/platform/qt/CheatsModel.h b/src/platform/qt/CheatsModel.h index 5a0690c4c..a1503ce1d 100644 --- a/src/platform/qt/CheatsModel.h +++ b/src/platform/qt/CheatsModel.h @@ -36,6 +36,8 @@ public: void endAppendRow(); void loadFile(const QString& path); + void saveFile(const QString& path); + void addSet(GBACheatSet* set); public slots: diff --git a/src/platform/qt/CheatsView.cpp b/src/platform/qt/CheatsView.cpp index 900f1eaaa..24bb77c8f 100644 --- a/src/platform/qt/CheatsView.cpp +++ b/src/platform/qt/CheatsView.cpp @@ -25,6 +25,7 @@ CheatsView::CheatsView(GameController* controller, QWidget* parent) 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())); @@ -49,6 +50,13 @@ void CheatsView::load() { } } +void CheatsView::save() { + QString filename = QFileDialog::getSaveFileName(this, tr("Select cheats file")); + if (!filename.isEmpty()) { + m_model.saveFile(filename); + } +} + void CheatsView::addSet() { GBACheatSet* set = new GBACheatSet; GBACheatSetInit(set, nullptr); diff --git a/src/platform/qt/CheatsView.h b/src/platform/qt/CheatsView.h index 14686f2ea..d81b58c21 100644 --- a/src/platform/qt/CheatsView.h +++ b/src/platform/qt/CheatsView.h @@ -28,6 +28,7 @@ public: private slots: void load(); + void save(); void addSet(); void removeSet(); diff --git a/src/platform/qt/CheatsView.ui b/src/platform/qt/CheatsView.ui index 49de41e4a..b5a1afdc0 100644 --- a/src/platform/qt/CheatsView.ui +++ b/src/platform/qt/CheatsView.ui @@ -68,9 +68,6 @@ - - false - Save