1 
2 #include <stdio.h>
3 #include <stdint.h>
4 
5 #define NMAPS			95
6 #define DATA_OFFSET		0x937B0
7 
8 typedef struct
9 {
10 	char tileset[32];
11 	char filename[32];
12 	int scroll_type;
13 	char background[32];
14 	char NPCset1[32];
15 	char NPCset2[32];
16 	uint8_t bossNo;
17 	char caption[35];
18 } MapRecord;
19 
20 MapRecord MapData[NMAPS];
21 
22 typedef struct
23 {
24 	char files[NMAPS+1][32];
25 	int nfiles;
26 } filelist;
27 
FindFileInList(filelist * list,char * fname)28 int FindFileInList(filelist *list, char *fname)
29 {
30 int i;
31 	for(i=0;i<list->nfiles;i++)
32 	{
33 		if (!strcasecmp(list->files[i], fname))
34 		{
35 			return i;
36 		}
37 	}
38 	return -1;
39 }
40 
AddFileToList(filelist * list,char * fname)41 void AddFileToList(filelist *list, char *fname)
42 {
43 	if (FindFileInList(list, fname) != -1) return;
44 
45 	//printf("Added '%s' to list at pos %d\n", fname, list->nfiles);
46 	strcpy(list->files[list->nfiles], fname);
47 	list->nfiles++;
48 }
49 
50 
main(void)51 int main(void)
52 {
53 filelist bg, tileset, npcset;
54 FILE *fp;
55 int i, j;
56 char *comma;
57 char buf[256];
58 
59 	// read data from exe
60 	fp = fopen("/data/win/Programs/Games/Cave Story Deluxe/CaveStory/Doukutsu.exe", "rb");
61 	if (!fp) { NX_ERROR("Failed opening exe\n"); return 1; }
62 
63 	// load raw data into struct
64 	fseek(fp, DATA_OFFSET, SEEK_SET);
65 	fread(MapData, sizeof(MapRecord), NMAPS, fp);
66 	fclose(fp);
67 
68 	// parse tileset and bg info and convert strings to numbers
69 	memset(&bg, 0, sizeof(bg));
70 	memset(&tileset, 0, sizeof(tileset));
71 	memset(&npcset, 0, sizeof(npcset));
72 	for(i=0;i<NMAPS;i++)
73 	{
74 		AddFileToList(&bg, MapData[i].background);
75 		AddFileToList(&tileset, MapData[i].tileset);
76 		AddFileToList(&npcset, MapData[i].NPCset1);
77 		AddFileToList(&npcset, MapData[i].NPCset2);
78 	}
79 
80 	// output data to .c & .h file
81 	fp = fopen("../autogen/stagedata.h", "wb");
82 
83 	fprintf(fp, "//auto-generated by extractmapinfo.c\n\n");
84 	fprintf(fp, "#define NMAPS\t %d\n", NMAPS);
85 	fprintf(fp, "typedef struct\n");
86 	fprintf(fp, "{\n");
87 	fprintf(fp, "\tchar filename[32];\n");
88 	fprintf(fp, "\tchar stagename[35];\n\n");
89 	fprintf(fp, "\tuint8_t tileset;\n");
90 	fprintf(fp, "\tuint8_t bg_no;\n");
91 	fprintf(fp, "\tuint8_t scroll_type;\n");
92 	fprintf(fp, "\tuint8_t bossNo;\n");
93 	fprintf(fp, "\tuint8_t NPCset1;\n");
94 	fprintf(fp, "\tuint8_t NPCset2;\n");
95 	fprintf(fp, "} MapRecord;\n\n");
96 
97 	fprintf(fp, "extern MapRecord stages[NMAPS];\n\n");
98 
99 	fprintf(fp, "#define NUM_BACKDROPS		%d\n", bg.nfiles);
100 	fprintf(fp, "#define NUM_TILESETS		%d\n\n", tileset.nfiles);
101 
102 	fprintf(fp, "extern const char *backdrop_names[];\n");
103 	fprintf(fp, "extern const char *tileset_names[];\n");
104 
105 	// output the NPC spriteset constants
106 	fprintf(fp, "\n\n");
107 	for(i=0;i<npcset.nfiles;i++)
108 	{
109 		// make the filename upper-case so it looks like a constant
110 		for(j=strlen(npcset.files[i])-1;j>=0;j--)
111 		{
112 			npcset.files[i][j] = toupper(npcset.files[i][j]);
113 		}
114 
115 		fprintf(fp, "#define NPCSET_%s\t\t %d\n", npcset.files[i], i);
116 	}
117 
118 	fprintf(fp, "\n");
119 	fclose(fp);
120 
121 
122 	fp = fopen("../autogen/stagedata.cpp", "wb");
123 
124 	fprintf(fp, "//auto-generated by extractmapinfo.c\n\n");
125 
126 	fprintf(fp, "#include <stdio.h>\n");
127 	fprintf(fp, "#include <stdint.h>\n");
128 	fprintf(fp, "#include \"stagedata.h\"\n\n");
129 
130 	// output the backdrop names
131 	fprintf(fp, "const char *backdrop_names[] = {\n");
132 	for(i=0;i<bg.nfiles;i++)
133 	{
134 		bg.files[i][0] = tolower(bg.files[i][0]);	// fix case-sensitivity issue on UNIX filesystems
135 		fprintf(fp, "\t\"%s\",\n", bg.files[i]);
136 	}
137 	fprintf(fp, "\tNULL\n};\n\n");
138 
139 	// output the tileset names
140 	fprintf(fp, "const char *tileset_names[] = {\n");
141 	for(i=0;i<tileset.nfiles;i++) { fprintf(fp, "\t\"%s\",\n", tileset.files[i]); }
142 	fprintf(fp, "\tNULL\n};\n\n");
143 
144 	// finally output the map records
145 	fprintf(fp, "MapRecord stages[NMAPS] = {\n");
146 
147 	comma = ",";
148 	for(i=0;i<NMAPS;i++)
149 	{
150 		if (i+1==NMAPS) comma = "";
151 
152 		fprintf(fp, "\"%s\", \"%s\", %d, %d, %d, %d, %d, %d%s\n", \
153 			MapData[i].filename, \
154 			MapData[i].caption, \
155 			FindFileInList(&tileset, MapData[i].tileset), \
156 			FindFileInList(&bg, MapData[i].background), \
157 			MapData[i].scroll_type, \
158 			MapData[i].bossNo, \
159 			FindFileInList(&npcset, MapData[i].NPCset1), \
160 			FindFileInList(&npcset, MapData[i].NPCset2), \
161 			comma);
162 	}
163 
164 	fprintf(fp, "};\n\n");
165 	fclose(fp);
166 
167 	return 0;
168 }
169 
170 
171