diff options
Diffstat (limited to 'src/ARCodeFile.cpp')
-rw-r--r-- | src/ARCodeFile.cpp | 191 |
1 files changed, 191 insertions, 0 deletions
diff --git a/src/ARCodeFile.cpp b/src/ARCodeFile.cpp new file mode 100644 index 0000000..57c710d --- /dev/null +++ b/src/ARCodeFile.cpp @@ -0,0 +1,191 @@ +/* + Copyright 2016-2020 Arisotura + + This file is part of melonDS. + + melonDS is free software: you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation, either version 3 of the License, or (at your option) + any later version. + + melonDS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with melonDS. If not, see http://www.gnu.org/licenses/. +*/ + +#include <stdio.h> +#include <string.h> +#include "ARCodeFile.h" +#include "Platform.h" + + +// TODO: import codes from other sources (usrcheat.dat, ...) +// TODO: more user-friendly error reporting + + +ARCodeFile::ARCodeFile(const char* filename) +{ + memset(Filename, 0, sizeof(Filename)); + strncpy(Filename, filename, 1023); + + Error = false; + + Categories.clear(); + + if (!Load()) + Error = true; +} + +ARCodeFile::~ARCodeFile() +{ + Categories.clear(); +} + +bool ARCodeFile::Load() +{ + FILE* f = Platform::OpenFile(Filename, "r"); + if (!f) return true; + + Categories.clear(); + + bool isincat = false; + ARCodeCat curcat; + + bool isincode = false; + ARCode curcode; + + char linebuf[1024]; + while (!feof(f)) + { + fgets(linebuf, 1024, f); + linebuf[1023] = '\0'; + + char* start = linebuf; + while (start[0]==' ' || start[0]=='\t') + start++; + + if (start[0]=='#' || start[0]=='\r' || start[0]=='\n' || start[0]=='\0') + continue; + + if (!strncasecmp(start, "CAT", 3)) + { + char catname[128]; + int ret = sscanf(start, "CAT %127[^\r\n]", catname); + catname[127] = '\0'; + + if (ret < 1) + { + printf("AR: malformed CAT line: %s\n", start); + fclose(f); + return false; + } + + if (isincode) curcat.Codes.push_back(curcode); + isincode = false; + + if (isincat) Categories.push_back(curcat); + isincat = true; + + memcpy(curcat.Name, catname, 128); + curcat.Codes.clear(); + } + else if (!strncasecmp(start, "CODE", 4)) + { + int enable; + char codename[128]; + int ret = sscanf(start, "CODE %d %127[^\r\n]", &enable, codename); + codename[127] = '\0'; + + if (ret < 2) + { + printf("AR: malformed CODE line: %s\n", start); + fclose(f); + return false; + } + + if (!isincat) + { + printf("AR: encountered CODE line with no category started\n"); + fclose(f); + return false; + } + + if (isincode) curcat.Codes.push_back(curcode); + isincode = true; + + memcpy(curcode.Name, codename, 128); + curcode.Enabled = enable!=0; + curcode.CodeLen = 0; + } + else + { + u32 c0, c1; + int ret = sscanf(start, "%08X %08X", &c0, &c1); + + if (ret < 2) + { + printf("AR: malformed data line: %s\n", start); + fclose(f); + return false; + } + + if (!isincode) + { + printf("AR: encountered data line with no code started\n"); + fclose(f); + return false; + } + + if (curcode.CodeLen >= 2*64) + { + printf("AR: code too long!\n"); + fclose(f); + return false; + } + + u32 idx = curcode.CodeLen; + curcode.Code[idx+0] = c0; + curcode.Code[idx+1] = c1; + curcode.CodeLen += 2; + } + } + + if (isincode) curcat.Codes.push_back(curcode); + if (isincat) Categories.push_back(curcat); + + fclose(f); + return true; +} + +bool ARCodeFile::Save() +{ + FILE* f = Platform::OpenFile(Filename, "w"); + if (!f) return false; + + for (ARCodeCatList::iterator it = Categories.begin(); it != Categories.end(); it++) + { + ARCodeCat& cat = *it; + + if (it != Categories.begin()) fprintf(f, "\n"); + fprintf(f, "CAT %s\n\n", cat.Name); + + for (ARCodeList::iterator jt = cat.Codes.begin(); jt != cat.Codes.end(); jt++) + { + ARCode& code = *jt; + fprintf(f, "CODE %d %s\n", code.Enabled, code.Name); + + for (u32 i = 0; i < code.CodeLen; i+=2) + { + fprintf(f, "%08X %08X\n", code.Code[i], code.Code[i+1]); + } + + fprintf(f, "\n"); + } + } + + fclose(f); + return true; +} |