-
-
Save profi200/e06794d7561ed552c518b4b0b2f5f2f6 to your computer and use it in GitHub Desktop.
#include <stdint.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
// Compile with "gcc -std=c17 -O2 -fstrict-aliasing -ffunction-sections -Wall -Wl,--gc-sections gbaEepromSaveFix.c -o gbaEepromSaveFix" | |
int main(int argc, char *argv[]) | |
{ | |
int res = 0; | |
FILE *f = fopen(argv[1], "rb+"); | |
if(f != NULL) | |
{ | |
do | |
{ | |
fseek(f, 0, SEEK_END); | |
const size_t fSize = ftell(f); | |
// Minimum 32 because of the unrolled byteswap loop below. | |
// The last check is a power of 2 check. | |
if(fSize == 0 || fSize < 32 || (fSize & (fSize - 1)) != 0) | |
{ | |
fputs("Broken save file or incorrect size!\n", stderr); | |
res = 2; | |
break; | |
} | |
fseek(f, 0, SEEK_SET); | |
uint64_t *buf = (uint64_t*)malloc(fSize); | |
if(buf == NULL) | |
{ | |
fputs("Out of memory.\n", stderr); | |
res = 3; | |
break; | |
} | |
if(fread(buf, 1, fSize, f) != fSize) | |
{ | |
fputs("Failed to read file.\n", stderr); | |
res = 4; | |
free(buf); | |
break; | |
} | |
for(size_t i = 0; i < fSize / 8; i += 4) | |
{ | |
buf[i + 0] = __builtin_bswap64(buf[i + 0]); | |
buf[i + 1] = __builtin_bswap64(buf[i + 1]); | |
buf[i + 2] = __builtin_bswap64(buf[i + 2]); | |
buf[i + 3] = __builtin_bswap64(buf[i + 3]); | |
} | |
fseek(f, 0, SEEK_SET); | |
if(fwrite(buf, 1, fSize, f) != fSize) | |
{ | |
fputs("Failed to write to file.\n", stderr); | |
res = 5; | |
} | |
free(buf); | |
} while(0); | |
fclose(f); | |
} | |
else | |
{ | |
fputs("Failed to open save file.\n", stderr); | |
res = 1; | |
} | |
if(res == 0) puts("Done."); | |
return res; | |
} |
Ah, thanks. Didn't know this is broken on OSX.
This doesn't work for me on Kirby & The Amazing Mirror. I tried using this to convert from open_agb_firm to emulator, and all save slots in the save file appear as 0% complete. Is there something I'm missing? I ran this on Windows 11 via WSL, compiled with the supplied gcc command.
Hmm, weird. I tried importing the save file from open_agb_firm directly into VisualBoyAdvance, and after giving me a "Cannot open file" error, it actually read it and converted the save. Not sure how that worked, but it did. I transfered that new save to Lemuroid and it worked there too. Again, very strange.
I'll just use that to transfer my save to and from open_agb_firm for now.
Is it even an EEPROM save? They usually have a size of either 512 bytes or 8 KiB.
It's 32KB.
Then it's a SRAM save and doesn't need conversion.
Oh, okay. That explains it. I'm sorry for wasting your time.
To compile on macOS:
clang -std=c17 -O2 -fstrict-aliasing -ffunction-sections -Wall gbaEepromSaveFix.c -o gbaEepromSaveFix
(the-Wl,--gc-sections
part is removed)