1
2 #include "extractstages.h"
3
4 #include "../maprecord.h"
5 #include "../stagedata.h"
6
7 #include <cstdint>
8 #include <cstdio>
9 #include <cstdlib>
10 #include <cstring>
11 #include <sys/stat.h>
12
13 #define NMAPS 95
14 #define DATA_OFFSET 0x937B0
15
16 #if defined(_WIN32)
17 #define strcasecmp _stricmp
18 #endif
19
20 struct EXEMapRecord
21 {
22 char tileset[32];
23 char filename[32];
24 int scroll_type;
25 char background[32];
26 char NPCset1[32];
27 char NPCset2[32];
28 uint8_t bossNo;
29 char caption[35];
30 };
31
32 EXEMapRecord exemapdata[NMAPS];
33 MapRecord mapdata[NMAPS];
34
35 // the NPC set system isn't used by NXEngine, but the information
36 // is used in a few places to figure out which sprite to be drawn.
37 // for example Balrog when he appears in the Gum Room is supposed to be green.
38 const char *npcsetnames[]
39 = {"guest", "0", "eggs1", "ravil", "weed", "maze", "sand", "omg", "cemet", "bllg", "plant", "frog",
40 "curly", "stream", "ironh", "toro", "x", "dark", "almo1", "eggs2", "twind", "moon", "cent", "heri",
41 "red", "miza", "dr", "almo2", "kings", "hell", "press", "priest", "ballos", "island", NULL};
42
find_index(const char * fname,const char * list[])43 int find_index(const char *fname, const char *list[])
44 {
45 for (int i = 0; list[i]; i++)
46 {
47 if (!strcasecmp(list[i], fname))
48 {
49 return i;
50 }
51 }
52
53 return 0xff;
54 }
55
extract_stages(FILE * exefp)56 bool extract_stages(FILE *exefp)
57 {
58 int i;
59
60 printf("[ data/stage.dat ]\n");
61
62 // load raw data into struct
63 fseek(exefp, DATA_OFFSET, SEEK_SET);
64 fread(exemapdata, sizeof(EXEMapRecord), NMAPS, exefp);
65
66 // convert the data
67 memset(mapdata, 0, sizeof(mapdata));
68 const char *error = NULL;
69
70 for (i = 0; i < NMAPS; i++)
71 {
72 strcpy(mapdata[i].filename, exemapdata[i].filename);
73 strcpy(mapdata[i].stagename, exemapdata[i].caption);
74
75 mapdata[i].scroll_type = exemapdata[i].scroll_type;
76 mapdata[i].bossNo = exemapdata[i].bossNo;
77
78 mapdata[i].tileset = find_index(exemapdata[i].tileset, tileset_names);
79 if (mapdata[i].tileset == 0xff)
80 {
81 error = "tileset";
82 break;
83 }
84
85 mapdata[i].bg_no = find_index(exemapdata[i].background, backdrop_names);
86 if (mapdata[i].bg_no == 0xff)
87 {
88 error = "backdrop";
89 break;
90 }
91
92 mapdata[i].NPCset1 = find_index(exemapdata[i].NPCset1, npcsetnames);
93 if (mapdata[i].NPCset1 == 0xff)
94 {
95 error = "NPCset1";
96 break;
97 }
98
99 mapdata[i].NPCset2 = find_index(exemapdata[i].NPCset2, npcsetnames);
100 if (mapdata[i].NPCset2 == 0xff)
101 {
102 error = "NPCset2";
103 break;
104 }
105 }
106
107 if (error)
108 {
109 printf("didn't recognize map %s name\n", error);
110 printf("on stage %d\n", i);
111
112 return 1;
113 }
114
115 // write out
116 FILE *fpo = fopen("data/stage.dat", "wb");
117 if (!fpo)
118 {
119 printf("failed to open stage.dat for writing\n");
120 return 1;
121 }
122
123 fputc(NMAPS, fpo);
124 for (i = 0; i < NMAPS; i++)
125 fwrite(&mapdata[i], sizeof(MapRecord), 1, fpo);
126
127 fclose(fpo);
128 return 0;
129 }
130