diff --git a/src/BizHawk.Client.DiscoHawk/AudioExtractor.cs b/src/BizHawk.Client.DiscoHawk/AudioExtractor.cs index 93f782dddf..48f495fa55 100644 --- a/src/BizHawk.Client.DiscoHawk/AudioExtractor.cs +++ b/src/BizHawk.Client.DiscoHawk/AudioExtractor.cs @@ -45,8 +45,7 @@ namespace BizHawk.Client.DiscoHawk try { File.WriteAllBytes(tempfile, waveData); - var ffmpeg = new FFMpeg(); - ffmpeg.Run("-f", "s16le", "-ar", "44100", "-ac", "2", "-i", tempfile, "-f", "mp3", "-ab", "192k", mp3Path); + FFMpeg.Run("-f", "s16le", "-ar", "44100", "-ac", "2", "-i", tempfile, "-f", "mp3", "-ab", "192k", mp3Path); } finally { diff --git a/src/BizHawk.Emulation.DiscSystem/API_MednaDisc.cs b/src/BizHawk.Emulation.DiscSystem/API_MednaDisc.cs index 43b6579a0d..f9667cab46 100644 --- a/src/BizHawk.Emulation.DiscSystem/API_MednaDisc.cs +++ b/src/BizHawk.Emulation.DiscSystem/API_MednaDisc.cs @@ -91,7 +91,7 @@ namespace BizHawk.Emulation.DiscSystem } #endif - private static void CheckLibrary() + static MednaDisc() { var lib = OSTailoredCode.LinkedLibManager.LoadOrZero("mednadisc.dll"); _IsLibraryAvailable = lib != IntPtr.Zero @@ -99,11 +99,6 @@ namespace BizHawk.Emulation.DiscSystem if (lib != IntPtr.Zero) OSTailoredCode.LinkedLibManager.FreeByPtr(lib); } - static MednaDisc() - { - CheckLibrary(); - } - private static bool _IsLibraryAvailable; public static bool IsLibraryAvailable => _IsLibraryAvailable; diff --git a/src/BizHawk.Emulation.DiscSystem/CDFS/ISOFile.cs b/src/BizHawk.Emulation.DiscSystem/CDFS/ISOFile.cs index e3080c6d6b..60afdd8f6d 100644 --- a/src/BizHawk.Emulation.DiscSystem/CDFS/ISOFile.cs +++ b/src/BizHawk.Emulation.DiscSystem/CDFS/ISOFile.cs @@ -146,19 +146,33 @@ namespace BizHawk.Emulation.DiscSystem return true; } - - private List> fileNodes; - private List dirsParsed; - /// /// Returns a flat list of all recursed files /// public List> EnumerateAllFilesRecursively() { - fileNodes = new List>(); + var fileNodes = new List>(); if (Root.Children == null) return fileNodes; - dirsParsed = new List(); + var dirsParsed = new List(); + + void ProcessDirectoryFiles(Dictionary idn) + { + foreach (var n in idn) + { + if (n.Value is ISODirectoryNode subdirNode) + { + if (dirsParsed.Contains(subdirNode)) continue; + dirsParsed.Add(subdirNode); + ProcessDirectoryFiles(subdirNode.Children); + } + else + { + fileNodes.Add(new KeyValuePair(n.Key, n.Value as ISOFileNode)); + } + } + } + foreach (var idn in Root.Children.Values.OfType()) // iterate through each folder { // process all files in this directory (and recursively process files in subfolders) @@ -167,24 +181,6 @@ namespace BizHawk.Emulation.DiscSystem ProcessDirectoryFiles(idn.Children); } return fileNodes.Distinct().ToList(); - } - - private void ProcessDirectoryFiles(Dictionary idn) - { - foreach (var n in idn) - { - if (n.Value is ISODirectoryNode subdirNode) - { - if (dirsParsed.Contains(subdirNode)) continue; - dirsParsed.Add(subdirNode); - ProcessDirectoryFiles(subdirNode.Children); - } - else - { - KeyValuePair f = new KeyValuePair(n.Key, n.Value as ISOFileNode); - fileNodes.Add(f); - } - } } /// diff --git a/src/BizHawk.Emulation.DiscSystem/DiscDecoding.cs b/src/BizHawk.Emulation.DiscSystem/DiscDecoding.cs index 1763f5a25d..47e4bb6003 100644 --- a/src/BizHawk.Emulation.DiscSystem/DiscDecoding.cs +++ b/src/BizHawk.Emulation.DiscSystem/DiscDecoding.cs @@ -1,5 +1,4 @@ using System; -using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Text; @@ -17,11 +16,6 @@ namespace BizHawk.Emulation.DiscSystem public bool IsAudio; } - private static string[] Escape(IEnumerable args) - { - return args.Select(s => s.Contains(" ") ? $"\"{s}\"" : s).ToArray(); - } - //note: accepts . or : in the stream stream/substream separator in the stream ID format, since that changed at some point in FFMPEG history //if someone has a better idea how to make the determination of whether an audio stream is available, I'm all ears private static readonly Regex rxHasAudio = new Regex(@"Stream \#(\d*(\.|\:)\d*)\: Audio", RegexOptions.Compiled); @@ -55,9 +49,9 @@ namespace BizHawk.Emulation.DiscSystem public int ExitCode; } - public RunResults Run(params string[] args) + public static RunResults Run(params string[] args) { - args = Escape(args); + args = args.Select(s => s.Contains(" ") ? $"\"{s}\"" : s).ToArray(); StringBuilder sbCmdline = new StringBuilder(); for (int i = 0; i < args.Length; i++) { @@ -106,7 +100,7 @@ namespace BizHawk.Emulation.DiscSystem } } - internal class AudioDecoder + internal static class AudioDecoder { [Serializable] public class AudioDecoder_Exception : Exception @@ -117,50 +111,17 @@ namespace BizHawk.Emulation.DiscSystem } } - public AudioDecoder() - { - } - - private bool CheckForAudio(string path) - { - FFMpeg ffmpeg = new FFMpeg(); - var qa = ffmpeg.QueryAudio(path); - return qa.IsAudio; - } - - /// - /// finds audio at a path similar to the provided path (i.e. finds Track01.mp3 for Track01.wav) - /// TODO - isnt this redundant with CueFileResolver? - /// - private string FindAudio(string audioPath) - { - string basePath = Path.GetFileNameWithoutExtension(audioPath); - //look for potential candidates - var di = new DirectoryInfo(Path.GetDirectoryName(audioPath)); - var fis = di.GetFiles(); - //first, look for the file type we actually asked for - foreach (var fi in fis) - { - if (fi.FullName.ToUpper() == audioPath.ToUpper()) - if (CheckForAudio(fi.FullName)) - return fi.FullName; - } - //then look for any other type - foreach (var fi in fis) - { - if (Path.GetFileNameWithoutExtension(fi.FullName).ToUpper() == basePath.ToUpper()) - { - if (CheckForAudio(fi.FullName)) - { - return fi.FullName; - } - } - } - return null; - } - /// could not find source audio for - public byte[] AcquireWaveData(string audioPath) => new FFMpeg() - .DecodeAudio(FindAudio(audioPath) ?? throw new AudioDecoder_Exception($"Could not find source audio for: {Path.GetFileName(audioPath)}")); + public static byte[] AcquireWaveData(string audioPath) + { + // find audio at a path similar to the provided path (i.e. finds Track01.mp3 for Track01.wav) + // TODO isn't this redundant with CueFileResolver? + var basePath = Path.GetFileNameWithoutExtension(audioPath); + var files = new DirectoryInfo(Path.GetDirectoryName(audioPath)).GetFiles().Select(fi => fi.FullName).ToList(); + var found = files.Where(f => string.Equals(f, audioPath, StringComparison.InvariantCulture)) // first, look for the file type we actually asked for + .Concat(files.Where(f => string.Equals(Path.GetFileNameWithoutExtension(f), basePath, StringComparison.InvariantCulture))) // then, look for any other type + .FirstOrDefault(f => new FFMpeg().QueryAudio(f).IsAudio); // ignore false positives + return new FFMpeg().DecodeAudio(found ?? throw new AudioDecoder_Exception($"Could not find source audio for: {Path.GetFileName(audioPath)}")); + } } } \ No newline at end of file diff --git a/src/BizHawk.Emulation.DiscSystem/DiscFormats/Blobs/Blob_ECM.cs b/src/BizHawk.Emulation.DiscSystem/DiscFormats/Blobs/Blob_ECM.cs index 4dc18f0f9d..6f7ec5def0 100644 --- a/src/BizHawk.Emulation.DiscSystem/DiscFormats/Blobs/Blob_ECM.cs +++ b/src/BizHawk.Emulation.DiscSystem/DiscFormats/Blobs/Blob_ECM.cs @@ -67,6 +67,8 @@ namespace BizHawk.Emulation.DiscSystem public void Load(string path) { + const string MISFORMED_EXCEPTION_MESSAGE = "Mis-formed ECM file"; + stream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read); //skip header @@ -77,17 +79,17 @@ namespace BizHawk.Emulation.DiscSystem { //read block count. this format is really stupid. maybe its good for detecting non-ecm files or something. int b = stream.ReadByte(); - if (b == -1) MisformedException(); + if (b == -1) throw new InvalidOperationException(MISFORMED_EXCEPTION_MESSAGE); int bytes = 1; int T = b & 3; long N = (b >> 2) & 0x1F; int nbits = 5; while (b.Bit(7)) { - if (bytes == 5) MisformedException(); //if we're gonna need a 6th byte, this file is broken + if (bytes == 5) throw new InvalidOperationException(MISFORMED_EXCEPTION_MESSAGE); //if we're gonna need a 6th byte, this file is broken b = stream.ReadByte(); bytes++; - if (b == -1) MisformedException(); + if (b == -1) throw new InvalidOperationException(MISFORMED_EXCEPTION_MESSAGE); N |= (long)(b & 0x7F) << nbits; nbits += 7; } @@ -98,7 +100,7 @@ namespace BizHawk.Emulation.DiscSystem //the 0x80000000 business is confusing, but this is almost positively an error if (N >= 0x100000000) - MisformedException(); + throw new InvalidOperationException(MISFORMED_EXCEPTION_MESSAGE); uint todo = (uint)N + 1; @@ -132,7 +134,7 @@ namespace BizHawk.Emulation.DiscSystem stream.Seek(todo * 2328, SeekOrigin.Current); logOffset += todo * 2336; } - else MisformedException(); + else throw new InvalidOperationException(MISFORMED_EXCEPTION_MESSAGE); } //TODO - endian bug. need an endian-independent binary reader with good license (miscutils is apache license) @@ -143,11 +145,6 @@ namespace BizHawk.Emulation.DiscSystem Length = logOffset; } - private void MisformedException() - { - throw new InvalidOperationException("Mis-formed ECM file"); - } - public static bool IsECM(string path) { using (var fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read)) diff --git a/src/BizHawk.Emulation.DiscSystem/DiscFormats/Blobs/RiffMaster.cs b/src/BizHawk.Emulation.DiscSystem/DiscFormats/Blobs/RiffMaster.cs index da96c9d60a..9939914331 100644 --- a/src/BizHawk.Emulation.DiscSystem/DiscFormats/Blobs/RiffMaster.cs +++ b/src/BizHawk.Emulation.DiscSystem/DiscFormats/Blobs/RiffMaster.cs @@ -38,9 +38,6 @@ namespace BizHawk.Emulation.DiscSystem BaseStream = null; } - private static string ReadTag(BinaryReader br) => - string.Concat(br.ReadChar(), br.ReadChar(), br.ReadChar(), br.ReadChar()); - protected static void WriteTag(BinaryWriter bw, string tag) { for (int i = 0; i < 4; i++) @@ -278,7 +275,9 @@ namespace BizHawk.Emulation.DiscSystem private long readCounter; private RiffChunk ReadChunk(BinaryReader br) - { + { + static string ReadTag(BinaryReader br) => string.Concat(br.ReadChar(), br.ReadChar(), br.ReadChar(), br.ReadChar()); + RiffChunk ret; string tag = ReadTag(br); readCounter += 4; uint size = br.ReadUInt32(); readCounter += 4; diff --git a/src/BizHawk.Emulation.DiscSystem/DiscFormats/CCD_format.cs b/src/BizHawk.Emulation.DiscSystem/DiscFormats/CCD_format.cs index bf66dfd6e8..e317df6bcf 100644 --- a/src/BizHawk.Emulation.DiscSystem/DiscFormats/CCD_format.cs +++ b/src/BizHawk.Emulation.DiscSystem/DiscFormats/CCD_format.cs @@ -214,31 +214,18 @@ namespace BizHawk.Emulation.DiscSystem return sections; } - private int PreParseIntegrityCheck(List sections) - { - if (sections.Count == 0) throw new CCDParseException("Malformed CCD format: no sections"); - - //we need at least a CloneCD and Disc section - if (sections.Count < 2) throw new CCDParseException("Malformed CCD format: insufficient sections"); - - var ccdSection = sections[0]; - if (ccdSection.Name != "CLONECD") - throw new CCDParseException("Malformed CCD format: confusing first section name"); - - if (!ccdSection.ContainsKey("VERSION")) - throw new CCDParseException("Malformed CCD format: missing version in CloneCD section"); - - if(sections[1].Name != "DISC") - throw new CCDParseException("Malformed CCD format: section[1] isn't [Disc]"); - - int version = ccdSection["VERSION"]; - - return version; - } - /// parsed is 1, parsed session number is not 1, or malformed entry public CCDFile ParseFrom(Stream stream) { + static int PreParseIntegrityCheck(IReadOnlyList sections) + { + if (sections.Count == 0) throw new CCDParseException("Malformed CCD format: no sections"); + if (sections.Count < 2) throw new CCDParseException("Malformed CCD format: insufficient sections"); //we need at least a CloneCD and Disc section + if (sections[0].Name != "CLONECD") throw new CCDParseException("Malformed CCD format: confusing first section name"); + if (sections[1].Name != "DISC") throw new CCDParseException("Malformed CCD format: section[1] isn't [Disc]"); + return sections[0].TryGetValue("VERSION", out var version) ? version : throw new CCDParseException("Malformed CCD format: missing version in CloneCD section"); + } + CCDFile ccdf = new CCDFile(); var sections = ParseSections(stream); diff --git a/src/BizHawk.Emulation.DiscSystem/DiscFormats/CUE/CUE_Load.cs b/src/BizHawk.Emulation.DiscSystem/DiscFormats/CUE/CUE_Load.cs index 0c7231ac00..701e173bce 100644 --- a/src/BizHawk.Emulation.DiscSystem/DiscFormats/CUE/CUE_Load.cs +++ b/src/BizHawk.Emulation.DiscSystem/DiscFormats/CUE/CUE_Load.cs @@ -107,8 +107,7 @@ namespace BizHawk.Emulation.DiscSystem.CUE { throw new DiscReferenceException(ccf.FullPath, "No decoding service was available (make sure ffmpeg.exe is available. even though this may be a wav, ffmpeg is used to load oddly formatted wave files. If you object to this, please send us a note and we'll see what we can do. It shouldn't be too hard.)"); } - AudioDecoder dec = new AudioDecoder(); - byte[] buf = dec.AcquireWaveData(ccf.FullPath); + byte[] buf = AudioDecoder.AcquireWaveData(ccf.FullPath); var blob = new Disc.Blob_WaveFile(); OUT_Disc.DisposableResources.Add(file_blob = blob); blob.Load(new MemoryStream(buf)); diff --git a/src/BizHawk.Emulation.DiscSystem/DiscIdentifier.cs b/src/BizHawk.Emulation.DiscSystem/DiscIdentifier.cs index 43a73ff6f7..42c7aaddb8 100644 --- a/src/BizHawk.Emulation.DiscSystem/DiscIdentifier.cs +++ b/src/BizHawk.Emulation.DiscSystem/DiscIdentifier.cs @@ -3,6 +3,8 @@ using System.Collections.Generic; using System.Linq; using System.Text; +using BizHawk.Common.BufferExtensions; + //disc type identification logic namespace BizHawk.Emulation.DiscSystem @@ -119,6 +121,79 @@ namespace BizHawk.Emulation.DiscSystem /// public DiscType DetectDiscType() { + // this is a reasonable approach to identify Saturn + bool DetectSegaSaturn() => StringAt("SEGA SEGASATURN", 0); + + // probably wrong + bool DetectMegaCD() => StringAt("SEGADISCSYSTEM", 0) || StringAt("SEGADISCSYSTEM", 16); + + bool DetectPSX() => StringAt(" Licensed by ", 0, 4) + && ( + StringAt("Sony Computer Entertainment Euro", 32, 4) + || StringAt("Sony Computer Entertainment Inc.", 32, 4) + || StringAt("Sony Computer Entertainment Amer", 32, 4) + || StringAt("Sony Computer Entertainment of A", 32, 4) + ); + + bool DetectPCFX() + { + var toc = _disc.TOC; + for (var t = toc.FirstRecordedTrackNumber; t <= toc.LastRecordedTrackNumber; t++) + { + var track = _disc.TOC.TOCItems[t]; + //asni - this search is less specific - turns out there are discs where 'Hu:' is not present + if (track.IsData && SectorContains("pc-fx", track.LBA)) return true; + } + 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 + bool DetectTurboCD() + { + var toc = _disc.TOC; + for (int t = toc.FirstRecordedTrackNumber; t <= toc.LastRecordedTrackNumber; t++) + { + var track = _disc.TOC.TOCItems[t]; + // asni - pcfx games also contain the 'PC Engine' string + if (track.IsData && SectorContains("pc engine", track.LBA + 1) && !SectorContains("pc-fx", track.LBA + 1)) return true; + } + return false; + } + + bool Detect3DO() + { + var toc = _disc.TOC; + for (var t = toc.FirstRecordedTrackNumber; t <= toc.LastRecordedTrackNumber; t++) + { + var track = _disc.TOC.TOCItems[t]; + if (track.IsData && SectorContains("iamaduckiamaduck", track.LBA)) return true; + } + return false; + } + + // asni - slightly longer-running than the others due to its brute-force nature. Should be run later in the method + bool DetectDreamcast() + { + for (var i = 0; i < 1000; i++) if (SectorContains("segakatana", i)) return true; + return false; + } + + bool DetectCDi() => StringAt("CD-RTOS", 8, 16); + + bool DetectGameCube() + { + var data = ReadSectorCached(0); + return data != null && data.Skip(28).Take(4).ToArray().BytesToHexString() == "C2339F3D"; + } + + bool DetectWii() + { + var data = ReadSectorCached(0); + return data != null && data.Skip(24).Take(4).ToArray().BytesToHexString() == "5D1C9EA3"; + } + // PCFX & TurboCD sometimes (if not alltimes) have audio on track 1 - run these before the AudioDisc detection (asni) if (DetectPCFX()) return DiscType.PCFX; @@ -219,120 +294,6 @@ namespace BizHawk.Emulation.DiscSystem return DiscType.UnknownFormat; } - /// - /// This is reasonable approach to ID saturn. - /// - private bool DetectSegaSaturn() - { - return StringAt("SEGA SEGASATURN", 0); - } - - /// - /// probably wrong - /// - private bool DetectMegaCD() - { - return StringAt("SEGADISCSYSTEM", 0) || StringAt("SEGADISCSYSTEM", 16); - } - - private bool DetectPSX() - { - if (!StringAt(" Licensed by ", 0, 4)) return false; - return (StringAt("Sony Computer Entertainment Euro", 32, 4) - || StringAt("Sony Computer Entertainment Inc.", 32, 4) - || StringAt("Sony Computer Entertainment Amer", 32, 4) - || StringAt("Sony Computer Entertainment of A", 32, 4) - ); - } - - private bool DetectPCFX() - { - var toc = _disc.TOC; - for (int t = toc.FirstRecordedTrackNumber; - t <= toc.LastRecordedTrackNumber; - t++) - { - var track = _disc.TOC.TOCItems[t]; - //asni - this search is less specific - turns out there are discs where 'Hu:' is not present - if (track.IsData && SectorContains("pc-fx", track.LBA)) - return true; - } - 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 - private bool DetectTurboCD() - { - var toc = _disc.TOC; - for (int t = toc.FirstRecordedTrackNumber; - t <= toc.LastRecordedTrackNumber; - t++) - { - var track = _disc.TOC.TOCItems[t]; - //asni - pcfx games also contain the 'PC Engine' string - if ((track.IsData && SectorContains("pc engine", track.LBA + 1) && !SectorContains("pc-fx", track.LBA + 1))) - return true; - } - return false; - } - - private bool Detect3DO() - { - var toc = _disc.TOC; - for (int t = toc.FirstRecordedTrackNumber; - t <= toc.LastRecordedTrackNumber; - t++) - { - var track = _disc.TOC.TOCItems[t]; - if (track.IsData && SectorContains("iamaduckiamaduck", track.LBA)) - return true; - } - return false; - } - - //asni - slightly longer running than the others due to its brute-force nature. Should run later in the method - private bool DetectDreamcast() - { - for (int i = 0; i < 1000; i++) - { - if (SectorContains("segakatana", i)) - return true; - } - - return false; - } - - private bool DetectCDi() - { - return StringAt("CD-RTOS", 8, 16); - } - - private bool DetectGameCube() - { - var data = ReadSectorCached(0); - if (data == null) return false; - byte[] magic = data.Skip(28).Take(4).ToArray(); - string hexString = ""; - foreach (var b in magic) - hexString += b.ToString("X2"); - - return hexString == "C2339F3D"; - } - - private bool DetectWii() - { - var data = ReadSectorCached(0); - if (data == null) return false; - byte[] magic = data.Skip(24).Take(4).ToArray(); - string hexString = ""; - foreach (var b in magic) - hexString += b.ToString("X2"); - - return hexString == "5D1C9EA3"; - } - private byte[] ReadSectorCached(int lba) { //read it if we don't have it cached diff --git a/src/BizHawk.Emulation.DiscSystem/DiscSectorReader.cs b/src/BizHawk.Emulation.DiscSystem/DiscSectorReader.cs index 0b3db177ac..daa895ac9e 100644 --- a/src/BizHawk.Emulation.DiscSystem/DiscSectorReader.cs +++ b/src/BizHawk.Emulation.DiscSystem/DiscSectorReader.cs @@ -126,44 +126,6 @@ namespace BizHawk.Emulation.DiscSystem return 2448; } - private int ReadLBA_2048_Mode1(int lba, byte[] buffer, int offset) - { - //we can read the 2048 bytes directly - var sector = disc.SynthProvider.Get(lba); - - if (sector == null) return 0; - - PrepareBuffer(buffer, offset, 2048); - PrepareJob(lba); - job.DestBuffer2448 = buf2442; - job.DestOffset = 0; - job.Parts = ESectorSynthPart.User2048; - - sector.Synth(job); - Buffer.BlockCopy(buf2442, 16, buffer, offset, 2048); - - return 2048; - } - - private int ReadLBA_2048_Mode2_Form1(int lba, byte[] buffer, int offset) - { - //we can read the 2048 bytes directly but we have to get them from the mode 2 data - var sector = disc.SynthProvider.Get(lba); - - if (sector == null) return 0; - - PrepareBuffer(buffer, offset, 2048); - PrepareJob(lba); - job.DestBuffer2448 = buf2442; - job.DestOffset = 0; - job.Parts = ESectorSynthPart.User2336; - - sector.Synth(job); - Buffer.BlockCopy(buf2442, 24, buffer, offset, 2048); - - return 2048; - } - /// /// Reads 12 bytes of subQ data from a sector. /// This is necessarily deinterleaved. @@ -196,10 +158,48 @@ namespace BizHawk.Emulation.DiscSystem /// public int ReadLBA_2048(int lba, byte[] buffer, int offset) { + int ReadLBA_2048_Mode1() + { + //we can read the 2048 bytes directly + var sector = disc.SynthProvider.Get(lba); + + if (sector == null) return 0; + + PrepareBuffer(buffer, offset, 2048); + PrepareJob(lba); + job.DestBuffer2448 = buf2442; + job.DestOffset = 0; + job.Parts = ESectorSynthPart.User2048; + + sector.Synth(job); + Buffer.BlockCopy(buf2442, 16, buffer, offset, 2048); + + return 2048; + } + + int ReadLBA_2048_Mode2_Form1() + { + //we can read the 2048 bytes directly but we have to get them from the mode 2 data + var sector = disc.SynthProvider.Get(lba); + + if (sector == null) return 0; + + PrepareBuffer(buffer, offset, 2048); + PrepareJob(lba); + job.DestBuffer2448 = buf2442; + job.DestOffset = 0; + job.Parts = ESectorSynthPart.User2336; + + sector.Synth(job); + Buffer.BlockCopy(buf2442, 24, buffer, offset, 2048); + + return 2048; + } + if (Policy.UserData2048Mode == DiscSectorReaderPolicy.EUserData2048Mode.AssumeMode1) - return ReadLBA_2048_Mode1(lba, buffer, offset); + return ReadLBA_2048_Mode1(); else if (Policy.UserData2048Mode == DiscSectorReaderPolicy.EUserData2048Mode.AssumeMode2_Form1) - return ReadLBA_2048_Mode2_Form1(lba, buffer, offset); + return ReadLBA_2048_Mode2_Form1(); else { //we need to determine the type of the sector. diff --git a/src/BizHawk.Emulation.DiscSystem/Internal/Algorithms/ECM.cs b/src/BizHawk.Emulation.DiscSystem/Internal/Algorithms/ECM.cs index 4bbbb15f7b..40b1ae13bb 100644 --- a/src/BizHawk.Emulation.DiscSystem/Internal/Algorithms/ECM.cs +++ b/src/BizHawk.Emulation.DiscSystem/Internal/Algorithms/ECM.cs @@ -215,40 +215,29 @@ namespace BizHawk.Emulation.DiscSystem return crc; } - - - /// - /// returns the address from a sector. useful for saving it before zeroing it for ECC calculations - /// - private static uint GetSectorAddress(byte[] sector, int sector_offset) - { - return (uint)( - (sector[sector_offset + 12 + 0] << 0) - | (sector[sector_offset + 12 + 1] << 8) - | (sector[sector_offset + 12 + 2] << 16) - ); - //| (sector[sector_offset + 12 + 3] << 24)); - } - - /// - /// sets the address for a sector. useful for restoring it after zeroing it for ECC calculations - /// - private static void SetSectorAddress(byte[] sector, int sector_offset, uint address) - { - sector[sector_offset + 12 + 0] = (byte)((address >> 0) & 0xFF); - sector[sector_offset + 12 + 1] = (byte)((address >> 8) & 0xFF); - sector[sector_offset + 12 + 2] = (byte)((address >> 16) & 0xFF); - //sector[sector_offset + 12 + 3] = (byte)((address >> 24) & 0xFF); - } - - - /// /// populates a sector with valid ECC information. /// it is safe to supply the same array for sector and dest. /// public static void ECC_Populate(byte[] src, int src_offset, byte[] dest, int dest_offset, bool zeroSectorAddress) { + // returns the address from a sector. useful for saving it before zeroing it for ECC calculations + static uint GetSectorAddress(byte[] sector, int sector_offset) => (uint)( + (sector[sector_offset + 12 + 0] << 0) + | (sector[sector_offset + 12 + 1] << 8) + | (sector[sector_offset + 12 + 2] << 16) +// | (sector[sector_offset + 12 + 3] << 24) + ); + + // sets the address for a sector. useful for restoring it after zeroing it for ECC calculations + static void SetSectorAddress(byte[] sector, int sector_offset, uint address) + { + sector[sector_offset + 12 + 0] = (byte)((address >> 0) & 0xFF); + sector[sector_offset + 12 + 1] = (byte)((address >> 8) & 0xFF); + sector[sector_offset + 12 + 2] = (byte)((address >> 16) & 0xFF); +// sector[sector_offset + 12 + 3] = (byte)((address >> 24) & 0xFF); + } + //save the old sector address, so we can restore it later. SOMETIMES ECC is supposed to be calculated without it? see TODO uint address = GetSectorAddress(src, src_offset); if (zeroSectorAddress) SetSectorAddress(src, src_offset, 0);