Changes by Harry Tuttle: game list more accurately reflects MAME's, added a root level XML "games" node, print ROM version along with title

This commit is contained in:
Bart Trzynadlowski 2017-04-05 05:35:45 +00:00
parent f6707ecfba
commit c013eab711
4 changed files with 2677 additions and 2496 deletions

File diff suppressed because it is too large Load diff

View file

@ -237,79 +237,84 @@ bool GameLoader::LoadGamesFromXML(const Util::Config::Node &xml)
{ {
for (auto it = xml.begin(); it != xml.end(); ++it) for (auto it = xml.begin(); it != xml.end(); ++it)
{ {
// Game node // Root games node
auto &game_node = *it; auto &root_node = *it;
if (game_node.Key() != "game") if (root_node.Key() != "games")
continue; continue;
if (game_node["name"].Empty()) for (auto &game_node: root_node)
{ {
//TODO: associate line numbers in config // Game node
//ErrorLog("%s: Ignoring <game> tag with missing 'name' attribute.", m_xml_filename.c_str()); if (game_node.Key() != "game")
continue;
}
std::string game_name = game_node["name"].ValueAs<std::string>();
if (m_regions_by_game.find(game_name) != m_regions_by_game.end())
{
ErrorLog("%s: Ignoring redefinition of game '%s'.", m_xml_filename.c_str(), game_name.c_str());
continue;
}
RegionsByName_t &regions_by_name = m_regions_by_game[game_name];
PopulateGameInfo(&m_game_info_by_game[game_name], game_node);
for (auto &roms_node: game_node)
{
if (roms_node.Key() != "roms")
continue; continue;
if (game_node["name"].Empty())
/*
* Regions define contiguous memory areas that individual ROM files are
* loaded into. It is possible to have multiple region tags identifying
* the same region. They will be aggregated. This is useful for parent
* and child ROM sets, which each may need to define the same region,
* with the child set loading in different files to overwrite the parent
* set.
*/
for (auto &region_node: roms_node)
{ {
if (region_node.Key() != "region") //TODO: associate line numbers in config
continue; //ErrorLog("%s: Ignoring <game> tag with missing 'name' attribute.", m_xml_filename.c_str());
continue;
}
std::string game_name = game_node["name"].ValueAs<std::string>();
if (m_regions_by_game.find(game_name) != m_regions_by_game.end())
{
ErrorLog("%s: Ignoring redefinition of game '%s'.", m_xml_filename.c_str(), game_name.c_str());
continue;
}
RegionsByName_t &regions_by_name = m_regions_by_game[game_name];
PopulateGameInfo(&m_game_info_by_game[game_name], game_node);
// Look up region structure or create new one if needed for (auto &roms_node: game_node)
std::string region_name = region_node["name"].Value<std::string>(); {
auto it = regions_by_name.find(region_name); if (roms_node.Key() != "roms")
Region::ptr_t region = (it != regions_by_name.end()) ? it->second : Region::Create(*this, region_node);
if (!region)
continue; continue;
/* /*
* Files are defined by the offset they are loaded at. Normally, there * Regions define contiguous memory areas that individual ROM files are
* should be one file per offset but parent/child ROM sets will violate * loaded into. It is possible to have multiple region tags identifying
* this, and so it is allowed. * the same region. They will be aggregated. This is useful for parent
* and child ROM sets, which each may need to define the same region,
* with the child set loading in different files to overwrite the parent
* set.
*/ */
std::vector<File::ptr_t> &files = region->files; for (auto &region_node: roms_node)
for (auto &file_node: region_node)
{ {
if (file_node.Key() != "file") if (region_node.Key() != "region")
continue; continue;
File::ptr_t file = File::Create(*this, file_node);
if (!file) // Look up region structure or create new one if needed
std::string region_name = region_node["name"].Value<std::string>();
auto it = regions_by_name.find(region_name);
Region::ptr_t region = (it != regions_by_name.end()) ? it->second : Region::Create(*this, region_node);
if (!region)
continue; continue;
files.push_back(file);
/*
* Files are defined by the offset they are loaded at. Normally, there
* should be one file per offset but parent/child ROM sets will violate
* this, and so it is allowed.
*/
std::vector<File::ptr_t> &files = region->files;
for (auto &file_node: region_node)
{
if (file_node.Key() != "file")
continue;
File::ptr_t file = File::Create(*this, file_node);
if (!file)
continue;
files.push_back(file);
}
// Check to ensure that some files were defined in the region
if (files.empty())
ErrorLog("%s: No files defined in region '%s' of '%s'.", m_xml_filename.c_str(), region->region_name.c_str(), game_name.c_str());
else
regions_by_name[region->region_name] = region;
} }
// Check to ensure that some files were defined in the region
if (files.empty())
ErrorLog("%s: No files defined in region '%s' of '%s'.", m_xml_filename.c_str(), region->region_name.c_str(), game_name.c_str());
else
regions_by_name[region->region_name] = region;
} }
// Check to ensure that some ROM regions were defined for the game
if (regions_by_name.empty())
ErrorLog("%s: No ROM regions defined for '%s'.", m_xml_filename.c_str(), game_name.c_str());
} }
// Check to ensure that some ROM regions were defined for the game
if (regions_by_name.empty())
ErrorLog("%s: No ROM regions defined for '%s'.", m_xml_filename.c_str(), game_name.c_str());
} }
// Check to ensure some games were defined // Check to ensure some games were defined
if (m_regions_by_game.empty()) if (m_regions_by_game.empty())
{ {

View file

@ -2551,7 +2551,7 @@ void CModel3::Reset(void)
// Apply patches to games // Apply patches to games
static void Patch(uint8_t *crom, const Game &game) static void Patch(uint8_t *crom, const Game &game)
{ {
if (game.name == "scudp") if (game.name == "scudplus" || game.name == "scudplusa") // No patching?
{ {
// Base offset of program in CROM: 0x710000 // Base offset of program in CROM: 0x710000
} }
@ -2568,7 +2568,7 @@ static void Patch(uint8_t *crom, const Game &game)
{ {
*(UINT32 *) &crom[0x7374f4] = 0x38840004; // an actual bug in the game code *(UINT32 *) &crom[0x7374f4] = 0x38840004; // an actual bug in the game code
} }
else if (game.name == "vs215" || game.name == "vs215o" || game.name == "vs29815") else if (game.name == "vs215" || game.name == "vs215o" || game.name == "vs29815" || game.name == "vs29915")
{ {
// VS215 is a modification of VS2 that runs on Step 1.5 hardware. I // VS215 is a modification of VS2 that runs on Step 1.5 hardware. I
// suspect the code here is trying to detect the system type but am too // suspect the code here is trying to detect the system type but am too
@ -2590,13 +2590,13 @@ static void Patch(uint8_t *crom, const Game &game)
*(UINT32 *) &crom[0x7C0C8] = 0x60000000; *(UINT32 *) &crom[0x7C0C8] = 0x60000000;
*(UINT32 *) &crom[0x7C0CC] = 0x60000000; *(UINT32 *) &crom[0x7C0CC] = 0x60000000;
} }
else if (game.name == "harley") else if (game.name == "harleya")
{ {
*(UINT32 *) &crom[0x50E8D4] = 0x60000000; *(UINT32 *) &crom[0x50E8D4] = 0x60000000;
*(UINT32 *) &crom[0x50E8F4] = 0x60000000; *(UINT32 *) &crom[0x50E8F4] = 0x60000000;
*(UINT32 *) &crom[0x50FB84] = 0x60000000; *(UINT32 *) &crom[0x50FB84] = 0x60000000;
} }
else if (game.name == "harleyb") else if (game.name == "harley")
{ {
*(UINT32 *) &crom[0x50ECB4] = 0x60000000; *(UINT32 *) &crom[0x50ECB4] = 0x60000000;
*(UINT32 *) &crom[0x50ECD4] = 0x60000000; *(UINT32 *) &crom[0x50ECD4] = 0x60000000;
@ -2613,7 +2613,7 @@ static void Patch(uint8_t *crom, const Game &game)
{ {
*(UINT32 *) &crom[0xF6DD0] = 0x60000000; // from MAME *(UINT32 *) &crom[0xF6DD0] = 0x60000000; // from MAME
} }
else if (game.name == "eca" || game.name == "ecax") else if (game.name == "eca" || game.name == "ecau")
{ {
*(UINT32 *) &crom[0x535580] = 0x60000000; *(UINT32 *) &crom[0x535580] = 0x60000000;
//*(UINT32 *) &crom[0x5023B4] = 0x60000000; //*(UINT32 *) &crom[0x5023B4] = 0x60000000;
@ -2819,7 +2819,10 @@ bool CModel3::LoadGame(const Game &game, const ROMSet &rom_set)
extra_hw.insert("Drive Board"); extra_hw.insert("Drive Board");
if (game.encryption_key) if (game.encryption_key)
extra_hw.insert("Security Board"); extra_hw.insert("Security Board");
std::cout << " Title: " << game.title << std::endl; if (!game.version.empty())
std::cout << " Title: " << game.title << " (" << game.version << ")" << std::endl;
else
std::cout << " Title: " << game.title << std::endl;
std::cout << " ROM Set: " << game.name << std::endl; std::cout << " ROM Set: " << game.name << std::endl;
std::cout << " Developer: " << game.manufacturer << std::endl; std::cout << " Developer: " << game.manufacturer << std::endl;
std::cout << " Year: " << game.year << std::endl; std::cout << " Year: " << game.year << std::endl;

View file

@ -1220,7 +1220,10 @@ static void PrintGameList(const std::string &xml_file, const std::map<std::strin
printf(" %s", game.name.c_str()); printf(" %s", game.name.c_str());
for (int i = game.name.length(); i < 9; i++) // pad for alignment (no game ID should be more than 9 letters) for (int i = game.name.length(); i < 9; i++) // pad for alignment (no game ID should be more than 9 letters)
printf(" "); printf(" ");
printf(" %s\n", game.title.c_str()); if (!game.version.empty())
printf(" %s (%s)\n", game.title.c_str(), game.version.c_str());
else
printf(" %s\n", game.title.c_str());
} }
} }