Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions hash/megadriv.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3800,6 +3800,7 @@ Info on Sega chip labels (from Sunbeam / Digital Corruption)
<description>Ishido - The Way of Stones (USA)</description>
<year>1990</year>
<publisher>Accolade</publisher>
<sharedfeat name="incompatibility" value="TMSS"/>
<part name="cart" interface="megadriv_cart">
<feature name="pcb" value="ACBWPC1190"/>
<feature name="ic1" value="MB834200A 2M5 BA 9044 T03 ISS0890"/>
Expand Down Expand Up @@ -11942,6 +11943,7 @@ but dumps still have to be confirmed.
<description>Budokan - The Martial Spirit (USA)</description>
<year>1990</year>
<publisher>Electronic Arts</publisher>
<sharedfeat name="incompatibility" value="TMSS"/>
<part name="cart" interface="megadriv_cart">
<dataarea name="rom" width="16" endianness="big" size="524288">
<rom name="budokan - the martial spirit (usa).bin" size="524288" crc="acd9f5fc" sha1="93bc8242106bc9b2e0a8a974a3f65b559dd2941d" offset="0x000000"/>
Expand Down Expand Up @@ -20522,6 +20524,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i
<description>Onslaught (Euro, USA)</description>
<year>1991</year>
<publisher>Ballistic</publisher>
<sharedfeat name="incompatibility" value="TMSS"/>
<part name="cart" interface="megadriv_cart">
<dataarea name="rom" width="16" endianness="big" size="524288">
<rom name="onslaught (euro, usa).bin" size="524288" crc="9f19d6df" sha1="dc542ddfa878f2aed3a7fcedc4b0f8d503eb5d70" offset="0x000000"/>
Expand Down Expand Up @@ -21578,6 +21581,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i
<description>Populous (USA)</description>
<year>1991</year>
<publisher>Sega</publisher>
<sharedfeat name="incompatibility" value="TMSS"/>
<part name="cart" interface="megadriv_cart">
<dataarea name="rom" width="16" endianness="big" size="524288">
<rom name="populous (usa).bin" size="524288" crc="bd74b31e" sha1="89907c4ba4fd9db4e8ef2271c0253bb0e4b6d52d" offset="0x000000"/>
Expand Down Expand Up @@ -29417,6 +29421,7 @@ Notice that these are not working on real hardware due to bugged code with VDP i
<description>Zany Golf (Euro, USA)</description>
<year>1990</year>
<publisher>Electronic Arts</publisher>
<sharedfeat name="incompatibility" value="TMSS"/>
<part name="cart" interface="megadriv_cart">
<dataarea name="rom" width="16" endianness="big" size="524288">
<rom name="zany golf (euro, usa).bin" size="524288" crc="ed5d12ea" sha1="4f9bea2d8f489bfbc963718a8dca212e033fb5a2" offset="0x000000"/>
Expand Down
40 changes: 20 additions & 20 deletions src/emu/diimage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1288,14 +1288,26 @@ bool device_image_interface::load_software_part(const char *path, software_part
}

// Load the software part
bool result = call_softlist_load(swpart->info().list(), swpart->info().shortname(), swpart->romdata());
software_list_device &swlist = swpart->info().list();
bool result = call_softlist_load(swlist, swpart->info().shortname(), swpart->romdata());

// Tell the world which part we actually loaded
std::string full_sw_name = string_format("%s:%s:%s", swpart->info().list().list_name(), swpart->info().shortname(), swpart->name());
std::string full_sw_name = string_format("%s:%s:%s", swlist.list_name(), swpart->info().shortname(), swpart->name());

// check compatibility
if (!swpart->is_compatible(swpart->info().list()))
osd_printf_warning("WARNING! the set %s might not work on this system due to missing filter(s) '%s'\n", swpart->info().shortname(), swpart->info().list().filter());
switch (swpart->is_compatible(swlist))
{
case SOFTWARE_IS_COMPATIBLE:
break;

case SOFTWARE_IS_INCOMPATIBLE:
swlist.popmessage("WARNING! the set %s might not work on this system due to incompatible filter(s) '%s'\n", swpart->info().shortname(), swlist.filter());
break;

case SOFTWARE_NOT_COMPATIBLE:
swlist.popmessage("WARNING! the set %s might not work on this system due to missing filter(s) '%s'\n", swpart->info().shortname(), swlist.filter());
break;
}

// check requirements and load those images
const char *requirement = swpart->feature("requirement");
Expand All @@ -1304,23 +1316,11 @@ bool device_image_interface::load_software_part(const char *path, software_part
software_part *req_swpart = find_software_item(requirement, false);
if (req_swpart != nullptr)
{
for (device_image_interface &req_image : image_interface_iterator(device().machine().root_device()))
device_image_interface *req_image = req_swpart->find_mountable_image(device().mconfig());
if (req_image != nullptr)
{
const char *interface = req_image.image_interface();
if (interface != nullptr)
{
if (req_swpart->matches_interface(interface))
{
const char *option = device().mconfig().options().value(req_image.brief_instance_name());
// mount only if not already mounted
if (*option == '\0' && !req_image.filename())
{
req_image.set_init_phase();
req_image.load(requirement);
}
break;
}
}
req_image->set_init_phase();
req_image->load(requirement);
}
}
}
Expand Down
72 changes: 61 additions & 11 deletions src/emu/softlist.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -140,26 +140,48 @@ const char *software_part::feature(const char *feature_name) const
// with the given software_list_device
//-------------------------------------------------

