mirror of
https://github.com/holub/mame
synced 2025-06-04 03:46:29 +03:00
102 lines
2.6 KiB
C++
102 lines
2.6 KiB
C++
// license:BSD-3-Clause
|
|
// copyright-holders:Nathan Woods
|
|
/*********************************************************************
|
|
|
|
hashfile.c
|
|
|
|
Code for parsing hash info (*.hsi) files
|
|
|
|
*********************************************************************/
|
|
|
|
#include "emu.h"
|
|
#include "hashfile.h"
|
|
#include "pool.h"
|
|
#include "emuopts.h"
|
|
#include "hash.h"
|
|
#include "drivenum.h"
|
|
#include <pugixml.hpp>
|
|
|
|
/*-------------------------------------------------
|
|
hashfile_lookup
|
|
-------------------------------------------------*/
|
|
|
|
static bool read_hash_config(const char *hash_path, const util::hash_collection &hashes, const char *sysname, std::string &result)
|
|
{
|
|
/* open a file */
|
|
emu_file file(hash_path, OPEN_FLAG_READ);
|
|
if (file.open(sysname, ".hsi") != osd_file::error::NONE)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
pugi::xml_document doc;
|
|
|
|
pugi::xml_parse_result res = doc.load_file(file.fullpath());
|
|
if (res)
|
|
{
|
|
// Do search by CRC32 and SHA1
|
|
std::string query = "/hashfile/hash[";
|
|
auto crc = hashes.internal_string().substr(1,8);
|
|
auto sha1 = hashes.internal_string().substr(10, 40);
|
|
query += "@crc32='" + crc + "' and @sha1='" + sha1 + "']/extrainfo";
|
|
pugi::xpath_node_set tools = doc.select_nodes(query.c_str());
|
|
for (pugi::xpath_node_set::const_iterator it = tools.begin(); it != tools.end(); ++it)
|
|
{
|
|
result = it->node().first_child().value();
|
|
return true;
|
|
}
|
|
|
|
// Try search by CRC32 only
|
|
query = "/hashfile/hash[";
|
|
query += "@crc32='" + crc + "']/extrainfo";
|
|
tools = doc.select_nodes(query.c_str());
|
|
for (pugi::xpath_node_set::const_iterator it = tools.begin(); it != tools.end(); ++it)
|
|
{
|
|
result = it->node().first_child().value();
|
|
return true;
|
|
}
|
|
|
|
}
|
|
return false;
|
|
}
|
|
|
|
|
|
bool hashfile_extrainfo(const char *hash_path, const game_driver &driver, const util::hash_collection &hashes, std::string &result)
|
|
{
|
|
/* now read the hash file */
|
|
int drv = driver_list::find(driver);
|
|
int compat, open = drv;
|
|
bool hashfound;
|
|
do
|
|
{
|
|
hashfound = read_hash_config(hash_path, hashes, driver_list::driver(open).name, result);
|
|
// first check if there are compatible systems
|
|
compat = driver_list::compatible_with(open);
|
|
// if so, try to open its hashfile
|
|
if (compat != -1)
|
|
open = compat;
|
|
// otherwise, try with the parent
|
|
else
|
|
{
|
|
drv = driver_list::clone(drv);
|
|
open = drv;
|
|
}
|
|
}
|
|
// if no extrainfo has been found but we can try a compatible or a parent set, go back
|
|
while (!hashfound && open != -1);
|
|
return hashfound;
|
|
}
|
|
|
|
|
|
|
|
bool hashfile_extrainfo(device_image_interface &image, std::string &result)
|
|
{
|
|
return hashfile_extrainfo(
|
|
image.device().mconfig().options().hash_path(),
|
|
image.device().mconfig().gamedrv(),
|
|
image.hash(),
|
|
result);
|
|
}
|
|
|
|
|