-
Notifications
You must be signed in to change notification settings - Fork 77
/
map_header_resolve_fields.py
123 lines (107 loc) · 4.11 KB
/
map_header_resolve_fields.py
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
import collections
import struct
import typing
import re
romfname = 'baserom.nds'
arm9offs = 0x00004000
arm9load = 0x02000000
mapheado = 0x020EEDBC
mapheads = 0x00003468
class MapHeader(typing.NamedTuple):
area_data_bank: int
move_model_bank: int
matrix_id: int
scripts_bank: int
level_scripts_bank: int
msg_bank: int
day_music_id: int
night_music_id: int
wild_encounter_bank: int
events_bank: int
mapsec: int
weather_type: int
camera_type: int
unk16: int
battle_bg: int
is_bike_allowed: bool
is_running_allowed: bool
is_escape_rope_allowed: bool
is_fly_allowed: bool
@classmethod
def from_buffer(cls, buffer: bytes) -> typing.Generator['MapHeader', None, typing.Any]:
for tup in struct.iter_unpack('<BBHHHHHHHHHBBBB', buffer):
*tup, flags = tup
tup += (flags & 15, flags & 16 != 0, flags & 32 != 0, flags & 64 != 0, flags & 128 != 0)
yield cls._make(tup)
def read_sndseq_h():
i = 0
with open('include/constants/sndseq.h') as fp:
for line in fp:
if line.startswith('#define SEQ_'):
name = line.split()[1]
if name.startswith('SEQ_SE_'):
while i < 1500:
yield str(i)
i += 1
elif not name.startswith('SEQ_PV'):
while i < 1000:
yield str(i)
i += 1
yield name
i += 1
def read_mapsec_h():
with open('include/constants/map_sections.h') as fp:
for line in fp:
if line.startswith('#define MAPSEC_'):
yield line.split()[1]
def read_naix(filename):
with open(filename) as fp:
for line in fp:
if (m := re.match(r'\s*(NARC_\w+)\s+=\s+\d+,', line)) is not None:
yield m[1]
class MyList(list):
def __getitem__(self, item):
try:
return super().__getitem__(item)
except IndexError:
return str(item)
def main():
sndseqs = MyList(read_sndseq_h())
mapsecs = MyList(read_mapsec_h())
msgnaix = MyList(read_naix('files/msgdata/msg.naix'))
scrseqnaix = MyList(read_naix('files/fielddata/script/scr_seq_release.naix'))
areanaix = MyList(read_naix('files/fielddata/areadata/area_data.naix'))
mmlistnaix = MyList(read_naix('files/fielddata/mm_list/move_model_list.naix'))
matlistnaix = MyList(read_naix('files/fielddata/mapmatrix/map_matrix.naix'))
d_encdatanaix = MyList(read_naix('files/fielddata/encountdata/d_enc_data.naix'))
p_encdatanaix = MyList(read_naix('files/fielddata/encountdata/p_enc_data.naix'))
eventnaix = MyList(read_naix('files/fielddata/eventdata/zone_event_release.naix'))
with open(romfname, 'rb') as rom:
rom.seek(mapheado - arm9load + arm9offs)
for header in MapHeader.from_buffer(rom.read(mapheads)): # type: MapHeader
print('{' + ', '.join((
areanaix[header.area_data_bank],
mmlistnaix[header.move_model_bank],
matlistnaix[header.matrix_id],
scrseqnaix[header.scripts_bank],
scrseqnaix[header.level_scripts_bank],
msgnaix[header.msg_bank],
sndseqs[header.day_music_id],
sndseqs[header.night_music_id],
'0xFFFF' if header.wild_encounter_bank == 0xFFFF else 'ENCDATA({}, {})'.format(
d_encdatanaix[header.wild_encounter_bank],
p_encdatanaix[header.wild_encounter_bank],
),
eventnaix[header.events_bank],
mapsecs[header.mapsec],
str(header.weather_type),
str(header.camera_type),
str(header.unk16),
str(header.battle_bg),
['FALSE', 'TRUE'][header.is_bike_allowed],
['FALSE', 'TRUE'][header.is_running_allowed],
['FALSE', 'TRUE'][header.is_escape_rope_allowed],
['FALSE', 'TRUE'][header.is_fly_allowed],
)) + '},')
if __name__ == '__main__':
main()