diff --git a/src/BizHawk.Emulation.DiscSystem/DiscIdentifier.cs b/src/BizHawk.Emulation.DiscSystem/DiscIdentifier.cs index 43a73ff6f7..6485de06b3 100644 --- a/src/BizHawk.Emulation.DiscSystem/DiscIdentifier.cs +++ b/src/BizHawk.Emulation.DiscSystem/DiscIdentifier.cs @@ -44,6 +44,11 @@ namespace BizHawk.Emulation.DiscSystem /// TurboCD, + /// + /// PC Engine "GECD" for unlicensed games + /// + TurboGECD, + /// /// MegaDrive add-on /// @@ -123,8 +128,11 @@ namespace BizHawk.Emulation.DiscSystem if (DetectPCFX()) return DiscType.PCFX; + if (DetectTurboGECD()) + return DiscType.TurboGECD; + if (DetectTurboCD()) - return DiscType.TurboCD; + return DiscType.TurboCD; //check track 1's data type. if it's an audio track, further data-track testing is useless //furthermore, it's probably senseless (no binary data there to read) @@ -260,6 +268,35 @@ namespace BizHawk.Emulation.DiscSystem return false; } + private bool DetectTurboGECD() + { + //approach taken from mednafen DetectGECD() + + //check for appropriate structure + var toc = _disc.TOC; + if (toc.FirstRecordedTrackNumber != 1) return false; + if (!toc.TOCItems[1].IsData) return false; + + //some have a signature + if (StringAt("HACKER CD ROM SYSTEM", 0x8, 0x10)) + return true; + + //some are more confusing + if (!StringAt("CD001", 0x1, 0x10)) + return false; + + byte[] sector20 = ReadDataSectorCached(20); + uint zecrc = (uint)BizHawk.Common.CRC32.Calculate(sector20); + + //known_crcs + if (zecrc == 0xd7b47c06) return true; // AV Tanjou + if (zecrc == 0x86aec522) return true; // Bishoujo Jyanshi [...] + if (zecrc == 0xc8d1b5ef) return true; // CD Bishoujo [...] + if (zecrc == 0x0bdbde64) return true; // CD Pachisuro [...] + + return false; + } + //asni 20171011 - this ONLY works if a valid cuefile/ccd is passed into DiscIdentifier. //if an .iso is presented, the internally manufactured cue data does not work - possibly something to do with //track 01 being Audio. Not tested, but presumably PCFX has the same issue @@ -311,7 +348,7 @@ namespace BizHawk.Emulation.DiscSystem private bool DetectGameCube() { - var data = ReadSectorCached(0); + var data = ReadDataSectorCached(0); if (data == null) return false; byte[] magic = data.Skip(28).Take(4).ToArray(); string hexString = ""; @@ -323,7 +360,7 @@ namespace BizHawk.Emulation.DiscSystem private bool DetectWii() { - var data = ReadSectorCached(0); + var data = ReadDataSectorCached(0); if (data == null) return false; byte[] magic = data.Skip(24).Take(4).ToArray(); string hexString = ""; @@ -333,7 +370,7 @@ namespace BizHawk.Emulation.DiscSystem return hexString == "5D1C9EA3"; } - private byte[] ReadSectorCached(int lba) + private byte[] ReadDataSectorCached(int lba) { //read it if we don't have it cached //we wont be caching very much here, it's no big deal @@ -349,19 +386,19 @@ namespace BizHawk.Emulation.DiscSystem return data; } - private bool StringAt(string s, int n, int lba = 0) + private bool StringAt(string s, int offset, int lba = 0) { - var data = ReadSectorCached(lba); + var data = ReadDataSectorCached(lba); if (data == null) return false; byte[] cmp = Encoding.ASCII.GetBytes(s); byte[] cmp2 = new byte[cmp.Length]; - Buffer.BlockCopy(data, n, cmp2, 0, cmp.Length); + Buffer.BlockCopy(data, offset, cmp2, 0, cmp.Length); return cmp.SequenceEqual(cmp2); } private bool SectorContains(string s, int lba = 0) { - var data = ReadSectorCached(lba); + var data = ReadDataSectorCached(lba); return data != null && Encoding.ASCII.GetString(data).ToLower().Contains(s.ToLower()); } }