mirror of
https://github.com/ksherlock/ample.git
synced 2024-10-31 15:04:56 +00:00
484dd39b67
- cffa2000 renamed to cffa 2.0 - sider1/sider2 added (but disabled)
243 lines
6.0 KiB
Python
243 lines
6.0 KiB
Python
import argparse
|
|
import subprocess
|
|
|
|
from plist import to_plist
|
|
|
|
import xml.etree.ElementTree as ET
|
|
|
|
from machines import MACHINES, SLOTS
|
|
|
|
# don't allow these for now. generally because they add floppy/hard drives
|
|
# but don't work with normal disk images
|
|
DISABLED = set((
|
|
'pcxport',
|
|
'hsscsi', # doesn't work
|
|
'corvus', # these apparently don't use normal disk images.
|
|
'zipdrive',
|
|
'focusdrive',
|
|
'vulcan',
|
|
'vulcangold',
|
|
'vulcaniie',
|
|
'sider',
|
|
'xebec',
|
|
'sider1',
|
|
'sider2',
|
|
))
|
|
|
|
|
|
def find_machine_media(parent):
|
|
# look for relevant device nodes. If the tag contains a slot, skip since it's
|
|
# not built in. Except the Apple3, where the floppy drives are actually slots 0/1/2/3/4
|
|
#
|
|
# apple1 has a "snapshot" device. not currently supported.
|
|
#
|
|
# in the //c (but not //c+) the floppy drives are in slot 6 which doesn't otherwise exist.
|
|
#
|
|
|
|
# no machines have built-in hard drives.
|
|
|
|
mname = parent.get("name")
|
|
remap = {
|
|
"cassette": "cass",
|
|
"apple1_cass": "cass",
|
|
"apple2_cass": "cass",
|
|
"floppy_5_25": "flop_5_25",
|
|
"floppy_3_5": "flop_3_5",
|
|
}
|
|
media = {}
|
|
for x in parent.findall("./device"):
|
|
tag = x.get("tag")
|
|
typ = x.get("type")
|
|
intf = x.get("interface")
|
|
if intf == None: intf = typ # cassette has no interface.
|
|
|
|
# print(" ",intf)
|
|
|
|
slot = None
|
|
if ':' in tag:
|
|
tt = tag.split(':')
|
|
if len(tt) >= 3: slot = tt[0]
|
|
# exclude:
|
|
# apple1 - tag="exp:cassette:cassette"
|
|
# apple2 - tag="sl6:diskiing:0:525" - <slot name="sl6">
|
|
# include:
|
|
# apple2c - tag="sl6:0:525" - <slot name="sl:0">.
|
|
# apple3 - tag="0:525" - <slot name="0">
|
|
|
|
# format slot name : slotoption name : machine->device type name
|
|
|
|
if mname == "apple2c" and slot == "sl6": slot = None
|
|
|
|
if slot: continue
|
|
# skip slot devices -- they'll be handled as part of the device.
|
|
#if ":" in tag and tag[0] not in "0123456789": continue
|
|
|
|
if intf in remap:
|
|
name = remap[intf]
|
|
media[name] = media.get(name, 0) + 1
|
|
|
|
return media
|
|
|
|
|
|
|
|
def find_media(parent, include_slots=False):
|
|
|
|
# not strictly correct since they could have different extensions.
|
|
|
|
|
|
# built-in devices (cassette_image, floppy_sonny, floppy_apple) and default slots
|
|
# have a top-level <device> node which includes the name and extensions.
|
|
|
|
|
|
# slot media generally has a <device> node inline (corvus, diskii)
|
|
# -or-
|
|
# slot/slotoption default="yes", devname is a machine with a device node.
|
|
# diskiing is an exception, naturally.
|
|
|
|
# this ignores the above.
|
|
|
|
|
|
remap_dev = {
|
|
"cassette_image": "cass",
|
|
"floppy_apple": "flop_5_25",
|
|
"harddisk_image": "hard",
|
|
"floppy_sonny": "flop_3_5",
|
|
}
|
|
remap_slot = {
|
|
"harddisk": "hard",
|
|
"hdd": "hard",
|
|
"cdrom": "cdrm",
|
|
"525": "flop_5_25",
|
|
}
|
|
|
|
media = {}
|
|
# floppies
|
|
for x in parent.findall("./device_ref"):
|
|
name = x.get("name")
|
|
if name in remap_dev:
|
|
name = remap_dev[name]
|
|
media[name] = media.get(name, 0) + 1
|
|
|
|
# ata_slot (vulcan, cffa, zip, etc) needs to check slot to see if default.
|
|
# nscsi_connector (a2scsi, a2hsscsi) needs to check slot to see if default.
|
|
|
|
# a2scsi - has 6 slots each with an option to be a cdrom or hard disk.
|
|
# default is 1 cdrom, 1 hard disk.
|
|
# could use -sl6:scsi:scsibus:6 harddisk|cdrom to explicitly set them.
|
|
# this would, of course, screw up the device counting logic.
|
|
|
|
# focus/vulcan can also enable a second harddisk/cdrom.
|
|
|
|
if not include_slots: return media
|
|
|
|
for x in parent.findall("./slot/slotoption"):
|
|
if x.get("default") != "yes": continue
|
|
name = x.get("name")
|
|
if name in remap_slot:
|
|
name = remap_slot[name]
|
|
media[name] = media.get(name, 0) + 1
|
|
|
|
|
|
# special case for the pc transporter. not in the xml but it adds 2 5.25" floppies
|
|
# n.b. - floppies are 5.25" 360k or 180k. not bootable, not usable from prodos
|
|
# without special prodos file or loading driver into pc transporter ram.
|
|
if parent.get("name") == "pcxport":
|
|
media.get["flop_5_25"] = media.get("flop_5_25", 0) + 2
|
|
|
|
if not media: return None
|
|
return media
|
|
|
|
devices = {}
|
|
|
|
p = argparse.ArgumentParser()
|
|
p.add_argument('machine', nargs="*")
|
|
args = p.parse_args()
|
|
|
|
machines = args.machine
|
|
if not machines: machines = MACHINES
|
|
|
|
for m in machines:
|
|
|
|
print(m)
|
|
|
|
env = {'DYLD_FALLBACK_FRAMEWORK_PATH': '../embedded'}
|
|
st = subprocess.run(["../embedded/mame64", m, "-listxml"], capture_output=True, env=env)
|
|
if st.returncode != 0:
|
|
print("mame error: {}".format(m))
|
|
exit(1)
|
|
|
|
data = { }
|
|
|
|
xml = st.stdout
|
|
root = ET.fromstring(xml)
|
|
|
|
path = 'machine[@name="{}"]'.format(m)
|
|
machine = root.find(path)
|
|
|
|
data["value"] = m
|
|
data["description"] = machine.find("description").text
|
|
tmp = [
|
|
{
|
|
"intValue": int(x.text),
|
|
"description": x.get("name"),
|
|
"value": x.get("name"),
|
|
"default": x.get("default") == "yes"
|
|
}
|
|
for x in machine.findall('ramoption')
|
|
]
|
|
# sort and add empty starting entry.
|
|
tmp.sort(key=lambda x: x["intValue"])
|
|
# tmp.insert(0, {"value": 0, "default": False, "description": "" })
|
|
data["ram"] = tmp
|
|
|
|
|
|
data["media"] = find_machine_media(machine)
|
|
|
|
|
|
# node = machine.find('display[@tag="screen"]')
|
|
node = machine.find('./display')
|
|
data["resolution"] = [int(node.get("width")), int(node.get("height")) * 2]
|
|
|
|
mm = {}
|
|
for x in root.findall("machine[@isdevice='yes']"):
|
|
name = x.get("name")
|
|
mm[name] = x # .find("description").text
|
|
# also need to find media...
|
|
|
|
# print(mm)
|
|
|
|
# ss = {}
|
|
for s in SLOTS:
|
|
path = 'slot[@name="{}"]/slotoption'.format(s)
|
|
nodes = machine.findall(path)
|
|
if not nodes: continue
|
|
|
|
tmp = []
|
|
has_default = False
|
|
for x in nodes:
|
|
name = x.get("name")
|
|
devname = x.get("devname")
|
|
desc = mm[devname].find("description").text
|
|
default = x.get("default") == "yes"
|
|
disabled = name in DISABLED
|
|
|
|
d = { "value": name, "description": desc, "default": default }
|
|
if disabled: d["disabled"] = True
|
|
else:
|
|
media = find_media(mm[devname], True)
|
|
if media: d["media"] = media
|
|
tmp.append(d)
|
|
has_default |= default
|
|
|
|
tmp.sort(key=lambda x: x["description"].upper() )
|
|
tmp.insert(0, {"value": "", "description": "—None—", "default": not has_default})
|
|
data[s] = tmp
|
|
|
|
|
|
path = "../Ample/Resources/{}.plist".format(m)
|
|
with open(path, "w") as f:
|
|
f.write(to_plist(data))
|
|
|
|
|
|
|