-
-
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-sectionspart is removed)