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