using System; using System.Text; using System.Collections.Generic; 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 1-indexed list of sessions (session 1 is at [1]) /// Support for multiple sessions is thoroughly not working yet /// public List Sessions = new List(); public class Session { //Notable omission: //Length of the session //How should this be defined? It's even harder than determining a track length /// /// 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; /// /// The number of user information tracks in the session. /// This excludes the lead-in and lead-out tracks /// Use this instead of Tracks.Count /// public int InformationTrackCount { get { return Tracks.Count - 2; } } /// /// All the tracks in the session.. but... Tracks[0] is the lead-in track. 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(); /// /// A reference to the first information track (Track 1) /// The raw TOC may have specified something different; it's not clear how this discrepancy is handled. /// public Track FirstInformationTrack { get { return Tracks[1]; } } /// /// A reference to the last information track on the disc. /// The raw TOC may have specified something different; it's not clear how this discrepancy is handled. /// public Track LastInformationTrack { get { return Tracks[InformationTrackCount]; } } /// /// 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]; } } /// /// A reference to the lead-in track /// public Track LeadinTrack { get { return Tracks[0]; } } /// /// Determines which track of the session is at the specified LBA. /// public Track SeekTrack(int lba) { var ses = this; for (int i = 1; i < Tracks.Count; i++) { var track = ses.Tracks[i]; //funny logic here: if the current track's LBA is > the requested track number, it means the previous track is the one we wanted if (track.LBA > lba) return ses.Tracks[i - 1]; } return ses.LeadoutTrack; } } /// /// The Type of a track as specified in the TOC Q-Subchannel data from the control flags. /// Could also be 4-Channel Audio, but we'll handle that later if needed /// public enum ETrackType { /// /// The track type isn't always known.. it can take this value til its populated /// Unknown, /// /// Data track( TOC Q control 0x04 flag set ) /// Data, /// /// Audio track( TOC Q control 0x04 flag clear ) /// Audio } /// /// Information about a Track. /// public class Track { //Notable omission: //a list of Indices. It's difficult to reliably construct it. //Notably, mednafen can't readily produce it. //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 shouldnt be) //Notable omission: //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. /// /// The number of the track (1-indexed) /// public int Number; /// /// The Mode of the track (0 is Audio, 1 and 2 are data) /// This is heuristically determined. /// Actual sector contents may vary /// public int Mode; /// /// Is this track a Data track? /// public bool IsData { get { return !IsAudio; } } /// /// Is this track an Audio track? /// public bool IsAudio { get { return Mode == 0; } } /// /// The 'control' properties of the track expected to be found in the track's subQ. /// However, this is what's indicated by the disc TOC. /// Actual sector contents may vary. /// public EControlQ Control; /// /// The starting LBA of the track (index 1). /// public int LBA; /// /// The next track in the session. null for the leadout track of a session. /// public Track NextTrack; } public class Index { public int Number; public int LBA; } } }