From affe5e31a786e39122d932cc9f38e0e3cb643749 Mon Sep 17 00:00:00 2001 From: Jeffrey Pfau Date: Fri, 19 Aug 2016 05:13:37 -0700 Subject: [PATCH] All: Restore cheat loading/saving --- src/core/cheats.c | 51 +++++++++++++++++++++++++++++++++-------------- src/core/cheats.h | 3 +++ src/gb/cheats.c | 15 ++++++++++++++ src/gba/cheats.c | 44 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 98 insertions(+), 15 deletions(-) diff --git a/src/core/cheats.c b/src/core/cheats.c index 466a12ddc..617dbb56f 100644 --- a/src/core/cheats.c +++ b/src/core/cheats.c @@ -131,21 +131,22 @@ void mCheatRemoveSet(struct mCheatDevice* device, struct mCheatSet* cheats) { } bool mCheatParseFile(struct mCheatDevice* device, struct VFile* vf) { -#warning Cheat loading is currently broken - return false; -#if 0 char cheat[MAX_LINE_LENGTH]; struct mCheatSet* set = NULL; struct mCheatSet* newSet; bool nextDisabled = false; - void* directives = NULL; + struct StringList directives; + StringListInit(&directives, 4); + while (true) { size_t i = 0; ssize_t bytesRead = vf->readline(vf, cheat, sizeof(cheat)); + rtrim(cheat); if (bytesRead == 0) { break; } if (bytesRead < 0) { + StringListDeinit(&directives); return false; } while (isspace((int) cheat[i])) { @@ -156,7 +157,6 @@ bool mCheatParseFile(struct mCheatDevice* device, struct VFile* vf) { do { ++i; } while (isspace((int) cheat[i])); - cheat[strlen(cheat) - 1] = '\0'; // Remove trailing newline newSet = device->createSet(device, &cheat[i]); newSet->enabled = !nextDisabled; nextDisabled = false; @@ -166,6 +166,7 @@ bool mCheatParseFile(struct mCheatDevice* device, struct VFile* vf) { if (set) { newSet->copyProperties(newSet, set); } + newSet->parseDirectives(newSet, &directives); set = newSet; break; case '!': @@ -177,10 +178,14 @@ bool mCheatParseFile(struct mCheatDevice* device, struct VFile* vf) { break; } if (strcasecmp(&cheat[i], "reset") == 0) { - directives = NULL; + size_t d; + for (d = 0; d < StringListSize(&directives); ++d) { + free(*StringListGetPointer(&directives, d)); + } + StringListClear(&directives); break; } - directives = set->parseDirective(set, &cheat[i], directives); + *StringListAppend(&directives) = strdup(&cheat[i]); break; default: if (!set) { @@ -188,33 +193,44 @@ bool mCheatParseFile(struct mCheatDevice* device, struct VFile* vf) { set->enabled = !nextDisabled; nextDisabled = false; } - mCheatAddLine(set, cheat); + mCheatAddLine(set, cheat, 0); break; } } if (set) { mCheatAddSet(device, set); } + size_t d; + for (d = 0; d < StringListSize(&directives); ++d) { + free(*StringListGetPointer(&directives, d)); + } + StringListClear(&directives); + StringListDeinit(&directives); return true; -#endif } bool mCheatSaveFile(struct mCheatDevice* device, struct VFile* vf) { -#warning Cheat saving is currently broken - return false; -#if 0 static const char lineStart[3] = "# "; static const char lineEnd = '\n'; - void* directives = NULL; + struct StringList directives; + StringListInit(&directives, 4); size_t i; for (i = 0; i < mCheatSetsSize(&device->cheats); ++i) { struct mCheatSet* set = *mCheatSetsGetPointer(&device->cheats, i); - void* directives = set->dumpDirectives(set, vf, directives); + set->dumpDirectives(set, &directives); if (!set->enabled) { static const char* disabledDirective = "!disabled\n"; vf->write(vf, disabledDirective, strlen(disabledDirective)); } + size_t d; + for (d = 0; d < StringListSize(&directives); ++d) { + char directive[64]; + ssize_t len = snprintf(directive, sizeof(directive) - 1, "!%s\n", *StringListGetPointer(&directives, d)); + if (len > 1) { + vf->write(vf, directive, (size_t) len > sizeof(directive) ? sizeof(directive) : len); + } + } vf->write(vf, lineStart, 2); if (set->name) { @@ -228,8 +244,13 @@ bool mCheatSaveFile(struct mCheatDevice* device, struct VFile* vf) { vf->write(vf, &lineEnd, 1); } } + size_t d; + for (d = 0; d < StringListSize(&directives); ++d) { + free(*StringListGetPointer(&directives, d)); + } + StringListClear(&directives); + StringListDeinit(&directives); return true; -#endif } void mCheatRefresh(struct mCheatDevice* device, struct mCheatSet* cheats) { diff --git a/src/core/cheats.h b/src/core/cheats.h index 5602c16b6..75697bf73 100644 --- a/src/core/cheats.h +++ b/src/core/cheats.h @@ -58,6 +58,9 @@ struct mCheatSet { bool (*addLine)(struct mCheatSet* set, const char* cheat, int type); void (*copyProperties)(struct mCheatSet* set, struct mCheatSet* oldSet); + void (*parseDirectives)(struct mCheatSet* set, const struct StringList* directives); + void (*dumpDirectives)(struct mCheatSet* set, struct StringList* directives); + void (*refresh)(struct mCheatSet* set, struct mCheatDevice* device); char* name; diff --git a/src/gb/cheats.c b/src/gb/cheats.c index 95489a1c5..2ac5dbc3e 100644 --- a/src/gb/cheats.c +++ b/src/gb/cheats.c @@ -47,6 +47,8 @@ static void GBCheatAddSet(struct mCheatSet* cheats, struct mCheatDevice* device) static void GBCheatRemoveSet(struct mCheatSet* cheats, struct mCheatDevice* device); static void GBCheatRefresh(struct mCheatSet* cheats, struct mCheatDevice* device); static void GBCheatSetCopyProperties(struct mCheatSet* set, struct mCheatSet* oldSet); +static void GBCheatParseDirectives(struct mCheatSet* set, const struct StringList* directives); +static void GBCheatDumpDirectives(struct mCheatSet* set, struct StringList* directives); static bool GBCheatAddLine(struct mCheatSet*, const char* line, int type); static struct mCheatSet* GBCheatSetCreate(struct mCheatDevice* device, const char* name) { @@ -63,6 +65,9 @@ static struct mCheatSet* GBCheatSetCreate(struct mCheatDevice* device, const cha set->d.addLine = GBCheatAddLine; set->d.copyProperties = GBCheatSetCopyProperties; + set->d.parseDirectives = GBCheatParseDirectives; + set->d.dumpDirectives = GBCheatDumpDirectives; + set->d.refresh = GBCheatRefresh; return &set->d; } @@ -212,3 +217,13 @@ static void GBCheatSetCopyProperties(struct mCheatSet* set, struct mCheatSet* ol UNUSED(set); UNUSED(oldSet); } + +static void GBCheatParseDirectives(struct mCheatSet* set, const struct StringList* directives) { + UNUSED(set); + UNUSED(directives); +} + +static void GBCheatDumpDirectives(struct mCheatSet* set, struct StringList* directives) { + UNUSED(set); + UNUSED(directives); +} diff --git a/src/gba/cheats.c b/src/gba/cheats.c index ba6a3fb0c..e2f3827b7 100644 --- a/src/gba/cheats.c +++ b/src/gba/cheats.c @@ -67,6 +67,8 @@ static void GBACheatAddSet(struct mCheatSet* cheats, struct mCheatDevice* device static void GBACheatRemoveSet(struct mCheatSet* cheats, struct mCheatDevice* device); static void GBACheatRefresh(struct mCheatSet* cheats, struct mCheatDevice* device); static void GBACheatSetCopyProperties(struct mCheatSet* set, struct mCheatSet* oldSet); +static void GBACheatParseDirectives(struct mCheatSet*, const struct StringList* directives); +static void GBACheatDumpDirectives(struct mCheatSet*, struct StringList* directives); static bool GBACheatAddLine(struct mCheatSet*, const char* line, int type); static struct mCheatSet* GBACheatSetCreate(struct mCheatDevice* device, const char* name) { @@ -89,6 +91,9 @@ static struct mCheatSet* GBACheatSetCreate(struct mCheatDevice* device, const ch set->d.addLine = GBACheatAddLine; set->d.copyProperties = GBACheatSetCopyProperties; + set->d.parseDirectives = GBACheatParseDirectives; + set->d.dumpDirectives = GBACheatDumpDirectives; + set->d.refresh = GBACheatRefresh; int i; @@ -268,3 +273,42 @@ static void GBACheatSetCopyProperties(struct mCheatSet* set, struct mCheatSet* o ++newSet->hook->refs; } } + +static void GBACheatParseDirectives(struct mCheatSet* set, const struct StringList* directives) { + struct GBACheatSet* cheats = (struct GBACheatSet*) set; + size_t d; + for (d = 0; d < StringListSize(directives); ++d) { + const char* directive = *StringListGetConstPointer(directives, d); + if (strcmp(directive, "GSAv1") == 0) { + GBACheatSetGameSharkVersion(cheats, 1); + continue; + } + if (strcmp(directive, "PARv3") == 0) { + GBACheatSetGameSharkVersion(cheats, 3); + continue; + } + } +} + +static void GBACheatDumpDirectives(struct mCheatSet* set, struct StringList* directives) { + struct GBACheatSet* cheats = (struct GBACheatSet*) set; + + // TODO: Check previous directives + size_t d; + for (d = 0; d < StringListSize(directives); ++d) { + free(*StringListGetPointer(directives, d)); + } + StringListClear(directives); + + char** directive = StringListAppend(directives); + switch (cheats->gsaVersion) { + case 1: + case 2: + *directive = strdup("GSAv1"); + break; + case 3: + case 4: + *directive = strdup("PARv3"); + break; + } +}