diff options
Diffstat (limited to 'helpers/dump_mappers.c')
| -rw-r--r-- | helpers/dump_mappers.c | 123 |
1 files changed, 123 insertions, 0 deletions
diff --git a/helpers/dump_mappers.c b/helpers/dump_mappers.c new file mode 100644 index 0000000..98dad4e --- /dev/null +++ b/helpers/dump_mappers.c @@ -0,0 +1,123 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <stdint.h> +#include <dirent.h> +#include <zlib.h> +#include <minizip/unzip.h> +#include <sys/stat.h> + +#define INES_HEADER_SIZE 16 + +static void print_mapper(uint32_t mapper, const char *path) { + uint32_t mapper_id = mapper >> 4; + uint32_t submapper = mapper & 0xF; + + printf("%03u_%x %s\n", mapper_id, submapper, path); +} + +static void process_nes_file(const char *path) { + FILE *f = fopen(path, "rb"); + if(!f) return; + + uint8_t header[INES_HEADER_SIZE]; + if(fread(header, 1, INES_HEADER_SIZE, f) != INES_HEADER_SIZE) { + fclose(f); + return; + } + fclose(f); + + if(memcmp(header, "NES\x1A", 4) != 0) return; + + uint8_t mapper_low = (header[6] >> 4); + uint8_t mapper_high = (header[7] & 0xF0); + uint8_t mapper_ext = header[8] & 0x0F; + uint8_t submapper = header[8] >> 4; + + uint32_t mapper = (mapper_ext << 8) | mapper_high | mapper_low; + mapper = (mapper << 4) | submapper; + + print_mapper(mapper, path); +} + +static void process_zip_file(const char *path) { + unzFile zip = unzOpen(path); + if(!zip) return; + + if(unzGoToFirstFile(zip) != UNZ_OK) { + unzClose(zip); + return; + } + + char filename[256]; + unz_file_info info; + if(unzGetCurrentFileInfo(zip, &info, filename, sizeof(filename), 0, 0, 0, 0) != UNZ_OK) { + unzClose(zip); + return; + } + + if(strstr(filename, ".nes") == 0) { + unzClose(zip); + return; + } + + if(unzOpenCurrentFile(zip) != UNZ_OK) { + unzClose(zip); + return; + } + + uint8_t header[INES_HEADER_SIZE]; + if(unzReadCurrentFile(zip, header, INES_HEADER_SIZE) != INES_HEADER_SIZE) { + unzCloseCurrentFile(zip); + unzClose(zip); + return; + } + unzCloseCurrentFile(zip); + unzClose(zip); + + if(memcmp(header, "NES\x1A", 4) != 0) return; + + uint8_t mapper_low = (header[6] >> 4); + uint8_t mapper_high = (header[7] & 0xF0); + uint8_t mapper_ext = header[8] & 0x0F; + uint8_t submapper = header[8] >> 4; + + uint32_t mapper = (mapper_ext << 8) | mapper_high | mapper_low; + mapper = (mapper << 4) | submapper; + + print_mapper(mapper, path); +} + +static void scan_directory(const char *path) { + DIR *dir = opendir(path); + if(!dir) return; + + struct dirent *entry; + while((entry = readdir(dir))) { + if(entry->d_name[0] == '.') continue; + + char fullpath[1024]; + snprintf(fullpath, sizeof(fullpath), "%s/%s", path, entry->d_name); + + struct stat st; + if(stat(fullpath, &st) < 0) continue; + + if(S_ISDIR(st.st_mode)) { + scan_directory(fullpath); + } else if(strstr(fullpath, ".nes")) { + process_nes_file(fullpath); + } else if(strstr(fullpath, ".zip")) { + process_zip_file(fullpath); + } + } + closedir(dir); +} + +int main(int argc, char **argv) { + if(argc < 2) { + fprintf(stderr, "Usage: %s <romdir>\n", argv[0]); + return 1; + } + scan_directory(argv[1]); + return 0; +} |
