summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author Vas Crabb <vas@vastheman.com>2017-08-04 17:13:34 +1000
committer Vas Crabb <vas@vastheman.com>2017-08-04 17:13:34 +1000
commitd96933356cda8f865a80245f17dd79a527d267b2 (patch)
treea500720df7ed9a0f413ed0e5633fec78ad28a179
parent0bdd1df2e33555ef9779c4a2106d3d8fea16c410 (diff)
minimaws: demonstrate slot card BIOS selection, requires exposing device BIOS sets in XML output
-rw-r--r--scripts/minimaws/lib/assets/machine.js97
-rw-r--r--scripts/minimaws/lib/dbaccess.py18
-rw-r--r--scripts/minimaws/lib/lxparse.py14
-rw-r--r--scripts/minimaws/lib/wsgiserve.py9
-rw-r--r--scripts/minimaws/schema.sql12
-rw-r--r--src/frontend/mame/info.cpp48
-rw-r--r--src/frontend/mame/info.h2
7 files changed, 165 insertions, 35 deletions
diff --git a/scripts/minimaws/lib/assets/machine.js b/scripts/minimaws/lib/assets/machine.js
index 8a398d4507a..223289c7811 100644
--- a/scripts/minimaws/lib/assets/machine.js
+++ b/scripts/minimaws/lib/assets/machine.js
@@ -2,6 +2,7 @@
// copyright-holders:Vas Crabb
var slot_info = Object.create(null);
+var bios_sets = Object.create(null);
var machine_flags = Object.create(null);
@@ -17,7 +18,10 @@ function update_cmd_preview()
if (item.nodeName == 'DT')
{
var selection = item.lastChild.selectedOptions[0];
- if (selection.getAttribute('data-isdefault') != 'yes')
+ var biospopup = document.getElementById(('select-slot-bios-' + item.getAttribute('data-slotname')).replace(/:/g, '-'));
+ var defcard = selection.getAttribute('data-isdefault') == 'yes';
+ var defbios = !biospopup || (biospopup.selectedOptions[0].getAttribute('data-isdefault') == 'yes');
+ if (!defcard || !defbios)
{
if (first)
first = false;
@@ -27,6 +31,8 @@ function update_cmd_preview()
if (card == '')
card = '""';
result += '-' + item.getAttribute('data-slotname') + ' ' + card;
+ if (!defbios)
+ result += ',bios=' + biospopup.value;
}
}
}
@@ -35,6 +41,41 @@ function update_cmd_preview()
}
+var fetch_bios_sets = (function ()
+ {
+ var pending = Object.create(null);
+ return function (device)
+ {
+ if (!Object.prototype.hasOwnProperty.call(bios_sets, device) && !Object.prototype.hasOwnProperty.call(pending, device))
+ {
+ pending[device] = true;
+ var req = new XMLHttpRequest();
+ req.open('GET', appurl + 'rpc/bios/' + device, true);
+ req.responseType = 'json';
+ req.onload =
+ function ()
+ {
+ delete pending[device];
+ if (req.status == 200)
+ {
+ bios_sets[device] = req.response;
+ var slotslist = document.getElementById('list-slot-options');
+ if (slotslist)
+ {
+ for (var item = slotslist.firstChild; item; item = item.nextSibling)
+ {
+ if ((item.nodeName == 'DT') && (item.getAttribute('data-slotcard') == device))
+ add_bios_row(item.getAttribute('data-slotname'), item.nextSibling.firstChild, device);
+ }
+ }
+ }
+ };
+ req.send();
+ }
+ };
+ })();
+
+
var fetch_machine_flags = (function ()
{
var pending = Object.create(null);
@@ -83,23 +124,62 @@ function add_flag_rows(table, device)
len = unemulated.length;
if (len > 0)
{
- row = table.appendChild(document.createElement('tr'));
+ row = document.createElement('tr');
row.appendChild(document.createElement('th')).textContent = 'Unemulated features:';
cell = row.appendChild(document.createElement('td'));
cell.textContent = unemulated[0];
for (i = 1; i < len; i++)
cell.textContent += ', ' + unemulated[i];
+ if (tbl.lastChild.getAttribute('class') == 'devbios')
+ tbl.insertBefore(row, tbl.lastChild);
+ else
+ tbl.appendChild(row)
}
len = imperfect.length;
if (len > 0)
{
- row = table.appendChild(document.createElement('tr'));
+ row = document.createElement('tr');
row.appendChild(document.createElement('th')).textContent = 'Imperfect features:';
cell = row.appendChild(document.createElement('td'));
cell.textContent = imperfect[0];
for (i = 1; i < len; i++)
cell.textContent += ', ' + unemulated[i];
+ if (tbl.lastChild.getAttribute('class') == 'devbios')
+ tbl.insertBefore(row, tbl.lastChild);
+ else
+ tbl.appendChild(row)
+ }
+}
+
+
+function add_bios_row(slot, table, device)
+{
+ var sorted_sets = Object.keys(bios_sets[device]).sort();
+ var len = sorted_sets.length;
+ if (len > 0)
+ {
+ var row = document.createElement('tr');
+ row.setAttribute('class', 'devbios');
+ row.appendChild(document.createElement('th')).textContent = 'BIOS:';
+ var popup = document.createElement('select');
+ popup.setAttribute('id', ('select-slot-bios-' + slot).replace(/:/g, '-'));
+ popup.onchange = slot_bios_change_handler;
+ for (var i = 0; i < len; i++)
+ {
+ var set = sorted_sets[i];
+ var detail = bios_sets[device][set];
+ var option = document.createElement('option');
+ option.setAttribute('value', set);
+ option.setAttribute('data-isdefault', detail.isdefault ? 'yes' : 'no');
+ option.textContent = set + ' - ' + detail.description;
+ popup.appendChild(option);
+ if (detail.isdefault)
+ popup.selectedIndex = i;
+ }
+ row.appendChild(document.createElement('td')).appendChild(popup);
+ table.appendChild(row);
+ update_cmd_preview();
}
}
@@ -251,6 +331,11 @@ function make_slot_change_handler(name, slot, defaults)
else
add_flag_rows(tbl, selection.device);
+ if (!Object.prototype.hasOwnProperty.call(bios_sets, selection.device))
+ fetch_bios_sets(selection.device);
+ else
+ add_bios_row(slotname, tbl, selection.device);
+
if (def.firstChild)
def.replaceChild(tbl, def.firstChild);
else
@@ -263,6 +348,12 @@ function make_slot_change_handler(name, slot, defaults)
}
+function slot_bios_change_handler(event)
+{
+ update_cmd_preview();
+}
+
+
function populate_slots(machine)
{
var placeholder = document.getElementById('para-slots-placeholder');
diff --git a/scripts/minimaws/lib/dbaccess.py b/scripts/minimaws/lib/dbaccess.py
index 147986e0039..59b22dfad5e 100644
--- a/scripts/minimaws/lib/dbaccess.py
+++ b/scripts/minimaws/lib/dbaccess.py
@@ -55,6 +55,8 @@ class UpdateQueries(object):
ADD_SYSTEM = 'INSERT INTO system (id, year, manufacturer) VALUES (?, ?, ?)'
ADD_CLONEOF = 'INSERT INTO cloneof (id, parent) VALUES (?, ?)'
ADD_ROMOF = 'INSERT INTO romof (id, parent) VALUES (?, ?)'
+ ADD_BIOSSET = 'INSERT INTO biosset (machine, name, description) VALUES (?, ?, ?)'
+ ADD_BIOSSETDEFAULT = 'INSERT INTO biossetdefault (id) VALUES (?)'
ADD_DIPSWITCH = 'INSERT INTO dipswitch (machine, isconfig, name, tag, mask) VALUES (?, ?, ?, ?, ?)'
ADD_DIPLOCATION = 'INSERT INTO diplocation (dipswitch, bit, name, num, inverted) VALUES (?, ?, ?, ?, ?)'
ADD_DIPVALUE = 'INSERT INTO dipvalue (dipswitch, name, value, isdefault) VALUES (?, ?, ?, ?)'
@@ -184,6 +186,14 @@ class QueryCursor(object):
'WHERE machine.shortname = ?',
(machine, ))
+ def get_biossets(self, machine):
+ return self.dbcurs.execute(
+ 'SELECT biosset.name AS name, biosset.description AS description, COUNT(biossetdefault.id) AS isdefault ' \
+ 'FROM biosset LEFT JOIN biossetdefault USING (id) ' \
+ 'WHERE biosset.machine = ? ' \
+ 'GROUP BY biosset.id',
+ (machine, ))
+
def get_devices_referenced(self, machine):
return self.dbcurs.execute(
'SELECT machine.shortname AS shortname, machine.description AS description, sourcefile.filename AS sourcefile ' \
@@ -291,6 +301,14 @@ class UpdateCursor(object):
self.dbcurs.execute(UpdateQueries.ADD_ROMOF, (machine, parent))
return self.dbcurs.lastrowid
+ def add_biosset(self, machine, name, description):
+ self.dbcurs.execute(UpdateQueries.ADD_BIOSSET, (machine, name, description))
+ return self.dbcurs.lastrowid
+
+ def add_biossetdefault(self, biosset):
+ self.dbcurs.execute(UpdateQueries.ADD_BIOSSETDEFAULT, (biosset, ))
+ return self.dbcurs.lastrowid
+
def add_devicereference(self, machine, device):
self.dbcurs.execute(UpdateQueries.ADD_TEMPORARY_DEVICEREFERENCE, (machine, device))
diff --git a/scripts/minimaws/lib/lxparse.py b/scripts/minimaws/lib/lxparse.py
index aeab5c1266d..69d5b91ba0e 100644
--- a/scripts/minimaws/lib/lxparse.py
+++ b/scripts/minimaws/lib/lxparse.py
@@ -126,11 +126,11 @@ class DipSwitchHandler(ElementHandler):
while (0 != self.mask) and not (self.mask & 1):
self.mask >>= 1
self.bit += 1
- self.dbcurs.add_diplocation(self.id, self.bit, attrs['name'], attrs['number'], attrs['inverted'] == 'yes' if 'inverted' in attrs else False)
+ self.dbcurs.add_diplocation(self.id, self.bit, attrs['name'], attrs['number'], attrs.get('inverted', 'no') == 'yes')
self.mask >>= 1
self.bit += 1
elif (name == 'dipvalue') or (name == 'confsetting'):
- self.dbcurs.add_dipvalue(self.id, attrs['name'], attrs['value'], attrs['default'] == 'yes' if 'default' in attrs else False)
+ self.dbcurs.add_dipvalue(self.id, attrs['name'], attrs['value'], attrs.get('default', 'no') == 'yes')
self.setChildHandler(name, attrs, self.IGNORE)
@@ -167,8 +167,8 @@ class MachineHandler(ElementHandler):
def startMainElement(self, name, attrs):
self.shortname = attrs['name']
self.sourcefile = attrs['sourcefile']
- self.isdevice = attrs['isdevice'] == 'yes' if 'isdevice' in attrs else False
- self.runnable = attrs['runnable'] == 'yes' if 'runnable' in attrs else True
+ self.isdevice = attrs.get('isdevice', 'no') == 'yes'
+ self.runnable = attrs.get('runnable', 'yes') == 'yes'
self.cloneof = attrs.get('cloneof')
self.romof = attrs.get('romof')
self.dbcurs.add_sourcefile(self.sourcefile)
@@ -177,7 +177,11 @@ class MachineHandler(ElementHandler):
if name in self.CHILD_HANDLERS:
self.setChildHandler(name, attrs, self.CHILD_HANDLERS[name](self))
else:
- if name == 'device_ref':
+ if name == 'biosset':
+ bios = self.dbcurs.add_biosset(self.id, attrs['name'], attrs['description'])
+ if attrs.get('default', 'no') == 'yes':
+ self.dbcurs.add_biossetdefault(bios)
+ elif name == 'device_ref':
self.dbcurs.add_devicereference(self.id, attrs['name'])
elif name == 'feature':
self.dbcurs.add_featuretype(attrs['type'])
diff --git a/scripts/minimaws/lib/wsgiserve.py b/scripts/minimaws/lib/wsgiserve.py
index 1743178dbb7..370ca811fa6 100644
--- a/scripts/minimaws/lib/wsgiserve.py
+++ b/scripts/minimaws/lib/wsgiserve.py
@@ -390,6 +390,14 @@ class SourceFileHandler(QueryPageHandler):
parent=cgi.escape(machine_info['cloneof'] or '')).encode('utf-8')
+class BiosRpcHandler(MachineRpcHandlerBase):
+ def data_page(self, machine):
+ result = { }
+ for name, description, isdefault in self.dbcurs.get_biossets(machine):
+ result[name] = { 'description': description, 'isdefault': True if isdefault else False }
+ yield json.dumps(result).encode('utf-8')
+
+
class FlagsRpcHandler(MachineRpcHandlerBase):
def data_page(self, machine):
result = { 'features': { } }
@@ -438,6 +446,7 @@ class SlotsRpcHandler(MachineRpcHandlerBase):
class MiniMawsApp(object):
JS_ESCAPE = re.compile('([\"\'\\\\])')
RPC_SERVICES = {
+ 'bios': BiosRpcHandler,
'flags': FlagsRpcHandler,
'slots': SlotsRpcHandler }
diff --git a/scripts/minimaws/schema.sql b/scripts/minimaws/schema.sql
index 86cec49cbcb..63e13c6c364 100644
--- a/scripts/minimaws/schema.sql
+++ b/scripts/minimaws/schema.sql
@@ -38,6 +38,18 @@ CREATE TABLE romof (
parent TEXT NOT NULL,
FOREIGN KEY (id) REFERENCES machine (id));
+CREATE TABLE biosset (
+ id INTEGER PRIMARY KEY,
+ machine INTEGER NOT NULL,
+ name TEXT NOT NULL,
+ description TEXT NOT NULL,
+ UNIQUE (machine ASC, name ASC),
+ FOREIGN KEY (machine) REFERENCES machine (id));
+
+CREATE TABLE biossetdefault (
+ id INTEGER PRIMARY KEY,
+ FOREIGN KEY (id) REFERENCES biosset (id));
+
CREATE TABLE devicereference (
id INTEGER PRIMARY KEY,
machine INTEGER NOT NULL,
diff --git a/src/frontend/mame/info.cpp b/src/frontend/mame/info.cpp
index 01872db6a51..d0b8d4281df 100644
--- a/src/frontend/mame/info.cpp
+++ b/src/frontend/mame/info.cpp
@@ -472,7 +472,7 @@ void info_xml_creator::output_one(driver_enumerator &drivlist, device_type_set *
fprintf(m_output, "\t\t<manufacturer>%s</manufacturer>\n", util::xml::normalize_string(driver.manufacturer));
// now print various additional information
- output_bios(driver);
+ output_bios(config->root_device());
output_rom(&drivlist, config->root_device());
output_device_refs(config->root_device());
output_sample(config->root_device());
@@ -542,6 +542,7 @@ void info_xml_creator::output_one_device(machine_config &config, device_t &devic
fprintf(m_output, ">\n");
fprintf(m_output, "\t\t<description>%s</description>\n", util::xml::normalize_string(device.name()));
+ output_bios(device);
output_rom(nullptr, device);
output_device_refs(device);
@@ -644,35 +645,30 @@ void info_xml_creator::output_sampleof(device_t &device)
//-------------------------------------------------
-// output_bios - print the BIOS set for a
-// game
+// output_bios - print BIOS sets for a device
//-------------------------------------------------
-void info_xml_creator::output_bios(game_driver const &driver)
+void info_xml_creator::output_bios(device_t const &device)
{
- // skip if no ROMs
- if (driver.rom)
+ // first determine the default BIOS name
+ std::string defaultname;
+ for (const rom_entry &rom : device.rom_region_vector())
+ if (ROMENTRY_ISDEFAULT_BIOS(&rom))
+ defaultname = ROM_GETNAME(&rom);
+
+ // iterate over ROM entries and look for BIOSes
+ for (const rom_entry &rom : device.rom_region_vector())
{
- auto rom_entries = rom_build_entries(driver.rom);
-
- // first determine the default BIOS name
- std::string defaultname;
- for (const rom_entry &rom : rom_entries)
- if (ROMENTRY_ISDEFAULT_BIOS(&rom))
- defaultname = ROM_GETNAME(&rom);
-
- // iterate over ROM entries and look for BIOSes
- for (const rom_entry &rom : rom_entries)
- if (ROMENTRY_ISSYSTEM_BIOS(&rom))
- {
- // output extracted name and descriptions
- fprintf(m_output, "\t\t<biosset");
- fprintf(m_output, " name=\"%s\"", util::xml::normalize_string(ROM_GETNAME(&rom)));
- fprintf(m_output, " description=\"%s\"", util::xml::normalize_string(ROM_GETHASHDATA(&rom)));
- if (defaultname == ROM_GETNAME(&rom))
- fprintf(m_output, " default=\"yes\"");
- fprintf(m_output, "/>\n");
- }
+ if (ROMENTRY_ISSYSTEM_BIOS(&rom))
+ {
+ // output extracted name and descriptions
+ fprintf(m_output, "\t\t<biosset");
+ fprintf(m_output, " name=\"%s\"", util::xml::normalize_string(ROM_GETNAME(&rom)));
+ fprintf(m_output, " description=\"%s\"", util::xml::normalize_string(ROM_GETHASHDATA(&rom)));
+ if (defaultname == ROM_GETNAME(&rom))
+ fprintf(m_output, " default=\"yes\"");
+ fprintf(m_output, "/>\n");
+ }
}
}
diff --git a/src/frontend/mame/info.h b/src/frontend/mame/info.h
index f210ade6320..a7a2738030a 100644
--- a/src/frontend/mame/info.h
+++ b/src/frontend/mame/info.h
@@ -47,7 +47,7 @@ private:
void output_one(driver_enumerator &drivlist, device_type_set *devtypes);
void output_sampleof(device_t &device);
- void output_bios(game_driver const &driver);
+ void output_bios(device_t const &device);
void output_rom(driver_enumerator *drivlist, device_t &device);
void output_device_refs(device_t &root);
void output_sample(device_t &device);