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