Skip to content

Instantly share code, notes, and snippets.

@RSDuck
Forked from nadiaholmquist/fix-pokemon-state.c
Created January 16, 2024 22:22
Show Gist options
  • Save RSDuck/3a39d1c71e3a4068849603141c162b3f to your computer and use it in GitHub Desktop.
Save RSDuck/3a39d1c71e3a4068849603141c162b3f to your computer and use it in GitHub Desktop.
melonDS Pokémon gen 5 save state fixer
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <errno.h>
const char wifi[] = { 'W', 'I', 'F', 'I' };
const char mem_fill[] = { 0xA5, 0xA5, 0x5A, 0x5A };
uint8_t* state;
int main(int argc, char** argv) {
if (argc > 2) {
fprintf(stderr, "Usage: %s <state>\n", argv[0]);
return 1;
}
FILE* f = fopen(argv[1], "rb");
if (!f) {
perror(argv[1]);
return errno;
}
fseek(f, 0, SEEK_END);
size_t size = ftell(f);
fseek(f, 0, SEEK_SET);
state = malloc(size);
fread(state, size, 1, f);
fclose(f);
size_t offset = 0;
int found = 0;
while (!found) {
for (size_t i = offset; i < size; i++) {
if (memcmp(state + i, wifi, 4) == 0) {
offset = i;
break;
}
}
if (offset == 0) {
fprintf(stderr, "Couldn't find Wi-Fi data.\n");
return 1;
}
size_t mem_offset = 0;
for (size_t i = offset; i < offset + 32; i++) {
if (memcmp(state + i, mem_fill, 4) == 0) {
mem_offset = i;
}
}
if (mem_offset == 0) {
offset++;
continue;
}
found = 1;
offset = mem_offset;
}
size_t fix_offset = offset + 0x2208;
if (state[fix_offset] != 1) {
fprintf(stderr, "Doesn't look like a save state that needs to be fixed. (%08lx == %02x)\n", fix_offset, state[fix_offset]);
return 1;
}
state[fix_offset] = 0x09;
const char* fixed = ".fixed";
char* new_name = malloc(strlen(argv[1]) + strlen(fixed));
sprintf(new_name, "%s%s", argv[1], fixed);
FILE* new_file = fopen(new_name, "wb");
if (!new_file) {
perror(new_name);
return errno;
}
fwrite(state, size, 1, new_file);
fclose(new_file);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment