using System;
//disc type identification logic
namespace BizHawk.Emulation.DiscSystem
{
public enum DiscType
{
///
/// Nothing is known about this disc type
///
UnknownFormat,
///
/// This is definitely a CDFS disc, but we can't identify anything more about it
///
UnknownCDFS,
///
/// Sony PSX
///
SonyPSX,
///
/// Sony PSP
///
SonyPSP,
///
/// Sega Saturn
///
SegaSaturn,
///
/// Its not clear whether we can ever have enough info to ID a turboCD disc (we're using hashes)
///
TurboCD,
///
/// MegaDrive addon
///
MegaCD
}
sealed public partial class Disc
{
///
/// Attempts to determine the type of the disc.
/// In the future, we might return a struct or a class with more detailed information
///
public DiscType DetectDiscType()
{
//sega doesnt put anything identifying in the cdfs volume info. but its consistent about putting its own header here in sector 0
if (DetectSegaSaturn()) return DiscType.SegaSaturn;
// not fully tested yet
if (DetectMegaCD()) return DiscType.MegaCD;
//we dont know how to detect TurboCD.
//an emulator frontend will likely just guess TurboCD if the disc is UnknownFormat
var iso = new ISOFile();
bool isIso = iso.Parse(DiscStream.Open_LBA_2048(this));
if (isIso)
{
var appId = System.Text.Encoding.ASCII.GetString(iso.VolumeDescriptors[0].ApplicationIdentifier).TrimEnd('\0', ' ');
if (appId == "PLAYSTATION")
return DiscType.SonyPSX;
if(appId == "PSP GAME")
return DiscType.SonyPSP;
return DiscType.UnknownCDFS;
}
return DiscType.UnknownFormat;
}
///
/// This is reasonable approach to ID saturn.
///
bool DetectSegaSaturn()
{
return StringAt("SEGA SEGASATURN", 0);
}
///
/// probably wrong
///
bool DetectMegaCD()
{
return StringAt("SEGADISCSYSTEM", 0) || StringAt("SEGADISCSYSTEM", 16);
}
private bool StringAt(string s, int n)
{
byte[] data = new byte[2048];
ReadLBA_2048(0, data, 0);
byte[] cmp = System.Text.Encoding.ASCII.GetBytes(s);
byte[] cmp2 = new byte[cmp.Length];
Buffer.BlockCopy(data, n, cmp2, 0, cmp.Length);
return System.Linq.Enumerable.SequenceEqual(cmp, cmp2);
}
}
}