1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84
|
struct MegaCD : CompactDisc {
auto name() -> string override { return "Mega CD"; }
auto extensions() -> vector<string> override { return {"mcd", "cue"}; }
auto load(string location) -> bool override;
auto save(string location) -> bool override;
auto analyze(string location) -> string;
};
auto MegaCD::load(string location) -> bool {
if(!inode::exists(location)) return false;
this->location = location;
this->manifest = analyze(location);
auto document = BML::unserialize(manifest);
if(!document) return false;
pak = new vfs::directory;
pak->setAttribute("title", document["game/title"].string());
pak->setAttribute("region", document["game/region"].string());
pak->append("manifest.bml", manifest);
if(directory::exists(location)) {
pak->append("cd.rom", vfs::disk::open({location, "cd.rom"}, vfs::read));
}
if(file::exists(location)) {
pak->append("cd.rom", vfs::cdrom::open(location));
}
return true;
}
auto MegaCD::save(string location) -> bool {
auto document = BML::unserialize(manifest);
return true;
}
auto MegaCD::analyze(string location) -> string {
auto sector = readDataSectorCUE(location, 0);
if(!sector || memory::compare(sector.data(), "SEGA", 4))
return CompactDisc::manifestAudio(location);
vector<string> regions;
if(!memory::compare(sector.data()+4, "DISCSYSTEM ", 12)
|| !memory::compare(sector.data()+4, "BOOTDISC ", 12)) {
if( Hash::CRC32({sector.data()+0x200, 340}).value() == 0x4571f623) // JP boot
regions.append("NTSC-J");
else if(Hash::CRC32({sector.data()+0x200, 1390}).value() == 0x6ffb4732) // EU boot
regions.append("PAL");
else if(Hash::CRC32({sector.data()+0x200, 1412}).value() == 0xf361ab57) // US boot
regions.append("NTSC-U");
}
if(!regions) regions.append("NTSC-J","NTSC-U","PAL"); // unknown boot
vector<string> devices;
string device = slice((const char*)(sector.data() + 0x190), 0, 16).trimRight(" ");
for(auto& id : device) {
if(id == '0'); //Master System controller
if(id == '4'); //multitap
if(id == '6'); //6-button controller
if(id == 'A'); //analog joystick
if(id == 'B'); //trackball
if(id == 'C'); //CD-ROM drive
if(id == 'D'); //download?
if(id == 'F'); //floppy drive
if(id == 'G'); //light gun
if(id == 'J'); //3-button controller
if(id == 'K'); //keyboard
if(id == 'L'); //Activator
if(id == 'M'); //mouse
if(id == 'P'); //printer
if(id == 'R'); //RS-232 modem
if(id == 'T'); //tablet
if(id == 'V'); //paddle
}
string s;
s += "game\n";
s +={" name: ", Medium::name(location), "\n"};
s +={" title: ", Medium::name(location), "\n"};
s +={" region: ", regions.merge(", "), "\n"};
if(devices)
s +={" device: ", devices.merge(", "), "\n"};
return s;
}
|