mirror of
https://github.com/RetroDECK/Supermodel.git
synced 2024-11-25 07:05:40 +00:00
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:
parent
f6707ecfba
commit
c013eab711
4908
Config/Games.xml
4908
Config/Games.xml
File diff suppressed because it is too large
Load diff
|
@ -234,85 +234,90 @@ static void PopulateGameInfo(Game *game, const Util::Config::Node &game_node)
|
|||
}
|
||||
|
||||
bool GameLoader::LoadGamesFromXML(const Util::Config::Node &xml)
|
||||
{
|
||||
for (auto it = xml.begin(); it != xml.end(); ++it)
|
||||
{
|
||||
// Game node
|
||||
auto &game_node = *it;
|
||||
if (game_node.Key() != "game")
|
||||
continue;
|
||||
if (game_node["name"].Empty())
|
||||
{
|
||||
//TODO: associate line numbers in config
|
||||
//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 ®ions_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;
|
||||
|
||||
/*
|
||||
* 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 ®ion_node: roms_node)
|
||||
{
|
||||
if (region_node.Key() != "region")
|
||||
continue;
|
||||
|
||||
// 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;
|
||||
|
||||
/*
|
||||
* 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 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
|
||||
if (m_regions_by_game.empty())
|
||||
{
|
||||
{
|
||||
for (auto it = xml.begin(); it != xml.end(); ++it)
|
||||
{
|
||||
// Root games node
|
||||
auto &root_node = *it;
|
||||
if (root_node.Key() != "games")
|
||||
continue;
|
||||
for (auto &game_node: root_node)
|
||||
{
|
||||
// Game node
|
||||
if (game_node.Key() != "game")
|
||||
continue;
|
||||
if (game_node["name"].Empty())
|
||||
{
|
||||
//TODO: associate line numbers in config
|
||||
//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 ®ions_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;
|
||||
|
||||
/*
|
||||
* 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 ®ion_node: roms_node)
|
||||
{
|
||||
if (region_node.Key() != "region")
|
||||
continue;
|
||||
|
||||
// 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;
|
||||
|
||||
/*
|
||||
* 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 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
|
||||
if (m_regions_by_game.empty())
|
||||
{
|
||||
ErrorLog("%s: No games defined.", m_xml_filename.c_str());
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -2548,13 +2548,13 @@ void CModel3::Reset(void)
|
|||
Initialization, Shutdown, and ROM Management
|
||||
******************************************************************************/
|
||||
|
||||
// Apply patches to games
|
||||
static void Patch(uint8_t *crom, const Game &game)
|
||||
{
|
||||
if (game.name == "scudp")
|
||||
{
|
||||
// Base offset of program in CROM: 0x710000
|
||||
}
|
||||
// Apply patches to games
|
||||
static void Patch(uint8_t *crom, const Game &game)
|
||||
{
|
||||
if (game.name == "scudplus" || game.name == "scudplusa") // No patching?
|
||||
{
|
||||
// Base offset of program in CROM: 0x710000
|
||||
}
|
||||
else if (game.name == "lemans24")
|
||||
{
|
||||
// Base offset of program in CROM: 6473C0
|
||||
|
@ -2565,13 +2565,13 @@ static void Patch(uint8_t *crom, const Game &game)
|
|||
*(UINT32 *) &crom[0x73EDC4] = 0x60000000;
|
||||
}
|
||||
else if (game.name == "lostwsga")
|
||||
{
|
||||
*(UINT32 *) &crom[0x7374f4] = 0x38840004; // an actual bug in the game code
|
||||
}
|
||||
else if (game.name == "vs215" || game.name == "vs215o" || game.name == "vs29815")
|
||||
{
|
||||
// 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
|
||||
{
|
||||
*(UINT32 *) &crom[0x7374f4] = 0x38840004; // an actual bug in the game code
|
||||
}
|
||||
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
|
||||
// suspect the code here is trying to detect the system type but am too
|
||||
// lazy to figure it out right now.
|
||||
*(UINT32 *) &crom[0x7001A8] = 0x48000000+(0xFFF01630-0xFFF001A8); // force a jump to FFF01630
|
||||
}
|
||||
|
@ -2587,19 +2587,19 @@ static void Patch(uint8_t *crom, const Game &game)
|
|||
else if (game.name == "srally2")
|
||||
{
|
||||
*(UINT32 *) &crom[0x7C0C4] = 0x60000000;
|
||||
*(UINT32 *) &crom[0x7C0C8] = 0x60000000;
|
||||
*(UINT32 *) &crom[0x7C0CC] = 0x60000000;
|
||||
}
|
||||
else if (game.name == "harley")
|
||||
{
|
||||
*(UINT32 *) &crom[0x50E8D4] = 0x60000000;
|
||||
*(UINT32 *) &crom[0x50E8F4] = 0x60000000;
|
||||
*(UINT32 *) &crom[0x50FB84] = 0x60000000;
|
||||
}
|
||||
else if (game.name == "harleyb")
|
||||
{
|
||||
*(UINT32 *) &crom[0x50ECB4] = 0x60000000;
|
||||
*(UINT32 *) &crom[0x50ECD4] = 0x60000000;
|
||||
*(UINT32 *) &crom[0x7C0C8] = 0x60000000;
|
||||
*(UINT32 *) &crom[0x7C0CC] = 0x60000000;
|
||||
}
|
||||
else if (game.name == "harleya")
|
||||
{
|
||||
*(UINT32 *) &crom[0x50E8D4] = 0x60000000;
|
||||
*(UINT32 *) &crom[0x50E8F4] = 0x60000000;
|
||||
*(UINT32 *) &crom[0x50FB84] = 0x60000000;
|
||||
}
|
||||
else if (game.name == "harley")
|
||||
{
|
||||
*(UINT32 *) &crom[0x50ECB4] = 0x60000000;
|
||||
*(UINT32 *) &crom[0x50ECD4] = 0x60000000;
|
||||
*(UINT32 *) &crom[0x50FF64] = 0x60000000;
|
||||
}
|
||||
else if (game.name == "swtrilgy")
|
||||
|
@ -2610,13 +2610,13 @@ static void Patch(uint8_t *crom, const Game &game)
|
|||
*(UINT32 *) &crom[0x02A0C] = 0x60000000;
|
||||
}
|
||||
else if (game.name == "swtrilgya")
|
||||
{
|
||||
*(UINT32 *) &crom[0xF6DD0] = 0x60000000; // from MAME
|
||||
}
|
||||
else if (game.name == "eca" || game.name == "ecax")
|
||||
{
|
||||
*(UINT32 *) &crom[0x535580] = 0x60000000;
|
||||
//*(UINT32 *) &crom[0x5023B4] = 0x60000000;
|
||||
{
|
||||
*(UINT32 *) &crom[0xF6DD0] = 0x60000000; // from MAME
|
||||
}
|
||||
else if (game.name == "eca" || game.name == "ecau")
|
||||
{
|
||||
*(UINT32 *) &crom[0x535580] = 0x60000000;
|
||||
//*(UINT32 *) &crom[0x5023B4] = 0x60000000;
|
||||
//*(UINT32 *) &crom[0x5023D4] = 0x60000000;
|
||||
}
|
||||
}
|
||||
|
@ -2816,13 +2816,16 @@ bool CModel3::LoadGame(const Game &game, const ROMSet &rom_set)
|
|||
if (DSB)
|
||||
extra_hw.insert(Util::Format() << "Digital Sound Board (Type " << game.mpeg_board << ")");
|
||||
if (rom_set.get_rom("driveboard_program").size)
|
||||
extra_hw.insert("Drive Board");
|
||||
if (game.encryption_key)
|
||||
extra_hw.insert("Security Board");
|
||||
std::cout << " Title: " << game.title << std::endl;
|
||||
std::cout << " ROM Set: " << game.name << std::endl;
|
||||
std::cout << " Developer: " << game.manufacturer << std::endl;
|
||||
std::cout << " Year: " << game.year << std::endl;
|
||||
extra_hw.insert("Drive Board");
|
||||
if (game.encryption_key)
|
||||
extra_hw.insert("Security Board");
|
||||
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 << " Developer: " << game.manufacturer << std::endl;
|
||||
std::cout << " Year: " << game.year << std::endl;
|
||||
std::cout << " Stepping: " << game.stepping << std::endl;
|
||||
if (!extra_hw.empty())
|
||||
std::cout << " Extra Hardware: " << Util::Format(", ").Join(extra_hw) << std::endl;
|
||||
|
|
|
@ -1217,13 +1217,16 @@ static void PrintGameList(const std::string &xml_file, const std::map<std::strin
|
|||
for (auto &v: games)
|
||||
{
|
||||
const Game &game = v.second;
|
||||
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)
|
||||
printf(" ");
|
||||
printf(" %s\n", game.title.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)
|
||||
printf(" ");
|
||||
if (!game.version.empty())
|
||||
printf(" %s (%s)\n", game.title.c_str(), game.version.c_str());
|
||||
else
|
||||
printf(" %s\n", game.title.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
static void LogConfig(const Util::Config::Node &config)
|
||||
{
|
||||
InfoLog("Runtime configuration:");
|
||||
|
|
Loading…
Reference in a new issue