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