diff --git a/BizHawk.Client.DiscoHawk/AudioExtractor.cs b/BizHawk.Client.DiscoHawk/AudioExtractor.cs index e611ae7218..b789d71e0e 100644 --- a/BizHawk.Client.DiscoHawk/AudioExtractor.cs +++ b/BizHawk.Client.DiscoHawk/AudioExtractor.cs @@ -19,15 +19,16 @@ namespace BizHawk.Client.DiscoHawk var dsr = new DiscSectorReader(disc); bool confirmed = false; - var tracks = disc.Structure.Sessions[0].Tracks; + var tracks = disc.Session1.Tracks; foreach (var track in tracks) { if (!track.IsAudio) continue; - var waveData = new byte[track.Length * 2352]; + int trackLength = track.NextTrack.LBA - track.LBA; + var waveData = new byte[trackLength * 2352]; int startLba = track.LBA; - for (int sector = 0; sector < track.Length; sector++) + for (int sector = 0; sector < trackLength; sector++) dsr.ReadLBA_2352(startLba + sector, waveData, sector * 2352); string mp3Path = string.Format("{0} - Track {1:D2}.mp3", Path.Combine(path, filebase), track.Number); diff --git a/BizHawk.Client.DiscoHawk/DiscoHawk.cs b/BizHawk.Client.DiscoHawk/DiscoHawk.cs index bdc78c1665..f0964de8aa 100644 --- a/BizHawk.Client.DiscoHawk/DiscoHawk.cs +++ b/BizHawk.Client.DiscoHawk/DiscoHawk.cs @@ -379,9 +379,9 @@ namespace BizHawk.Client.DiscoHawk }; //verify sector count - if (src_disc.LBACount != dst_disc.LBACount) + if (src_disc.Session1.LeadoutLBA != dst_disc.Session1.LeadoutLBA) { - sw.Write("LBACount count {0} vs {1}\n", src_disc.LBACount, dst_disc.LBACount); + sw.Write("LeadoutTrack.LBA {0} vs {1}\n", src_disc.Session1.LeadoutTrack.LBA, dst_disc.Session1.LeadoutTrack.LBA); goto SKIPPO; } @@ -442,12 +442,12 @@ namespace BizHawk.Client.DiscoHawk }; //verify each sector contents - int nSectors = src_disc.LBACount; + int nSectors = src_disc.Session1.LeadoutLBA; for (int lba = -150; lba < nSectors; lba++) { if (verbose) if (lba % 1000 == 0) - Console.WriteLine("LBA {0} of {1}", lba, src_disc.LBACount); + Console.WriteLine("LBA {0} of {1}", lba, nSectors); if (cancelToken != null) if (cancelToken.Token.IsCancellationRequested) diff --git a/BizHawk.Emulation.Cores/Consoles/PC Engine/ScsiCDBus.cs b/BizHawk.Emulation.Cores/Consoles/PC Engine/ScsiCDBus.cs index c7cdfefdbd..2ddd89f8cf 100644 --- a/BizHawk.Emulation.Cores/Consoles/PC Engine/ScsiCDBus.cs +++ b/BizHawk.Emulation.Cores/Consoles/PC Engine/ScsiCDBus.cs @@ -422,7 +422,7 @@ namespace BizHawk.Emulation.Cores.PCEngine case 0x80: // Set start offset in track units byte trackNo = CommandBuffer[2].BCDtoBin(); - audioStartLBA = disc.Structure.Sessions[0].Tracks[trackNo - 1].LBA; + audioStartLBA = disc.Session1.Tracks[trackNo].LBA; break; } @@ -457,10 +457,10 @@ namespace BizHawk.Emulation.Cores.PCEngine case 0x80: // Set end offset in track units byte trackNo = CommandBuffer[2].BCDtoBin(); - if (trackNo - 1 >= disc.Structure.Sessions[0].Tracks.Count) - audioEndLBA = disc.LBACount; + if (trackNo - 1 >= disc.Session1.Tracks.Count) + audioEndLBA = disc.Session1.LeadoutLBA; else - audioEndLBA = disc.Structure.Sessions[0].Tracks[trackNo - 1].LBA; + audioEndLBA = disc.Session1.Tracks[trackNo].LBA; break; } @@ -530,13 +530,14 @@ namespace BizHawk.Emulation.Cores.PCEngine { DataIn.Clear(); DataIn.Enqueue(0x01); - DataIn.Enqueue(((byte)disc.Structure.Sessions[0].Tracks.Count).BinToBCD()); + DataIn.Enqueue(((byte)disc.Session1.Tracks.Count).BinToBCD()); SetPhase(BusPhase_DataIn); break; } case 1: // return total disc length in minutes/seconds/frames { - int totalLbaLength = disc.LBACount; + //zero 07-jul-2015 - I may have broken this + int totalLbaLength = disc.Session1.LeadoutLBA; byte m, s, f; Disc.ConvertLBAtoMSF(totalLbaLength, out m, out s, out f); @@ -548,20 +549,18 @@ namespace BizHawk.Emulation.Cores.PCEngine SetPhase(BusPhase_DataIn); break; } - case 2: // Return starting position of specified track in MSF format + case 2: // Return starting position of specified track in MSF format. TODO - did zero adapt this right? track indexing might be off { int track = CommandBuffer[2].BCDtoBin(); - var tracks = disc.Structure.Sessions[0].Tracks; + var tracks = disc.Session1.Tracks; if (CommandBuffer[2] > 0x99) throw new Exception("invalid track number BCD request... is something I need to handle?"); if (track == 0) track = 1; - track--; - int lbaPos; - if (track > tracks.Count) - lbaPos = disc.TOCRaw.LeadoutLBA.Sector; //zero 03-jul-2015 - did I adapt this right? + if (track > disc.Session1.InformationTrackCount) + lbaPos = disc.Session1.LeadoutLBA; //zero 03-jul-2015 - did I adapt this right? else lbaPos = tracks[track].LBA; @@ -573,7 +572,7 @@ namespace BizHawk.Emulation.Cores.PCEngine DataIn.Enqueue(s.BinToBCD()); DataIn.Enqueue(f.BinToBCD()); - if (track > tracks.Count || disc.Structure.Sessions[0].Tracks[track].IsAudio) + if (track > tracks.Count || disc.Session1.Tracks[track].IsAudio) DataIn.Enqueue(0); else DataIn.Enqueue(4); diff --git a/BizHawk.Emulation.Cores/Consoles/Sega/Saturn/Yabause.cs b/BizHawk.Emulation.Cores/Consoles/Sega/Saturn/Yabause.cs index 0f5d5c1eee..c76e508fbb 100644 --- a/BizHawk.Emulation.Cores/Consoles/Sega/Saturn/Yabause.cs +++ b/BizHawk.Emulation.Cores/Consoles/Sega/Saturn/Yabause.cs @@ -392,13 +392,13 @@ namespace BizHawk.Emulation.Cores.Sega.Saturn int CD_ReadTOC(IntPtr dest) { // this stuff from yabause's cdbase.c. don't ask me to explain it + //TODO - we could just get this out of the actual TOC, it's the same thing - var TOC = CD.Structure; int[] rTOC = new int[102]; - var ses = TOC.Sessions[0]; + var ses = CD.Session1; int ntrk = ses.Tracks.Count; - for (int i = 0; i < 99; i++) + for (int i = 1; i <= 99; i++) { if (i < ntrk) { diff --git a/BizHawk.Emulation.Cores/Consoles/Sega/gpgx/GPGX.cs b/BizHawk.Emulation.Cores/Consoles/Sega/gpgx/GPGX.cs index fe8149c752..73a8c5953d 100644 --- a/BizHawk.Emulation.Cores/Consoles/Sega/gpgx/GPGX.cs +++ b/BizHawk.Emulation.Cores/Consoles/Sega/gpgx/GPGX.cs @@ -292,7 +292,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx if (audio) { byte[] data = new byte[2352]; - if (lba < CD.LBACount) + if (lba < CD.Session1.LeadoutLBA) { DiscSectorReader.ReadLBA_2352(lba, data, 0); } @@ -322,16 +322,17 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx ret.readcallback = cd_callback_handle = new LibGPGX.cd_read_cb(CDRead); - var ses = CD.Structure.Sessions[0]; + var ses = CD.Session1; int ntrack = ses.Tracks.Count; // bet you a dollar this is all wrong + //zero 07-jul-2015 - throws a dollar in the pile, since he probably messed it up worse for (int i = 0; i < LibGPGX.CD_MAX_TRACKS; i++) { if (i < ntrack) { ret.tracks[i].start = ses.Tracks[i].LBA; - ret.tracks[i].end = ses.Tracks[i].Length + ret.tracks[i].start; + ret.tracks[i].end = ses.Tracks[i + 1].LBA; if (i == ntrack - 1) { ret.end = ret.tracks[i].end; diff --git a/BizHawk.Emulation.Cores/Consoles/Sega/gpgx/GPGXDynamic.cs b/BizHawk.Emulation.Cores/Consoles/Sega/gpgx/GPGXDynamic.cs index 0300700b32..26fa0934f3 100644 --- a/BizHawk.Emulation.Cores/Consoles/Sega/gpgx/GPGXDynamic.cs +++ b/BizHawk.Emulation.Cores/Consoles/Sega/gpgx/GPGXDynamic.cs @@ -291,7 +291,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx if (audio) { byte[] data = new byte[2352]; - if (lba < CD.LBACount) + if (lba < CD.Session1.LeadoutLBA) { CDReader.ReadLBA_2352(lba, data, 0); } @@ -321,16 +321,17 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx ret.readcallback = cd_callback_handle = new LibGPGXDynamic.cd_read_cb(CDRead); - var ses = CD.Structure.Sessions[0]; + var ses = CD.Session1; int ntrack = ses.Tracks.Count; // bet you a dollar this is all wrong + //zero 07-jul-2015 - throws a dollar in the pile, since he probably messed it up worse for (int i = 0; i < LibGPGXDynamic.CD_MAX_TRACKS; i++) { if (i < ntrack) { ret.tracks[i].start = ses.Tracks[i].LBA; - ret.tracks[i].end = ses.Tracks[i].Length + ret.tracks[i].start; + ret.tracks[i].end = ses.Tracks[i + 1].LBA; if (i == ntrack - 1) { ret.end = ret.tracks[i].end; diff --git a/BizHawk.Emulation.Cores/Consoles/Sony/PSX/Octoshock.cs b/BizHawk.Emulation.Cores/Consoles/Sony/PSX/Octoshock.cs index ddafc67692..64d919b237 100644 --- a/BizHawk.Emulation.Cores/Consoles/Sony/PSX/Octoshock.cs +++ b/BizHawk.Emulation.Cores/Consoles/Sony/PSX/Octoshock.cs @@ -142,7 +142,7 @@ namespace BizHawk.Emulation.Cores.Sony.PSX cbReadTOC = ShockDisc_ReadTOC; cbReadLBA = ShockDisc_ReadLBA2448; this.cbActivity = cbActivity; - OctoshockDll.shock_CreateDisc(out OctoshockHandle, IntPtr.Zero, disc.LBACount, cbReadTOC, cbReadLBA, true); + OctoshockDll.shock_CreateDisc(out OctoshockHandle, IntPtr.Zero, disc.Session1.LeadoutLBA, cbReadTOC, cbReadLBA, true); } OctoshockDll.ShockDisc_ReadTOC cbReadTOC; diff --git a/BizHawk.Emulation.DiscSystem/API/Disc.API.cs b/BizHawk.Emulation.DiscSystem/API/Disc.API.cs index ba56d63283..6e2de04f3b 100644 --- a/BizHawk.Emulation.DiscSystem/API/Disc.API.cs +++ b/BizHawk.Emulation.DiscSystem/API/Disc.API.cs @@ -7,37 +7,10 @@ using BizHawk.Common.BufferExtensions; namespace BizHawk.Emulation.DiscSystem { - [Serializable] - public class DiscReferenceException : Exception - { - public DiscReferenceException(string fname, Exception inner) - : base(string.Format("A disc attempted to reference a file which could not be accessed or loaded: {0}", fname), inner) - { - } - public DiscReferenceException(string fname, string extrainfo) - : base(string.Format("A disc attempted to reference a file which could not be accessed or loaded:\n\n{0}\n\n{1}", fname, extrainfo)) - { - } - } - - - sealed public partial class Disc { - /// - /// Main API to determine how many LBAs are available on the disc. - /// This counts from LBA 0 to the final sector available. - /// THIS IS DUMB. Like everything else here. - /// Fetch it from a toc or disc structure - /// - public int LBACount { get { return ABACount - 150; } } - - /// - /// Main API to determine how many ABAs (sectors) are available on the disc. - /// This counts from ABA 0 to the final sector available. - /// - public int ABACount { get { return Sectors.Count; } } + // converts LBA to minute:second:frame format. //TODO - somewhat redundant with Timestamp, which is due for refactoring into something not cue-related diff --git a/BizHawk.Emulation.DiscSystem/API/DiscExceptions.cs b/BizHawk.Emulation.DiscSystem/API/DiscExceptions.cs new file mode 100644 index 0000000000..5565f4d510 --- /dev/null +++ b/BizHawk.Emulation.DiscSystem/API/DiscExceptions.cs @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; + +using BizHawk.Common.BufferExtensions; + +//some old junk + +namespace BizHawk.Emulation.DiscSystem +{ + [Serializable] + public class DiscReferenceException : Exception + { + public DiscReferenceException(string fname, Exception inner) + : base(string.Format("A disc attempted to reference a file which could not be accessed or loaded: {0}", fname), inner) + { + } + public DiscReferenceException(string fname, string extrainfo) + : base(string.Format("A disc attempted to reference a file which could not be accessed or loaded:\n\n{0}\n\n{1}", fname, extrainfo)) + { + } + } + + +} \ No newline at end of file diff --git a/BizHawk.Emulation.DiscSystem/API/DiscHasher.cs b/BizHawk.Emulation.DiscSystem/API/DiscHasher.cs index 4a37cb62bc..2990b4925c 100644 --- a/BizHawk.Emulation.DiscSystem/API/DiscHasher.cs +++ b/BizHawk.Emulation.DiscSystem/API/DiscHasher.cs @@ -20,13 +20,13 @@ namespace BizHawk.Emulation.DiscSystem { byte[] buffer = new byte[512 * 2352]; DiscSectorReader dsr = new DiscSectorReader(disc); - foreach (var track in disc.Structure.Sessions[0].Tracks) + foreach (var track in disc.Session1.Tracks) { if (track.IsAudio) continue; - int lba_len = Math.Min(track.Length, 512); - for (int s = 0; s < 512 && s < track.Length; s++) + int lba_len = Math.Min(track.NextTrack.LBA, 512); + for (int s = 0; s < 512 && s < lba_len; s++) dsr.ReadLBA_2352(track.LBA + s, buffer, s * 2352); return buffer.HashMD5(0, lba_len * 2352); diff --git a/BizHawk.Emulation.DiscSystem/API/DiscStream.cs b/BizHawk.Emulation.DiscSystem/API/DiscStream.cs index f938059a40..95db67d0db 100644 --- a/BizHawk.Emulation.DiscSystem/API/DiscStream.cs +++ b/BizHawk.Emulation.DiscSystem/API/DiscStream.cs @@ -70,7 +70,7 @@ namespace BizHawk.Emulation.DiscSystem SectorSize = 2048; Disc = disc; - NumSectors = disc.LBACount; + NumSectors = disc.Session1.LeadoutLBA; dsr = new DiscSectorReader(disc); //following the provided view diff --git a/BizHawk.Emulation.DiscSystem/BizHawk.Emulation.DiscSystem.csproj b/BizHawk.Emulation.DiscSystem/BizHawk.Emulation.DiscSystem.csproj index a15a2d717a..18dd392acb 100644 --- a/BizHawk.Emulation.DiscSystem/BizHawk.Emulation.DiscSystem.csproj +++ b/BizHawk.Emulation.DiscSystem/BizHawk.Emulation.DiscSystem.csproj @@ -52,6 +52,7 @@ + diff --git a/BizHawk.Emulation.DiscSystem/CDAudio.cs b/BizHawk.Emulation.DiscSystem/CDAudio.cs index 7dfbb41056..37f93d97c7 100644 --- a/BizHawk.Emulation.DiscSystem/CDAudio.cs +++ b/BizHawk.Emulation.DiscSystem/CDAudio.cs @@ -50,11 +50,14 @@ namespace BizHawk.Emulation.DiscSystem public void PlayTrack(int track) { - if (track < 1 || track > Disc.Structure.Sessions[0].Tracks.Count) + if (track < 1 || track > Disc.Session1.InformationTrackCount) return; - StartLBA = Disc.Structure.Sessions[0].Tracks[track - 1].LBA; - EndLBA = StartLBA + Disc.Structure.Sessions[0].Tracks[track - 1].Length; + StartLBA = Disc.Session1.Tracks[track].LBA; + + //play until the beginning of the next track (?) + EndLBA = Disc.Session1.Tracks[track + 1].LBA; + PlayingTrack = track; CurrentSector = StartLBA; SectorOffset = 0; @@ -71,7 +74,9 @@ namespace BizHawk.Emulation.DiscSystem PlayingTrack = track.Number; StartLBA = lba; - EndLBA = track.LBA + track.Length; + + //play until the beginning of the next track (?) + EndLBA = Disc.Session1.Tracks[track.Number + 1].LBA; CurrentSector = StartLBA; SectorOffset = 0; @@ -123,7 +128,7 @@ namespace BizHawk.Emulation.DiscSystem { if (CachedSector != CurrentSector) { - if (CurrentSector >= Disc.LBACount) + if (CurrentSector >= Disc.Session1.LeadoutLBA) Array.Clear(SectorCache, 0, 2352); // request reading past end of available disc else DiscSectorReader.ReadLBA_2352(CurrentSector, SectorCache, 0); diff --git a/BizHawk.Emulation.DiscSystem/Disc.cs b/BizHawk.Emulation.DiscSystem/Disc.cs index ee9258100c..d4d01447d8 100644 --- a/BizHawk.Emulation.DiscSystem/Disc.cs +++ b/BizHawk.Emulation.DiscSystem/Disc.cs @@ -82,12 +82,6 @@ namespace BizHawk.Emulation.DiscSystem public partial class Disc : IDisposable { - /// - /// The DiscMountPolicy used to mount the disc. Consider this read-only. - /// NOT SURE WE NEED THIS - /// - //public DiscMountPolicy DiscMountPolicy; - /// /// Free-form optional memos about the disc /// @@ -102,6 +96,7 @@ namespace BizHawk.Emulation.DiscSystem /// /// The DiscTOCRaw corresponding to the RawTOCEntries. /// TODO - rename to TOC + /// TODO - there's one of these for every session, so... having one here doesnt make sense /// public DiscTOCRaw TOCRaw; @@ -110,6 +105,11 @@ namespace BizHawk.Emulation.DiscSystem /// public DiscStructure Structure; + /// + /// DiscStructure.Session 1 of the disc, since that's all thats needed most of the time. + /// + public DiscStructure.Session Session1 { get { return Structure.Sessions[1]; } } + /// /// Disposable resources (blobs, mostly) referenced by this disc /// @@ -120,8 +120,17 @@ namespace BizHawk.Emulation.DiscSystem /// internal List Sectors = new List(); + /// + /// Parameters set during disc loading which can be referenced by the sector synthesizers + /// internal SectorSynthParams SynthParams = new SectorSynthParams(); + /// + /// The DiscMountPolicy used to mount the disc. Consider this read-only. + /// NOT SURE WE NEED THIS + /// + //public DiscMountPolicy DiscMountPolicy; + public Disc() { } @@ -134,7 +143,6 @@ namespace BizHawk.Emulation.DiscSystem } } - /// /// generates lead-out sectors according to very crude approximations /// TODO - this isnt being used right now diff --git a/BizHawk.Emulation.DiscSystem/Jobs/DiscMountJob.cs b/BizHawk.Emulation.DiscSystem/Jobs/DiscMountJob.cs index 8fee2cd2f9..9fddaf195f 100644 --- a/BizHawk.Emulation.DiscSystem/Jobs/DiscMountJob.cs +++ b/BizHawk.Emulation.DiscSystem/Jobs/DiscMountJob.cs @@ -88,6 +88,20 @@ namespace BizHawk.Emulation.DiscSystem RunMednaDisc(); break; } + + if (OUT_Disc != null) + { + //generate toc and structure: + //1. TOCRaw from RawTOCEntries + var tocSynth = new DiscTOCRaw.SynthesizeFromRawTOCEntriesJob() { Entries = OUT_Disc.RawTOCEntries }; + tocSynth.Run(); + OUT_Disc.TOCRaw = tocSynth.Result; + //2. Structure frmo TOCRaw + var structureSynth = new DiscStructure.SynthesizeFromTOCRawJob() { IN_Disc = OUT_Disc, TOCRaw = OUT_Disc.TOCRaw }; + structureSynth.Run(); + OUT_Disc.Structure = structureSynth.Result; + } + FinishLog(); } @@ -178,20 +192,7 @@ namespace BizHawk.Emulation.DiscSystem OUT_Disc = ccdLoader.LoadCCDToDisc(IN_FromPath); } - DONE: - if (OUT_Disc != null) - { - //generate toc and structure: - //1. TOCRaw from RawTOCEntries - var tocSynth = new DiscTOCRaw.SynthesizeFromRawTOCEntriesJob() { Entries = OUT_Disc.RawTOCEntries }; - tocSynth.Run(); - OUT_Disc.TOCRaw = tocSynth.Result; - //2. Structure frmo TOCRaw - var structureSynth = new DiscStructure.SynthesizeFromTOCRawJob() { IN_Disc = OUT_Disc, TOCRaw = OUT_Disc.TOCRaw }; - structureSynth.Run(); - OUT_Disc.Structure = structureSynth.Result; - } - + DONE: ; } } diff --git a/BizHawk.Emulation.DiscSystem/TOC/DiscStructure.cs b/BizHawk.Emulation.DiscSystem/TOC/DiscStructure.cs index c6d0bd82eb..24b1cc4517 100644 --- a/BizHawk.Emulation.DiscSystem/TOC/DiscStructure.cs +++ b/BizHawk.Emulation.DiscSystem/TOC/DiscStructure.cs @@ -7,50 +7,34 @@ namespace BizHawk.Emulation.DiscSystem /// /// Contains structural information for the disc broken down into c# data structures for easy interrogation. /// This represents a best-effort interpretation of the raw disc image. + /// NOTE: Since this ended up really just having the list of sessions.. maybe it isn't needed and can just float on up into Disc /// public class DiscStructure { /// /// This is a 0-indexed list of sessions (session 1 is at [0]) /// Support for multiple sessions is thoroughly not working yet + /// TODO - make re-index me with a null session 0 /// public List Sessions = new List(); - /// - /// How many sectors in the disc, including the 150 lead-in sectors, up to the end of the last track (before the lead-out track) - /// TODO - does anyone ever need this as the ABA Count? Rename it LBACount or ABACount - /// - public int LengthInSectors; /// - /// Length (including lead-in) of the disc as a timestamp - /// TODO - does anyone ever need this as the ABA Count? Rename it LBACount or ABACount - /// - public Timestamp FriendlyLength { get { return new Timestamp(LengthInSectors); } } - - /// - /// How many bytes of data in the disc (including lead-in). Disc sectors are really 2352 bytes each, so this is LengthInSectors * 2352 - /// TODO - this is garbage - /// - public long BinarySize - { - get { return LengthInSectors * 2352; } - } - - /// - /// Determines which track of session 0 is at the specified LBA. + /// Determines which track of session 1 is at the specified LBA. /// Returns null if it's before track 1 /// public Track SeekTrack(int lba) { var ses = Sessions[0]; - for (int i = 0; i < ses.Tracks.Count; i++) + + //take care with this loop bounds: + for (int i = 1; i <= ses.InformationTrackCount; i++) { var track = ses.Tracks[i]; if (track.LBA > lba) - return (i==0)?null:ses.Tracks[i - 1]; + return (i==1)?null:ses.Tracks[i]; } - return ses.Tracks[ses.Tracks.Count - 1]; + return ses.Tracks[ses.Tracks.Count]; } ///// @@ -94,6 +78,7 @@ namespace BizHawk.Emulation.DiscSystem Result = new DiscStructure(); var session = new Session(); + Result.Sessions.Add(null); //placeholder session for reindexing Result.Sessions.Add(session); session.Number = 1; @@ -101,6 +86,13 @@ namespace BizHawk.Emulation.DiscSystem if(TOCRaw.FirstRecordedTrackNumber != 1) throw new InvalidOperationException("Unsupported: FirstRecordedTrackNumber != 1"); + //add a lead-in track + session.Tracks.Add(new DiscStructure.Track() { + Number = 0, + Control = EControlQ.None, //TODO - not accurate (take from track 1?) + LBA = -150 //TODO - not accurate + }); + int ntracks = TOCRaw.LastRecordedTrackNumber - TOCRaw.FirstRecordedTrackNumber + 1; for(int i=0;i + /// The LBA of the session's leadout. In other words, for all intents and purposes, the end of the session + /// + public int LeadoutLBA { get { return LeadoutTrack.LBA; } } + /// /// The session number /// public int Number; /// - /// All the tracks in the session.. but... Tracks[0] should be "Track 1". So beware of this. - /// Tracks.Count will be good for counting the useful user information tracks on the disc. + /// The number of user information tracks in the session. + /// This excludes track 0 and the lead-out track. + /// Use this instead of Tracks.Count + /// + public int InformationTrackCount; + + /// + /// All the tracks in the session.. but... Tracks[0] is the lead-in track placeholder. Tracks[1] should be "Track 1". So beware of this. + /// For a disc with "3 tracks", Tracks.Count will be 5: it includes that lead-in track as well as the leadout track. + /// Perhaps we should turn this into a special collection type with no Count or Length, or a method to GetTrack() /// public List Tracks = new List(); - //I've thought about how to solve this, but it's not easy. - //At some point we may need to add a true track 0, too. - //Ideas: Dictionary, or a separate PhysicalTracks and UserTracks list, or add a null and make all loops just cope with that - //But, the DiscStructure is kind of weak. It might be better to just optimize it for end-users - //It seems that the current end-users are happy with tracks being implemented the way it is - //removed: - ////the length of the session (should be the sum of all track lengths) - //public int length_aba; + /// + /// A reference to the first information track (Track 1) + /// + public Track FirstInformationTrack { get { return Tracks[1]; } } + + /// + /// A reference to the lead-out track. + /// Effectively, the end of the user area of the disc. + /// + public Track LeadoutTrack { get { return Tracks[Tracks.Count - 1]; } } } /// @@ -184,11 +213,10 @@ namespace BizHawk.Emulation.DiscSystem //Indices may need scanning sector by sector. //It's unlikely that any software would be needing indices anyway. //We should add another index scanning service if that's ever needed. - //(note: a CCD should contain indices, but it's not clear whether it's required. logically it wshouldnt be) + //(note: a CCD should contain indices, but it's not clear whether it's required. logically it shouldnt be) //Notable omission: - //Mode (0,1,2) - //Modes 1 and 2 can't be generally distinguished. - //It's a relatively easy heuristic, though: just read the first sector of each track. + //Length of the track. + //How should this be defined? Between which indices? It's really hard. //These omissions could be handled by ReadStructure() policies which permit the scanning of the entire disc. //After that, they could be cached in here. @@ -228,17 +256,9 @@ namespace BizHawk.Emulation.DiscSystem public int LBA; /// - /// The length of the track, counted from its index 1 to the next track. - /// TODO - Shouldn't it exclude the post-gap? - /// NO - in at least one place (CDAudio) this is used.. and.. it should probably play through the post-gap - /// That just goes to show how ill-defined this concept is + /// The next track in the session. null for the leadout track of a session. /// - public int Length; - - ///// - ///// The length as a timestamp (for accessing as a MM:SS:FF) - ///// - //public Timestamp FriendlyLength { get { return new Timestamp(Length); } } + public Track NextTrack; } public class Index @@ -247,19 +267,6 @@ namespace BizHawk.Emulation.DiscSystem public int LBA; } - //public void AnalyzeLengthsFromIndexLengths() - //{ - // //this is a little more complex than it looks, because the length of a thing is not determined by summing it - // //but rather by the difference in lbas between start and end - // LengthInSectors = 0; - // foreach (var session in Sessions) - // { - // var firstTrack = session.Tracks[0]; - // var lastTrack = session.Tracks[session.Tracks.Count - 1]; - // session.length_aba = lastTrack.Indexes[0].aba + lastTrack.Length - firstTrack.Indexes[0].aba; - // LengthInSectors += session.length_aba; - // } - //} } } \ No newline at end of file