summaryrefslogtreecommitdiff
path: root/dump_mappers.c
blob: 42034de9447bfd97e6be9e5224643fa5dfe45434 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
#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 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 = (submapper << 12) | (mapper_ext << 8) | mapper_high | mapper_low;
	printf("0x%04x  %s\n", 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 = (submapper << 12) | (mapper_ext << 8) | mapper_high | mapper_low;
	printf("0x%04x  %s\n", 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;
}