bool software_part::is_compatible(const software_list_device &swlistdev) const
software_compatibility software_part::is_compatible(const software_list_device &swlistdev) const
{
// get the compatibility feature and the softlist filter; if either is nullptr, assume compatible
const char *compatibility = feature("compatibility");
// get the softlist filter; if null, assume compatible
const char *filter = swlistdev.filter();
if (compatibility == nullptr || filter == nullptr)
return true;
if (filter == nullptr)
return SOFTWARE_IS_COMPATIBLE;

// copy the comma-delimited strings and ensure they end with a final comma
std::string comp = std::string(compatibility).append(",");
// copy the comma-delimited string and ensure it ends with a final comma
std::string filt = std::string(filter).append(",");

// iterate over filter items and see if they exist in the compatibility list; if so, return true
// get the incompatibility filter and test against it first if it exists
const char *incompatibility = feature("incompatibility");
if (incompatibility != nullptr)
{
// copy the comma-delimited string and ensure it ends with a final comma
std::string incomp = std::string(incompatibility).append(",");

// iterate over filter items and see if they exist in the list; if so, it's incompatible
for (int start = 0, end = filt.find_first_of(',',start); end != -1; start = end + 1, end = filt.find_first_of(',', start))
{
std::string token(filt, start, end - start + 1);
if (incomp.find(token) != -1)
return SOFTWARE_IS_INCOMPATIBLE;
}
}

// get the compatibility feature; if null, assume compatible
const char *compatibility = feature("compatibility");
if (compatibility == nullptr)
return SOFTWARE_IS_COMPATIBLE;

// copy the comma-delimited string and ensure it ends with a final comma
std::string comp = std::string(compatibility).append(",");

// iterate over filter items and see if they exist in the compatibility list; if so, it's compatible
for (int start = 0, end = filt.find_first_of(',',start); end != -1; start = end + 1, end = filt.find_first_of(',', start))
{
std::string token(filt, start, end - start + 1);
if (comp.find(token) != -1)
return true;
return SOFTWARE_IS_COMPATIBLE;
}
return false;
return SOFTWARE_NOT_COMPATIBLE;
}


Expand All @@ -183,6 +205,34 @@ bool software_part::matches_interface(const char *interface_list) const
}


//-------------------------------------------------
// find_mountable_image - find an image interface
// that can automatically mount this software part
//-------------------------------------------------

device_image_interface *software_part::find_mountable_image(const machine_config &mconfig) const
{
// if automount="no", don't bother
const char *mount = feature("automount");
if (mount != nullptr && strcmp(mount, "no") == 0)
return nullptr;

for (device_image_interface &image : image_interface_iterator(mconfig.root_device()))
{
const char *interface = image.image_interface();
if (interface != nullptr && matches_interface(interface))
{
// mount only if not already mounted
const char *option = mconfig.options().value(image.brief_instance_name());
if (*option == '\0' && !image.filename())

return &image;
}
}
return nullptr;
}



