summaryrefslogtreecommitdiff
path: root/helpers/dump_mappers.c
diff options
context:
space:
mode:
Diffstat (limited to 'helpers/dump_mappers.c')
-rw-r--r--helpers/dump_mappers.c123
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;
+}