forked from libretro/libretro-database
-
Notifications
You must be signed in to change notification settings - Fork 0
/
mame-member.py
126 lines (110 loc) · 3.51 KB
/
mame-member.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
124
125
126
import sys
import codecs
from xml.etree.cElementTree import parse as xmlparse
def header(data):
if data.tag == 'mame':
return {
'name': 'MAME',
'version': data.attrib['build'].split(' ')[0]
}
header = data.find('header')
if header:
return {
'name': header.find('name').text,
'version': header.find('version').text
}
return {
'name': 'MAME',
'version': 'unknown'
}
# Treat a machine as arcade if it has coin slots
def is_arcade(data):
input = data.find('input')
return bool(input and input.attrib.get('coins'))
def machine(data):
attr = data.attrib
name = attr['name']
desc = data.find('description').text
year = data.find('year')
manu = data.find('manufacturer')
info = {}
info['name'] = name
info['description'] = desc
if year:
info['year'] = year.text
if manu:
info['manufacturer'] = manu.text
roms = []
for r in data.findall('rom'):
ra = r.attrib
if 'crc' not in ra or 'size' not in ra:
continue
rinfo = {
'name': ra['name'],
'size': ra['size'],
'crc': ra['crc']
}
if 'sha1' in ra:
rinfo['sha1'] = ra['sha1']
roms.append(rinfo)
info['roms'] = roms
return info
def machines(data):
info = {}
for m in data.findall('machine'):
if not is_arcade(m):
sys.stderr.write("Skipping non-arcade machine {}\n".format(repr(m.find('description').text)))
continue
minfo = machine(m)
info[minfo['name']] = minfo
for g in data.findall('game'):
minfo = machine(g)
info[minfo['name']] = minfo
return info
def crcmap(data):
seen = {}
info = {}
# Look for CRC collisions
for machine in data.itervalues():
for rom in machine['roms']:
crc = rom['crc']
if crc in seen:
seen[crc] += 1
else:
seen[crc] = 1
for machine in data.itervalues():
unique = None
for rom in machine['roms']:
name = rom['name']
if ' ' in name:
continue
crc = rom['crc']
if seen[crc] > 1:
continue
unique = crc
continue
sys.stderr.write("{}: {}\n".format(unique, repr(machine['description'])))
if unique is not None:
info[unique] = machine
return info
def emit(header, data, out):
out.write('clrmamepro (\n')
out.write(' name "{}"\n'.format(header['name']))
out.write(' version {}\n'.format(header['version']))
out.write(')\n\n')
for crc, game in data.iteritems():
out.write('game (\n')
out.write(u' name "{}"\n'.format(game['description']))
if 'year' in game:
out.write(' year "{}"\n'.format(game['year']))
if 'manufacturer' in game:
out.write(u' developer "{}"\n'.format(game['manufacturer']))
for rom in filter(lambda r: r['crc'] == crc, game['roms']):
if 'sha1' in rom:
out.write(' rom ( name {name} size {size} crc {crc} sha1 {sha1} )\n'.format(**rom))
else:
out.write(' rom ( name {name} size {size} crc {crc} )\n'.format(**rom))
out.write(')\n\n')
data = xmlparse(sys.argv[1]).getroot()
with codecs.open(sys.argv[2], 'w', 'utf-8') as out:
emit(header(data), crcmap(machines(data)), out)