Skip to content

Instantly share code, notes, and snippets.

@profi200
Last active March 30, 2023 20:23
Show Gist options
  • Save profi200/e06794d7561ed552c518b4b0b2f5f2f6 to your computer and use it in GitHub Desktop.
Save profi200/e06794d7561ed552c518b4b0b2f5f2f6 to your computer and use it in GitHub Desktop.
A tool to fix wrong byte order GBA EEPROM saves as created by some emulators.
#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;
}
@FoxBlocks
Copy link

Oh, okay. That explains it. I'm sorry for wasting your time.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment