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