mirror of
https://github.com/TomHarte/CLK.git
synced 2024-12-23 20:29:42 +00:00
The Sega static analyser now attempts to differentiate region and paging scheme.
This commit is contained in:
parent
c365cca38a
commit
f0b6c406ff
@ -11,6 +11,9 @@
|
||||
#include "Target.hpp"
|
||||
|
||||
Analyser::Static::TargetList Analyser::Static::Sega::GetTargets(const Media &media, const std::string &file_name, TargetPlatform::IntType potential_platforms) {
|
||||
if(media.cartridges.empty())
|
||||
return {};
|
||||
|
||||
TargetList targets;
|
||||
std::unique_ptr<Target> target(new Target);
|
||||
|
||||
@ -23,10 +26,53 @@ Analyser::Static::TargetList Analyser::Static::Sega::GetTargets(const Media &med
|
||||
target->model = Target::Model::MasterSystem;
|
||||
}
|
||||
|
||||
// If this is a Master System title, look for a ROM header.
|
||||
if(target->model == Target::Model::MasterSystem) {
|
||||
const auto &data = media.cartridges.front()->get_segments()[0].data;
|
||||
|
||||
// First try to locate a header.
|
||||
size_t header_offset = 0;
|
||||
size_t potential_offsets[] = {0x1ff0, 0x3ff0, 0x7ff0};
|
||||
for(auto potential_offset: potential_offsets) {
|
||||
if(!memcmp(&data[potential_offset], "TMR SEGA", 8)) {
|
||||
header_offset = potential_offset;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// If a header was found, use it to crib region.
|
||||
if(header_offset) {
|
||||
// Treat export titles as European by default; decline to
|
||||
// do so only if (US) or (NTSC) is in the file name.
|
||||
const uint8_t region = data[header_offset + 0x0f] >> 4;
|
||||
switch(region) {
|
||||
default: break;
|
||||
case 4: {
|
||||
std::string lowercase_name = file_name;
|
||||
std::transform(lowercase_name.begin(), lowercase_name.end(), lowercase_name.begin(), ::tolower);
|
||||
if(lowercase_name.find("(jp)") != std::string::npos) {
|
||||
target->region =
|
||||
(lowercase_name.find("(us)") == std::string::npos &&
|
||||
lowercase_name.find("(ntsc)") == std::string::npos) ? Target::Region::Europe : Target::Region::USA;
|
||||
}
|
||||
} break;
|
||||
}
|
||||
|
||||
// Also check for a Codemasters header.
|
||||
// If one is found, set the paging scheme appropriately.
|
||||
const uint16_t inverse_checksum = uint16_t(0x10000 - (data[0x7fe6] | (data[0x7fe7] << 8)));
|
||||
if(
|
||||
data[0x7fe3] >= 0x87 && data[0x7fe3] < 0x96 && // i.e. game is dated between 1987 and 1996
|
||||
(inverse_checksum&0xff) == data[0x7fe8] &&
|
||||
(inverse_checksum >> 8) == data[0x7fe9] && // i.e. the standard checksum appears to be present
|
||||
!data[0x7fea] && !data[0x7feb] && !data[0x7fec] && !data[0x7fed] && !data[0x7fee] && !data[0x7fef]
|
||||
) {
|
||||
target->paging_scheme = Target::PagingScheme::Codemasters;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
target->media.cartridges = media.cartridges;
|
||||
|
||||
if(!target->media.empty())
|
||||
targets.push_back(std::move(target));
|
||||
|
||||
targets.push_back(std::move(target));
|
||||
return targets;
|
||||
}
|
||||
|
@ -19,7 +19,20 @@ struct Target: public ::Analyser::Static::Target {
|
||||
SG1000
|
||||
};
|
||||
|
||||
enum class Region {
|
||||
Japan,
|
||||
USA,
|
||||
Europe
|
||||
};
|
||||
|
||||
enum class PagingScheme {
|
||||
Sega,
|
||||
Codemasters
|
||||
};
|
||||
|
||||
Model model = Model::MasterSystem;
|
||||
Region region = Region::Japan;
|
||||
PagingScheme paging_scheme = PagingScheme::Sega;
|
||||
};
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user