//**************************************************************************
// SOFTWARE INFO
Expand Down Expand Up @@ -340,7 +390,7 @@ void software_list_device::find_approx_matches(const char *name, int matches, so
for (software_info &swinfo : get_info())
{
software_part *part = swinfo.first_part();
if ((interface == nullptr || part->matches_interface(interface)) && part->is_compatible(*this))
if ((interface == nullptr || part->matches_interface(interface)) && part->is_compatible(*this) == SOFTWARE_IS_COMPATIBLE)
{
// pick the best match between driver name and description
int longpenalty = driver_list::penalty_compare(name, swinfo.longname());
Expand Down
9 changes: 8 additions & 1 deletion src/emu/softlist.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,12 @@ enum softlist_type
SOFTWARE_LIST_COMPATIBLE_SYSTEM
};

enum software_compatibility
{
SOFTWARE_IS_COMPATIBLE,
SOFTWARE_IS_INCOMPATIBLE,
SOFTWARE_NOT_COMPATIBLE
};


//**************************************************************************
Expand Down Expand Up @@ -115,9 +121,10 @@ class software_part
rom_entry *romdata(unsigned int index = 0) { return (index < m_romdata.size()) ? &m_romdata[index] : nullptr; }

// helpers
bool is_compatible(const software_list_device &swlist) const;
software_compatibility is_compatible(const software_list_device &swlist) const;
bool matches_interface(const char *interface) const;
const char *feature(const char *feature_name) const;
device_image_interface *find_mountable_image(const machine_config &mconfig) const;

private:
// internal state
Expand Down
44 changes: 16 additions & 28 deletions src/frontend/mame/clifront.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,7 @@ int cli_frontend::execute(int argc, char **argv)
throw emu_fatalerror(EMU_ERR_FATALERROR, "Error: unknown option: %s\n", m_options.software_name());

bool found = false;
bool compatible = false;
for (software_list_device &swlistdev : iter)
{
software_info *swinfo = swlistdev.find(m_options.software_name());
Expand All @@ -209,46 +210,33 @@ int cli_frontend::execute(int argc, char **argv)
// loop through all parts
for (software_part &swpart : swinfo->parts())
{
const char *mount = swpart.feature("automount");
if (swpart.is_compatible(swlistdev))
// only load compatible software this way
if (swpart.is_compatible(swlistdev) == SOFTWARE_IS_COMPATIBLE)
{
if (mount == nullptr || strcmp(mount,"no") != 0)
device_image_interface *image = swpart.find_mountable_image(config);
if (image != nullptr)
{
// search for an image device with the right interface
for (device_image_interface &image : image_interface_iterator(config.root_device()))
{
const char *interface = image.image_interface();
if (interface != nullptr)
{
if (swpart.matches_interface(interface))
{
const char *option = m_options.value(image.brief_instance_name());

// mount only if not already mounted
if (*option == 0)
{
std::string val = string_format("%s:%s:%s", swlistdev.list_name(), m_options.software_name(), swpart.name());
std::string val = string_format("%s:%s:%s", swlistdev.list_name(), m_options.software_name(), swpart.name());

// call this in order to set slot devices according to mounting
mame_options::parse_slot_devices(m_options, argc, argv, option_errors, image.instance_name(), val.c_str(), &swpart);
break;
}
}
}
}
// call this in order to set slot devices according to mounting
mame_options::parse_slot_devices(m_options, argc, argv, option_errors, image->instance_name(), val.c_str(), &swpart);
}
found = true;
compatible = true;
}
}
found = true;
}

if (found)
if (compatible)
break;
}
if (!found)
if (!compatible)
{
software_list_device::display_matches(config, nullptr, m_options.software_name());
throw emu_fatalerror(EMU_ERR_FATALERROR, nullptr);
if (!found)
throw emu_fatalerror(EMU_ERR_FATALERROR, nullptr);
else
throw emu_fatalerror(EMU_ERR_FATALERROR, "Software '%s' is incompatible with system '%s'\n", m_options.software_name(), m_options.system_name());
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/frontend/mame/ui/selsoft.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -538,7 +538,7 @@ void ui_menu_select_software::build_software_list()
for (software_info &swinfo : swlist.get_info())
{
software_part *part = swinfo.first_part();
if (part->is_compatible(swlist))
if (part->is_compatible(swlist) == SOFTWARE_IS_COMPATIBLE)
{
const char *instance_name = nullptr;
const char *type_name = nullptr;
Expand Down
2 changes: 1 addition & 1 deletion src/frontend/mame/ui/swlist.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ ui_menu_software_list::entry_info *ui_menu_software_list::append_software_entry(
// check if at least one of the parts has the correct interface and add a menu entry only in this case
for (const software_part &swpart : swinfo.parts())
{
if (swpart.matches_interface(m_interface) && swpart.is_compatible(*m_swlist))
if (swpart.matches_interface(m_interface) && swpart.is_compatible(*m_swlist) == SOFTWARE_IS_COMPATIBLE)
{
entry_updated = TRUE;
// allocate a new entry
Expand Down
5 changes: 4 additions & 1 deletion src/mame/drivers/megadriv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -406,6 +406,9 @@ static MACHINE_CONFIG_START( ms_megadpal, md_cons_state )
MCFG_SOFTWARE_LIST_ADD("cart_list","megadriv")
MACHINE_CONFIG_END

static MACHINE_CONFIG_DERIVED( genesis_tmss, ms_megadriv )
MCFG_SOFTWARE_LIST_FILTER("cart_list","TMSS")
MACHINE_CONFIG_END



Expand Down Expand Up @@ -1058,7 +1061,7 @@ CONS( 1990, megadriv, genesis, 0, ms_megadpal, md, md_cons_state,
CONS( 1988, megadrij, genesis, 0, ms_megadriv, md, md_cons_state, md_jpn, "Sega", "Mega Drive (Japan, NTSC)", MACHINE_SUPPORTS_SAVE )

// 1990+ models had the TMSS security chip, leave this as a clone, it reduces compatibility and nothing more.
CONS( 1990, genesis_tmss, genesis, 0, ms_megadriv, md, md_cons_state, genesis, "Sega", "Genesis (USA, NTSC, with TMSS chip)", MACHINE_SUPPORTS_SAVE )
CONS( 1990, genesis_tmss, genesis, 0, genesis_tmss, md, md_cons_state, genesis, "Sega", "Genesis (USA, NTSC, with TMSS chip)", MACHINE_SUPPORTS_SAVE )


// the 32X plugged in the cart slot, games plugged into the 32x. Maybe it should be handled as an expansion device?
Expand Down